From 9375eb2367788146293945a1544276d0f65281ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 28 Mar 2024 03:57:05 +0000 Subject: [PATCH] deploy: KusionStack/kusionstack.io@8827871dc4c4f35641baeeebb60c39542f0cbf26 --- 404.html | 8 +++--- assets/js/03c33ea8.58c891d5.js | 1 - assets/js/03c33ea8.ad31b494.js | 1 + assets/js/043680c6.67e00309.js | 1 - assets/js/043680c6.da1f0f15.js | 1 + assets/js/048ed126.5e7c39a4.js | 1 + assets/js/048ed126.a713192f.js | 1 - assets/js/05939e2b.9fedbab2.js | 1 + assets/js/05939e2b.aaf248e9.js | 1 - ...2121e.e63e6dd9.js => 05e2121e.6eadd0e0.js} | 2 +- assets/js/06519e08.41afbcf4.js | 1 - assets/js/06519e08.583b8469.js | 1 + assets/js/073cf144.05519135.js | 1 - assets/js/073cf144.ab6fb57e.js | 1 + ...f87c9.6238ad40.js => 084f87c9.da8f5fca.js} | 2 +- assets/js/091a426a.2be81aad.js | 1 - assets/js/091a426a.411e9eeb.js | 1 + assets/js/09b7d7e1.9b3784fe.js | 1 + assets/js/09b7d7e1.b8b4d220.js | 1 - assets/js/0a185701.3fe6bef4.js | 1 + assets/js/0b745da3.04428ad4.js | 1 - assets/js/0b745da3.11825daf.js | 1 + ...91782.caa55d3c.js => 0bf91782.3e421779.js} | 2 +- assets/js/0dc90373.48fe1927.js | 1 - assets/js/0dc90373.eb82127b.js | 1 + assets/js/0e7cda11.11e5d9ca.js | 1 + assets/js/0e7cda11.f86c28ee.js | 1 - assets/js/0f1fb433.6680edfb.js | 1 - assets/js/0f1fb433.9718efdd.js | 1 + assets/js/0f9ab0f2.0598045f.js | 1 + assets/js/0f9ab0f2.af2be204.js | 1 - assets/js/1133e639.6d5e2522.js | 1 + assets/js/1133e639.928746f5.js | 1 - assets/js/16d34038.81cad349.js | 1 - assets/js/1759e3b3.75e8d80c.js | 1 - assets/js/1759e3b3.c16cd999.js | 1 + ...56dd8.d2019cde.js => 17b56dd8.6a3aeb77.js} | 2 +- assets/js/1835c74b.2bfb8617.js | 1 + assets/js/1835c74b.db986336.js | 1 - assets/js/1898401f.c9ca6608.js | 1 - assets/js/1898401f.fa90b4f7.js | 1 + assets/js/1961a063.3d193eee.js | 1 + assets/js/1961a063.a8071215.js | 1 - assets/js/1977b36b.5f3b145b.js | 1 - assets/js/1977b36b.b788d5ee.js | 1 + assets/js/19d6fa9a.79cacd6f.js | 1 + assets/js/19d6fa9a.f1b43ebd.js | 1 - ...dd558.96c6b381.js => 19fdd558.e466c4e8.js} | 2 +- ...f5579.53344ca5.js => 1a5f5579.4a2ddacb.js} | 2 +- assets/js/1aa0cc2e.a3da7fb0.js | 1 - assets/js/1aa0cc2e.da5c9ea0.js | 1 + assets/js/1aea322a.6265a3e0.js | 1 + assets/js/1aea322a.9a3c594c.js | 1 - ...9e815.2d9143d4.js => 1b99e815.e0cdc2d3.js} | 2 +- assets/js/1c549a2d.333ccd1c.js | 1 - assets/js/1c549a2d.aac0a3f6.js | 1 + assets/js/1fe9451f.4658cdba.js | 1 + assets/js/1fe9451f.ca1c3b23.js | 1 - assets/js/20d5d8d7.ba287408.js | 1 - assets/js/20d5d8d7.cc383b35.js | 1 + ...5f1af.f7d9fd25.js => 2115f1af.d9a37f9b.js} | 2 +- assets/js/22cda74c.1ecaea8f.js | 1 + assets/js/22cda74c.6ea7132b.js | 1 - assets/js/2353ab8e.6804a17b.js | 1 - assets/js/2353ab8e.dcd1b566.js | 1 + ...b575e.15551eb2.js => 237b575e.45b6ef1e.js} | 2 +- assets/js/23bbb932.52032b41.js | 1 - assets/js/23bbb932.726ad797.js | 1 + assets/js/26fe9297.96894e7f.js | 1 + assets/js/26fe9297.bbc7d4f8.js | 1 - assets/js/28005ec6.5b4c5ee5.js | 1 - assets/js/28005ec6.6599965d.js | 1 + assets/js/281e8991.490faf47.js | 1 + assets/js/281e8991.d6d8d49d.js | 1 - ...f5fa1.e7768f6e.js => 287f5fa1.75a3faa3.js} | 2 +- ...e08e8.9a8c6761.js => 28de08e8.796c1f89.js} | 2 +- assets/js/2b4be8fd.0ebc72ab.js | 1 - assets/js/2b4be8fd.ec338e27.js | 1 + assets/js/2e98070f.462da715.js | 1 - assets/js/2e98070f.ba257614.js | 1 + assets/js/2e999f74.101389b3.js | 1 + assets/js/2e999f74.a2353f97.js | 1 - assets/js/30546e72.9178b7fb.js | 1 + assets/js/30546e72.e9bbd5b0.js | 1 - ...bace7.541a67ad.js => 305bace7.a69aabe8.js} | 2 +- assets/js/32000204.2c8aa695.js | 1 - assets/js/32000204.61d2178b.js | 1 + assets/js/32956a74.522512e9.js | 1 - assets/js/32956a74.6ee24615.js | 1 + ...8bfc8.175f08eb.js => 33c8bfc8.26688612.js} | 2 +- ...f352d.1c76b491.js => 34bf352d.7c19c4b2.js} | 2 +- assets/js/3536e8ef.af8d45ec.js | 1 - assets/js/3536e8ef.cc81c73d.js | 1 + assets/js/3712c5a4.2bb652b5.js | 1 - assets/js/3712c5a4.cfbc991f.js | 1 + ...5f14e.6cadf77f.js => 3715f14e.ab9bba0e.js} | 2 +- ...ee327.6f6e1672.js => 376ee327.c6e6e730.js} | 2 +- assets/js/37badd01.452e0e5c.js | 1 - assets/js/37badd01.6e9d76a9.js | 1 + ...759e2.003052fb.js => 39a759e2.4f82439b.js} | 2 +- assets/js/3a980746.018d6b6c.js | 1 - assets/js/3a980746.cfba503b.js | 1 + ...f5c9a.4a74a1a0.js => 3b1f5c9a.15db957d.js} | 2 +- assets/js/3ba9be36.02f87a61.js | 1 - assets/js/3ba9be36.2230bb4e.js | 1 + assets/js/3bda864c.983d1487.js | 1 - assets/js/3bda864c.fb59e54b.js | 1 + assets/js/3c3bc024.329f8bb0.js | 1 + assets/js/3c3bc024.dab5524f.js | 1 - assets/js/3d3b6af8.83e8c78f.js | 1 + assets/js/3d3b6af8.840d42ce.js | 1 - ...240dc.97be4a01.js => 3de240dc.fbdcaaa2.js} | 2 +- assets/js/4032a3e5.3e801b32.js | 1 + assets/js/4032a3e5.8e8b71c9.js | 1 - assets/js/407e1392.ea639fd9.js | 1 + assets/js/407e1392.f0923f60.js | 1 - assets/js/434d80d9.8389b7c3.js | 1 + assets/js/434d80d9.a0959f68.js | 1 - ...6c285.72a024a5.js => 4406c285.c769db72.js} | 2 +- ...7a3de.4a4e8a9d.js => 44a7a3de.3f45a4db.js} | 2 +- assets/js/45bfe338.470cc412.js | 1 + assets/js/45bfe338.adb144b4.js | 1 - assets/js/47d45151.18ace9fc.js | 1 - assets/js/47d45151.e66857e2.js | 1 + assets/js/497c7ba5.6e9bf2ab.js | 1 + assets/js/497c7ba5.a4ee2553.js | 1 - assets/js/4a6d5a33.33808d51.js | 1 + assets/js/4a6d5a33.749feba8.js | 1 - assets/js/4ac8e691.0fda8509.js | 1 + assets/js/4ac8e691.9bed4cad.js | 1 - ...6b697.b28ddd16.js => 4b36b697.141e98b4.js} | 2 +- assets/js/4c493feb.2493bdf2.js | 1 + assets/js/4c493feb.c1159b54.js | 1 - assets/js/4d1b877d.4f983a44.js | 1 + assets/js/4d1b877d.bf2731fe.js | 1 - assets/js/4df25393.3cb01d89.js | 1 + assets/js/4df25393.dd212270.js | 1 - ...63eb9.4b344b64.js => 4e363eb9.4909794c.js} | 2 +- assets/js/50dd26bc.407076be.js | 1 + assets/js/50dd26bc.b1ec5a82.js | 1 - ...4ba79.e6452f9d.js => 5114ba79.48a06846.js} | 2 +- assets/js/5276ed9c.c5d1e5be.js | 1 - assets/js/5276ed9c.eefa78c9.js | 1 + assets/js/55141fa2.1c98af2d.js | 1 + assets/js/55141fa2.6b6b35ce.js | 1 - assets/js/551843d2.362a0ef6.js | 1 + assets/js/551843d2.41313eba.js | 1 - assets/js/56362d1e.67075293.js | 1 - assets/js/56362d1e.7f27268d.js | 1 + ...dbdc9.3f454234.js => 566dbdc9.310585c2.js} | 2 +- assets/js/5674e156.7499a6c1.js | 1 + assets/js/5674e156.b028d47e.js | 1 - assets/js/56d50f7c.0e2ca84e.js | 1 + assets/js/56d50f7c.bc0aede7.js | 1 - assets/js/595d2708.6fc2fd7a.js | 1 - assets/js/595d2708.b1d29a11.js | 1 + ...344a5.6fa21c2b.js => 5ad344a5.2e48a8bf.js} | 2 +- assets/js/5b1b6e2c.2a2121dd.js | 1 + assets/js/5b1b6e2c.b8eb5e1e.js | 1 - ...39018.20823a8f.js => 5ea39018.92e4ec51.js} | 2 +- assets/js/5ec8c180.a1e9f0a7.js | 1 + assets/js/5ee164ec.4263c688.js | 1 + assets/js/5ee164ec.7fe6e530.js | 1 - assets/js/5f456afb.271ca9f7.js | 1 + assets/js/5f456afb.d7c709c3.js | 1 - assets/js/5fff1932.63a9af64.js | 1 + assets/js/5fff1932.64ded398.js | 1 - assets/js/600a00a0.06d75661.js | 1 - assets/js/600a00a0.19fc5231.js | 1 + assets/js/60cc01db.51acc0e7.js | 1 + assets/js/60cc01db.bd18c39c.js | 1 - assets/js/61f95e53.0e8b8130.js | 1 + assets/js/61f95e53.13d744d9.js | 1 - ...accb9.4a58b7ec.js => 630accb9.4c8f8a7e.js} | 2 +- ...c7392.757dc55f.js => 640c7392.5fc45ad2.js} | 2 +- assets/js/69e6dfa6.2a081405.js | 1 + assets/js/69e6dfa6.2fc299cc.js | 1 - assets/js/6a034c6e.25cb7092.js | 1 - assets/js/6a034c6e.4dc0c5ac.js | 1 + assets/js/6b830420.2351029d.js | 1 + assets/js/6b830420.b5fd3075.js | 1 - assets/js/6eb5e412.5292b49c.js | 1 + assets/js/6eb5e412.84c97c04.js | 1 - assets/js/6ece4ae7.c4c6fb3f.js | 1 + assets/js/6ece4ae7.ea904ef8.js | 1 - assets/js/6fb6dfc9.71c1905c.js | 1 + assets/js/6fb6dfc9.e8920cf5.js | 1 - ...2af80.1c782dc5.js => 7062af80.0f6b4260.js} | 2 +- assets/js/70dfc3b7.490b71e4.js | 1 - assets/js/70dfc3b7.97f702cd.js | 1 + ...d01e9.8b775c16.js => 70fd01e9.af28bc51.js} | 2 +- assets/js/72ae1949.1864e971.js | 1 + assets/js/72ae1949.3f745ef1.js | 1 - assets/js/72c158da.6b232634.js | 1 + assets/js/72c158da.eccd5906.js | 1 - ...b5664.b44170e2.js => 735b5664.3f93833d.js} | 2 +- assets/js/75071e09.91cf8ea0.js | 1 - assets/js/75071e09.bf149714.js | 1 + ...0d161.45961935.js => 7590d161.67c28f14.js} | 2 +- assets/js/76b33887.1ab6b263.js | 1 - assets/js/76b33887.749220b6.js | 1 + assets/js/7772ebc2.11cd736f.js | 1 - assets/js/7772ebc2.e028e064.js | 1 + assets/js/77c6b439.613db0a6.js | 1 + assets/js/77c6b439.a486d3a5.js | 1 - assets/js/78ec9a9a.0ec5e5f6.js | 1 - assets/js/78ec9a9a.4cdedd58.js | 1 + assets/js/79b30505.121a45b0.js | 1 + assets/js/79b30505.afc2508c.js | 1 - assets/js/7b92056b.1d96726c.js | 1 + assets/js/7b92056b.b2c99df4.js | 1 - ...9cf58.48b5dd20.js => 7d19cf58.9c4cd7e8.js} | 2 +- assets/js/7dad11d2.124f1ab7.js | 1 + assets/js/7dad11d2.2974f534.js | 1 - assets/js/7f5c0070.6531cfd8.js | 1 + assets/js/7f5c0070.bac41f7f.js | 1 - ...29501.26d61c93.js => 82029501.18008d5b.js} | 2 +- assets/js/821c5d9e.0845ce23.js | 1 + assets/js/821c5d9e.cfaf598f.js | 1 - assets/js/82345ec9.bb06a026.js | 1 - assets/js/82345ec9.fa9665d4.js | 1 + assets/js/82e833af.89312298.js | 1 - assets/js/82e833af.c38d7cc4.js | 1 + assets/js/83192466.380d49f8.js | 1 + assets/js/83192466.b599c16b.js | 1 - assets/js/837fd906.6bd427c4.js | 1 + assets/js/837fd906.86c0be46.js | 1 - assets/js/83e1f194.98952125.js | 1 - assets/js/83e1f194.ad69af40.js | 1 + assets/js/8619d2de.06f3901b.js | 1 + assets/js/8619d2de.761efd9a.js | 1 - ...64c80.a8f97a1b.js => 86764c80.55f9b4ab.js} | 2 +- assets/js/87668920.4aa96a90.js | 1 + assets/js/87668920.57da924c.js | 1 - assets/js/87ed36d5.0da94ca9.js | 1 - assets/js/87ed36d5.53343c6e.js | 1 + assets/js/8827e5e6.3a01b91b.js | 1 + assets/js/8827e5e6.41c4aebf.js | 1 - assets/js/8a2c5ffd.71805797.js | 1 - assets/js/8a2c5ffd.a2f6d36d.js | 1 + assets/js/8b19a93e.8496eafd.js | 1 - assets/js/8b19a93e.8979ef6f.js | 1 + assets/js/8b810823.3ca25134.js | 1 - assets/js/8b810823.f6490f68.js | 1 + assets/js/8d59c070.00f6a67d.js | 1 + assets/js/8d59c070.2ce7053f.js | 1 - assets/js/8e17bf11.5d8d059f.js | 1 - assets/js/8e17bf11.c4f869d6.js | 1 + ...b0243.1fa866ba.js => 8ebb0243.5d1db1a5.js} | 2 +- ...adede.82d08ed6.js => 8f5adede.89b38597.js} | 2 +- assets/js/8fcded8c.0579ecc9.js | 1 - assets/js/8fcded8c.63397745.js | 1 + ...7585f.fd59f9f3.js => 92e7585f.af0bf984.js} | 2 +- assets/js/935f2afb.009b227a.js | 1 + assets/js/935f2afb.c61778ca.js | 1 - assets/js/9595b411.88e3cf18.js | 1 + assets/js/9595b411.e4151beb.js | 1 - assets/js/9662bf8d.a11ba1b1.js | 1 - assets/js/9662bf8d.e0078cb6.js | 1 + assets/js/977fdfc4.4b11e617.js | 1 + assets/js/977fdfc4.f3c7fcf1.js | 1 - assets/js/97d4b178.23c0f1d6.js | 1 + assets/js/97d4b178.5c4f0b6b.js | 1 - assets/js/99000770.1311682f.js | 1 - assets/js/99000770.ffe7dc96.js | 1 + assets/js/990e3068.d6055d90.js | 1 + assets/js/990e3068.f5be684b.js | 1 - assets/js/99153eb1.5a891290.js | 1 - assets/js/99153eb1.dbb20b4b.js | 1 + assets/js/9aa57586.7b227a3b.js | 1 - assets/js/9aa57586.b95d248d.js | 1 + assets/js/9c804087.1dc9d49f.js | 1 - assets/js/9c804087.6aaba070.js | 1 + assets/js/9d1d9869.167e28fc.js | 1 - assets/js/9d1d9869.7c820359.js | 1 + ...571d8.38e01710.js => 9e3571d8.57689d11.js} | 2 +- assets/js/9f069a65.668f0f89.js | 1 + assets/js/9f069a65.932ffb24.js | 1 - assets/js/9fc66687.57aa4047.js | 1 + assets/js/9fc66687.5b4b8dbc.js | 1 - assets/js/a08f9b67.0653218e.js | 1 - assets/js/a08f9b67.4e677d30.js | 1 + ...1ee0b.4f7f6d44.js => a121ee0b.8eda715d.js} | 2 +- assets/js/a27ca0d9.32308675.js | 1 + assets/js/a27ca0d9.d5833bb9.js | 1 - assets/js/a28f322c.64c84735.js | 1 + assets/js/a28f322c.efc35126.js | 1 - assets/js/a5969c3a.2e2ca053.js | 1 - assets/js/a5969c3a.f64b85e6.js | 1 + ...9fa37.c668e600.js => a8f9fa37.32f56175.js} | 2 +- assets/js/abc4e0a8.01396e1a.js | 1 - assets/js/abc4e0a8.40e42a93.js | 1 + assets/js/ad602bef.54441f42.js | 1 - assets/js/ad602bef.d706b590.js | 1 + assets/js/adf149f0.635eafd2.js | 1 + assets/js/adf149f0.6a84419c.js | 1 - assets/js/aec48fb4.47698132.js | 1 - assets/js/aec48fb4.e21b233c.js | 1 + assets/js/af046d03.0c8d20c1.js | 1 + assets/js/af046d03.6f24420a.js | 1 - assets/js/af2e79ee.00cacc63.js | 1 - assets/js/af2e79ee.9daf7eac.js | 1 + assets/js/b049517a.75e46ed3.js | 1 + assets/js/b049517a.e4ec7dff.js | 1 - assets/js/b075c519.7635c071.js | 1 + assets/js/b075c519.ce1d6b1a.js | 1 - assets/js/b2f45e36.6ac4def4.js | 1 + assets/js/b2f45e36.99cc16c4.js | 1 - assets/js/b3471d8e.746a2f4c.js | 1 - assets/js/b3471d8e.ad00d781.js | 1 + assets/js/b34bf6de.6ed79029.js | 1 + assets/js/b34bf6de.838dcca3.js | 1 - ...8c180.cb041950.js => b44b4ce2.475485ff.js} | 2 +- assets/js/b44b4ce2.a0de6e32.js | 1 - assets/js/b46813dd.364c88b4.js | 1 - assets/js/b46813dd.a11fb422.js | 1 + assets/js/b509c81b.aeea8285.js | 1 - assets/js/b509c81b.b10ec20a.js | 1 + assets/js/b57a4a2d.04ebf6ac.js | 1 - assets/js/b57a4a2d.3b54e102.js | 1 + assets/js/b5d95ae4.69d9052f.js | 1 - assets/js/b5d95ae4.abfc5821.js | 1 + ...f2faa.37ca3985.js => b6cf2faa.183608ed.js} | 2 +- assets/js/b6dea0ad.5d55a0d7.js | 1 + assets/js/b6dea0ad.cd24d5b1.js | 1 - ...fdfcb.fb1bde34.js => b70fdfcb.079b5d16.js} | 2 +- ...e870b.04febfb1.js => b72e870b.32e861fd.js} | 2 +- assets/js/b7847a20.c0ab7bba.js | 1 + assets/js/b7847a20.d3e7f5b2.js | 1 - ...af01f.0df1e7b0.js => b8caf01f.de8cdbb9.js} | 2 +- assets/js/b9b61d04.15460c78.js | 1 - assets/js/b9b61d04.e07f242c.js | 1 + assets/js/baa12f70.132881b4.js | 1 + assets/js/baa12f70.733a15a2.js | 1 - ...f1c36.41c592be.js => bbff1c36.e41b8a00.js} | 2 +- assets/js/bc5f1a80.0df8560d.js | 1 + assets/js/bc5f1a80.ee7d23c2.js | 1 - assets/js/c02a675f.92d65b30.js | 1 + assets/js/c02a675f.9d8def74.js | 1 - assets/js/c09b0fe7.660076a3.js | 1 - assets/js/c09b0fe7.a66e4b54.js | 1 + assets/js/c15b59ba.582524dc.js | 1 + assets/js/c15b59ba.ef28dfaa.js | 1 - assets/js/c1bf8f22.5cf2e82b.js | 1 + assets/js/c1bf8f22.d2bba25b.js | 1 - assets/js/c2884f74.27697d2b.js | 1 - assets/js/c2884f74.d0b0ad50.js | 1 + assets/js/c311d7f4.401ed809.js | 1 - assets/js/c311d7f4.d147804d.js | 1 + assets/js/c31a6c64.8ec97530.js | 1 + assets/js/c31a6c64.dbba3d47.js | 1 - ...28e1b.46469b73.js => c3728e1b.21bf3d2b.js} | 2 +- assets/js/c4ba81c3.2dbc3af6.js | 1 + assets/js/c4ba81c3.cb955b2d.js | 1 - assets/js/c5353c60.3e26b543.js | 1 + assets/js/c5353c60.9b747761.js | 1 - assets/js/c5a89df7.1948f9a2.js | 1 - assets/js/c5a89df7.f48ef27c.js | 1 + assets/js/c6ae2a42.5cdb0a17.js | 1 - assets/js/c6ae2a42.8b27f6a1.js | 1 + assets/js/c7fa01e5.0ccaf230.js | 1 - assets/js/c7fa01e5.2ed2e287.js | 1 + ...e621c.1e08be72.js => cd9e621c.6b430410.js} | 2 +- assets/js/d0375dde.535a8363.js | 1 + assets/js/d0375dde.7c666183.js | 1 - assets/js/d05ef132.65b778ef.js | 1 - assets/js/d05ef132.ff4dea0a.js | 1 + assets/js/d08bdbd3.29405804.js | 1 - assets/js/d08bdbd3.c2a6f40d.js | 1 + ...7a415.b51c0c01.js => d107a415.66e33494.js} | 2 +- assets/js/d33f5cb2.22228d8c.js | 1 + assets/js/d33f5cb2.8fdce34e.js | 1 - assets/js/d398f178.15ecdd0f.js | 1 - assets/js/d398f178.b537c3ee.js | 1 + assets/js/d5b05897.a399b999.js | 1 + assets/js/d5b05897.c920e343.js | 1 - ...68d14.1c4e0780.js => d5d68d14.c5270262.js} | 2 +- ...cad0c.d29f91ad.js => d65cad0c.5f482958.js} | 2 +- ...729b6.827935fd.js => d7b729b6.96f32350.js} | 2 +- assets/js/d9a047ee.31f9d1e2.js | 1 + assets/js/d9a047ee.63be3c37.js | 1 - assets/js/da7786fc.6c63c41b.js | 1 + assets/js/da7786fc.bb98a240.js | 1 - ...43463.ef5b8864.js => db343463.3da9b571.js} | 2 +- ...f606f.62860f23.js => dbbf606f.97b635b4.js} | 2 +- assets/js/dc405d94.9417abb8.js | 1 - assets/js/dc405d94.9704fa68.js | 1 + assets/js/de200a2a.97fae5c5.js | 1 - assets/js/de200a2a.c7ae3379.js | 1 + assets/js/de7874bb.85b47aee.js | 1 - assets/js/de7874bb.d96d2922.js | 1 + assets/js/dfc7c90d.2419115f.js | 1 - assets/js/dfc7c90d.8a7ed7eb.js | 1 + assets/js/e381d75c.bb9d48d2.js | 1 + assets/js/e381d75c.ef4bf99a.js | 1 - assets/js/e4f1eb77.5d5c3e3f.js | 1 - assets/js/e4f1eb77.ee805867.js | 1 + assets/js/e6798fa1.59bd1f38.js | 1 - assets/js/e6798fa1.86a6cbff.js | 1 + ...5a9f3.b7fd9f41.js => e695a9f3.e9c83c36.js} | 2 +- ...6141c.fc99a527.js => e696141c.07b0088b.js} | 2 +- ...1010f.a002a4c1.js => e701010f.b698b789.js} | 2 +- assets/js/e7e8cb25.6b10ab5e.js | 1 - assets/js/e7e8cb25.8655f88d.js | 1 + assets/js/e8149155.9a5b1f0c.js | 1 - assets/js/e8149155.d98e2fe2.js | 1 + ...7f19f.79dc2d14.js => e877f19f.e3eeb47f.js} | 2 +- assets/js/e89e36c0.5babc632.js | 1 + assets/js/e89e36c0.d5a819be.js | 1 - assets/js/ebf27649.a13fb837.js | 1 - assets/js/ebf27649.e699151a.js | 1 + ...a6eee.1683acaa.js => ecaa6eee.eb4b9d9e.js} | 2 +- assets/js/ecbd3f41.05abb6bd.js | 1 + assets/js/ecbd3f41.a7744f53.js | 1 - assets/js/eccaeac4.538071fd.js | 1 + assets/js/eccaeac4.c95926af.js | 1 - ...e9c54.8b9e5d08.js => ed2e9c54.ca949112.js} | 2 +- assets/js/ee59e712.905fad65.js | 1 - assets/js/ee59e712.f41b3cd0.js | 1 + assets/js/ee68f9c5.3e3baacd.js | 1 - assets/js/ee68f9c5.f701e4a5.js | 1 + ...d0512.ab908c81.js => ee6d0512.1bc64518.js} | 2 +- assets/js/f058aa3c.3e6113b2.js | 1 + assets/js/f058aa3c.8ea5185c.js | 1 - ...404ac.3e9d65b1.js => f1e404ac.481de01c.js} | 2 +- ...acb22.955acd7b.js => f34acb22.6b18f013.js} | 2 +- assets/js/f35beff3.291f9bb5.js | 1 - assets/js/f35beff3.6d7affb8.js | 1 + ...eafd2.4a8b45c3.js => f4eeafd2.fb43806c.js} | 2 +- ...5a87f.5fbe324e.js => f655a87f.c0d72261.js} | 2 +- assets/js/f7f2164e.081d3b09.js | 1 - assets/js/f7f2164e.9737060e.js | 1 + assets/js/f9476b7a.049b6102.js | 1 + assets/js/f9476b7a.add3b000.js | 1 - assets/js/fa47a47e.097ed95e.js | 1 - assets/js/fa47a47e.c61f88d3.js | 1 + assets/js/fd1fdd14.01b0b155.js | 1 + assets/js/fd1fdd14.915e24d2.js | 1 - ...cbe36.4346cf95.js => fdecbe36.0de627fd.js} | 2 +- assets/js/main.3e823d7e.js | 2 ++ ...CENSE.txt => main.3e823d7e.js.LICENSE.txt} | 0 assets/js/main.bce0811d.js | 2 -- assets/js/runtime~main.884946b6.js | 1 - assets/js/runtime~main.b5a7af0a.js | 1 + blog/2021-kcl-intro/index.html | 8 +++--- blog/2021-kusion-intro/index.html | 8 +++--- .../index.html | 8 +++--- .../2022-learn-from-scale-practice/index.html | 8 +++--- blog/2022-open-day/index.html | 8 +++--- .../2022-origin-present-and-future/index.html | 8 +++--- .../index.html | 8 +++--- blog/2022-sense-of-open-day/index.html | 8 +++--- blog/2023-05-26-qcon-guangzhou/index.html | 8 +++--- blog/archive/index.html | 8 +++--- blog/index.html | 8 +++--- blog/page/2/index.html | 8 +++--- blog/page/3/index.html | 8 +++--- blog/page/4/index.html | 8 +++--- blog/page/5/index.html | 8 +++--- blog/tags/index.html | 8 +++--- blog/tags/kcl/index.html | 8 +++--- blog/tags/kclvm/index.html | 8 +++--- blog/tags/kusion-stack/index.html | 8 +++--- blog/tags/kusion-stack/page/2/index.html | 8 +++--- blog/tags/kusion-stack/page/3/index.html | 8 +++--- blog/tags/kusion-stack/page/4/index.html | 8 +++--- blog/tags/kusion/index.html | 8 +++--- blog/tags/kusion/page/2/index.html | 8 +++--- blog/tags/kusion/page/3/index.html | 8 +++--- blog/tags/kusion/page/4/index.html | 8 +++--- blog/tags/large-scale/index.html | 8 +++--- blog/tags/platform-engineering/index.html | 8 +++--- docs/community/intro/index.html | 10 ++++---- docs/ctrlmesh/concepts/index.html | 10 ++++---- docs/ctrlmesh/faq/index.html | 10 ++++---- docs/ctrlmesh/intro/index.html | 10 ++++---- docs/ctrlmesh/started/install/index.html | 10 ++++---- docs/ctrlmesh/started/try/index.html | 10 ++++---- docs/index.html | 10 ++++---- .../concepts/app-configuration/index.html | 10 ++++---- .../concepts/backend-configuration/index.html | 10 ++++---- .../concepts/how-kusion-works/index.html | 10 ++++---- docs/kusion/concepts/intent/index.html | 10 ++++---- docs/kusion/concepts/kusion-module/index.html | 10 ++++---- .../concepts/project/configuration/index.html | 10 ++++---- .../concepts/project/overview/index.html | 10 ++++---- .../concepts/stack/configuration/index.html | 10 ++++---- .../kusion/concepts/stack/overview/index.html | 10 ++++---- docs/kusion/concepts/workspace/index.html | 10 ++++---- .../base-override/index.html | 10 ++++---- .../databse/index.html | 10 ++++---- .../kcl-basics/index.html | 10 ++++---- .../monitoring/index.html | 10 ++++---- .../networking/index.html | 10 ++++---- .../operational-rules/index.html | 10 ++++---- .../overview/index.html | 10 ++++---- .../secret/index.html | 10 ++++---- .../workload/index.html | 10 ++++---- docs/kusion/faq/install-error/index.html | 10 ++++---- docs/kusion/faq/kcl/index.html | 10 ++++---- .../deliver-wordpress/index.html | 10 ++++---- .../getting-started/install-kusion/index.html | 10 ++++---- docs/kusion/reference/commands/index.html | 10 ++++---- .../commands/kusion-apply/index.html | 10 ++++---- .../commands/kusion-build/index.html | 10 ++++---- .../commands/kusion-compile/index.html | 10 ++++---- .../commands/kusion-destroy/index.html | 10 ++++---- .../reference/commands/kusion-init/index.html | 10 ++++---- .../commands/kusion-preview/index.html | 10 ++++---- .../commands/kusion-version/index.html | 10 ++++---- .../kusion-workspace-create/index.html | 10 ++++---- .../kusion-workspace-delete/index.html | 10 ++++---- .../commands/kusion-workspace-list/index.html | 10 ++++---- .../commands/kusion-workspace-show/index.html | 10 ++++---- .../kusion-workspace-update/index.html | 10 ++++---- .../commands/kusion-workspace/index.html | 10 ++++---- .../app-configuration/index.html | 10 ++++---- .../catalog-models/database/mysql/index.html | 10 ++++---- .../database/postgres/index.html | 10 ++++---- .../catalog-models/internal/common/index.html | 10 ++++---- .../internal/container/index.html | 10 ++++---- .../internal/container/lifecycle/index.html | 10 ++++---- .../internal/container/probe/index.html | 10 ++++---- .../internal/network/port/index.html | 10 ++++---- .../catalog-models/internal/secret/index.html | 10 ++++---- .../monitoring/prometheus/index.html | 10 ++++---- .../catalog-models/trait/opsrule/index.html | 10 ++++---- .../catalog-models/workload/job/index.html | 10 ++++---- .../workload/service/index.html | 10 ++++---- docs/kusion/reference/modules/index.html | 10 ++++---- .../modules/naming-conventions/index.html | 10 ++++---- .../database/mysql/index.html | 10 ++++---- .../database/postgres/index.html | 10 ++++---- .../monitoring/prometheus/index.html | 10 ++++---- .../networking/port/index.html | 10 ++++---- .../trait/opsrule/index.html | 10 ++++---- .../workspace-configs/workload/job/index.html | 10 ++++---- .../workload/service/index.html | 10 ++++---- docs/kusion/reference/roadmap/index.html | 10 ++++---- .../cloud-resources/database/index.html | 10 ++++---- .../cloud-resources/expose-service/index.html | 10 ++++---- .../index.html | 10 ++++---- .../observability/prometheus/index.html | 10 ++++---- .../using-cloud-secrets/index.html | 10 ++++---- .../working-with-k8s/container/index.html | 10 ++++---- .../deploy-application/index.html | 10 ++++---- .../working-with-k8s/image-upgrade/index.html | 10 ++++---- .../working-with-k8s/job/index.html | 10 ++++---- .../working-with-k8s/resource-spec/index.html | 10 ++++---- .../working-with-k8s/service/index.html | 10 ++++---- .../set-up-operational-rules/index.html | 10 ++++---- .../what-is-kusion/kusion-vs-x/index.html | 10 ++++---- docs/next/community/intro/index.html | 10 ++++---- docs/next/ctrlmesh/concepts/index.html | 10 ++++---- docs/next/ctrlmesh/faq/index.html | 10 ++++---- docs/next/ctrlmesh/intro/index.html | 10 ++++---- docs/next/ctrlmesh/started/install/index.html | 10 ++++---- docs/next/ctrlmesh/started/try/index.html | 10 ++++---- docs/next/index.html | 10 ++++---- .../concepts/app-configuration/index.html | 10 ++++---- .../concepts/backend-configuration/index.html | 25 ------------------- docs/next/kusion/concepts/backend/index.html | 25 +++++++++++++++++++ .../kusion/concepts/configuration/index.html | 10 ++++---- .../concepts/how-kusion-works/index.html | 12 ++++----- docs/next/kusion/concepts/intent/index.html | 10 ++++---- .../kusion/concepts/kusion-module/index.html | 10 ++++---- .../concepts/project/configuration/index.html | 10 ++++---- .../concepts/project/overview/index.html | 10 ++++---- .../concepts/stack/configuration/index.html | 10 ++++---- .../kusion/concepts/stack/overview/index.html | 10 ++++---- .../next/kusion/concepts/workspace/index.html | 14 +++++------ .../base-override/index.html | 10 ++++---- .../databse/index.html | 10 ++++---- .../kcl-basics/index.html | 10 ++++---- .../monitoring/index.html | 10 ++++---- .../networking/index.html | 10 ++++---- .../operational-rules/index.html | 10 ++++---- .../overview/index.html | 10 ++++---- .../secret/index.html | 10 ++++---- .../workload/index.html | 10 ++++---- docs/next/kusion/faq/install-error/index.html | 10 ++++---- docs/next/kusion/faq/kcl/index.html | 10 ++++---- .../deliver-wordpress/index.html | 10 ++++---- .../getting-started/install-kusion/index.html | 10 ++++---- .../next/kusion/reference/commands/index.html | 10 ++++---- .../commands/kusion-apply/index.html | 10 ++++---- .../commands/kusion-build/index.html | 10 ++++---- .../commands/kusion-compile/index.html | 10 ++++---- .../commands/kusion-destroy/index.html | 10 ++++---- .../reference/commands/kusion-init/index.html | 10 ++++---- .../commands/kusion-preview/index.html | 10 ++++---- .../commands/kusion-version/index.html | 10 ++++---- .../kusion-workspace-create/index.html | 10 ++++---- .../kusion-workspace-delete/index.html | 10 ++++---- .../commands/kusion-workspace-list/index.html | 10 ++++---- .../commands/kusion-workspace-show/index.html | 10 ++++---- .../kusion-workspace-update/index.html | 10 ++++---- .../commands/kusion-workspace/index.html | 10 ++++---- .../app-configuration/index.html | 10 ++++---- .../catalog-models/database/mysql/index.html | 10 ++++---- .../database/postgres/index.html | 10 ++++---- .../catalog-models/internal/common/index.html | 10 ++++---- .../internal/container/index.html | 10 ++++---- .../internal/container/lifecycle/index.html | 10 ++++---- .../internal/container/probe/index.html | 10 ++++---- .../internal/network/port/index.html | 10 ++++---- .../catalog-models/internal/secret/index.html | 10 ++++---- .../monitoring/prometheus/index.html | 10 ++++---- .../catalog-models/trait/opsrule/index.html | 10 ++++---- .../catalog-models/workload/job/index.html | 10 ++++---- .../workload/service/index.html | 10 ++++---- docs/next/kusion/reference/modules/index.html | 10 ++++---- .../modules/naming-conventions/index.html | 10 ++++---- .../database/mysql/index.html | 10 ++++---- .../database/postgres/index.html | 10 ++++---- .../monitoring/prometheus/index.html | 10 ++++---- .../networking/port/index.html | 10 ++++---- .../trait/opsrule/index.html | 10 ++++---- .../workspace-configs/workload/job/index.html | 10 ++++---- .../workload/service/index.html | 10 ++++---- docs/next/kusion/reference/roadmap/index.html | 10 ++++---- .../cloud-resources/database/index.html | 10 ++++---- .../cloud-resources/expose-service/index.html | 10 ++++---- .../index.html | 10 ++++---- .../observability/prometheus/index.html | 10 ++++---- .../using-cloud-secrets/index.html | 10 ++++---- .../working-with-k8s/container/index.html | 10 ++++---- .../deploy-application/index.html | 10 ++++---- .../working-with-k8s/image-upgrade/index.html | 10 ++++---- .../working-with-k8s/job/index.html | 10 ++++---- .../working-with-k8s/resource-spec/index.html | 10 ++++---- .../working-with-k8s/service/index.html | 10 ++++---- .../set-up-operational-rules/index.html | 10 ++++---- .../what-is-kusion/kusion-vs-x/index.html | 10 ++++---- .../concepts/podopslifecycle/index.html | 10 ++++---- docs/next/operating/introduction/index.html | 10 ++++---- .../operating/manuals/collaset/index.html | 10 ++++---- .../manuals/poddecoration/index.html | 10 ++++---- .../manuals/podtransitionrule/index.html | 10 ++++---- .../manuals/resourceconsist/index.html | 10 ++++---- .../demo-graceful-operation/index.html | 10 ++++---- .../next/operating/started/install/index.html | 10 ++++---- .../concepts/podopslifecycle/index.html | 10 ++++---- docs/operating/introduction/index.html | 10 ++++---- docs/operating/manuals/collaset/index.html | 10 ++++---- .../manuals/poddecoration/index.html | 10 ++++---- .../manuals/podtransitionrule/index.html | 10 ++++---- .../manuals/resourceconsist/index.html | 10 ++++---- .../demo-graceful-operation/index.html | 10 ++++---- docs/operating/started/install/index.html | 10 ++++---- docs/v0.9/community/intro/index.html | 10 ++++---- docs/v0.9/ctrlmesh/concepts/index.html | 10 ++++---- docs/v0.9/ctrlmesh/faq/index.html | 10 ++++---- docs/v0.9/ctrlmesh/intro/index.html | 10 ++++---- docs/v0.9/ctrlmesh/started/install/index.html | 10 ++++---- docs/v0.9/ctrlmesh/started/try/index.html | 10 ++++---- docs/v0.9/index.html | 10 ++++---- .../concepts/appconfiguration/index.html | 10 ++++---- docs/v0.9/kusion/concepts/arch/index.html | 10 ++++---- docs/v0.9/kusion/concepts/glossary/index.html | 10 ++++---- docs/v0.9/kusion/concepts/index.html | 10 ++++---- docs/v0.9/kusion/concepts/intent/index.html | 10 ++++---- docs/v0.9/kusion/concepts/kusion/index.html | 10 ++++---- .../base_override/index.html | 10 ++++---- .../config-walkthrough/database/index.html | 10 ++++---- .../config-walkthrough/kcl_basics/index.html | 10 ++++---- .../config-walkthrough/monitoring/index.html | 10 ++++---- .../config-walkthrough/networking/index.html | 10 ++++---- .../operational_rules/index.html | 10 ++++---- .../config-walkthrough/overview/index.html | 10 ++++---- .../config-walkthrough/secret/index.html | 10 ++++---- .../config-walkthrough/workload/index.html | 10 ++++---- .../deliver-wordpress/index.html | 10 ++++---- docs/v0.9/kusion/getting-started/index.html | 10 ++++---- .../getting-started/install-kusion/index.html | 10 ++++---- .../cloud-resources/database/index.html | 10 ++++---- .../cloud-resources/expose-service/index.html | 10 ++++---- .../index.html | 10 ++++---- docs/v0.9/kusion/guides/index.html | 10 ++++---- .../observability/prometheus/index.html | 10 ++++---- .../working-with-k8s/container/index.html | 10 ++++---- .../deploy-application/index.html | 10 ++++---- .../working-with-k8s/image-upgrade/index.html | 10 ++++---- .../kusion/guides/working-with-k8s/index.html | 10 ++++---- .../working-with-k8s/resource-spec/index.html | 10 ++++---- .../working-with-k8s/service/index.html | 10 ++++---- docs/v0.9/kusion/intro/kusion-vs-x/index.html | 10 ++++---- .../backend/backend-configuration/index.html | 10 ++++---- docs/v0.9/kusion/reference/cli/index.html | 10 ++++---- .../kusion/reference/cli/kusion/index.html | 10 ++++---- .../cli/kusion/kusion_apply/index.html | 10 ++++---- .../cli/kusion/kusion_build/index.html | 10 ++++---- .../cli/kusion/kusion_compile/index.html | 10 ++++---- .../cli/kusion/kusion_destroy/index.html | 10 ++++---- .../cli/kusion/kusion_init/index.html | 10 ++++---- .../cli/kusion/kusion_preview/index.html | 10 ++++---- .../cli/kusion/kusion_version/index.html | 10 ++++---- .../database/doc_database/index.html | 10 ++++---- .../doc_app_configuration/index.html | 10 ++++---- .../container/doc_container/index.html | 10 ++++---- .../lifecycle/doc_lifecycle/index.html | 10 ++++---- .../container/probe/doc_probe/index.html | 10 ++++---- .../internal/doc_common/index.html | 10 ++++---- .../internal/network/doc_port/index.html | 10 ++++---- .../internal/secret/doc_secret/index.html | 10 ++++---- .../monitoring/doc_prometheus/index.html | 10 ++++---- .../trait/doc_opsrule/index.html | 10 ++++---- .../workload/doc_job/index.html | 10 ++++---- .../workload/doc_service/index.html | 10 ++++---- docs/v0.9/kusion/reference/model/index.html | 10 ++++---- .../model/naming-conventions/index.html | 10 ++++---- .../reference/model/overview/index.html | 10 ++++---- .../project-stack-config-items/index.html | 10 ++++---- docs/v0.9/kusion/reference/roadmap/index.html | 10 ++++---- docs/v0.9/kusion/support/index.html | 10 ++++---- .../kusion/support/install-error/index.html | 10 ++++---- docs/v0.9/kusion/support/kcl/index.html | 10 ++++---- .../concepts/podopslifecycle/index.html | 10 ++++---- docs/v0.9/operating/introduction/index.html | 10 ++++---- .../operating/manuals/collaset/index.html | 10 ++++---- .../manuals/poddecoration/index.html | 10 ++++---- .../manuals/podtransitionrule/index.html | 10 ++++---- .../manuals/resourceconsist/index.html | 10 ++++---- .../demo-graceful-operation/index.html | 10 ++++---- .../v0.9/operating/started/install/index.html | 10 ++++---- index.html | 8 +++--- markdown-page/index.html | 8 +++--- search/index.html | 8 +++--- sitemap.xml | 2 +- 729 files changed, 1668 insertions(+), 1668 deletions(-) delete mode 100644 assets/js/03c33ea8.58c891d5.js create mode 100644 assets/js/03c33ea8.ad31b494.js delete mode 100644 assets/js/043680c6.67e00309.js create mode 100644 assets/js/043680c6.da1f0f15.js create mode 100644 assets/js/048ed126.5e7c39a4.js delete mode 100644 assets/js/048ed126.a713192f.js create mode 100644 assets/js/05939e2b.9fedbab2.js delete mode 100644 assets/js/05939e2b.aaf248e9.js rename assets/js/{05e2121e.e63e6dd9.js => 05e2121e.6eadd0e0.js} (55%) delete mode 100644 assets/js/06519e08.41afbcf4.js create mode 100644 assets/js/06519e08.583b8469.js delete mode 100644 assets/js/073cf144.05519135.js create mode 100644 assets/js/073cf144.ab6fb57e.js rename assets/js/{084f87c9.6238ad40.js => 084f87c9.da8f5fca.js} (65%) delete mode 100644 assets/js/091a426a.2be81aad.js create mode 100644 assets/js/091a426a.411e9eeb.js create mode 100644 assets/js/09b7d7e1.9b3784fe.js delete mode 100644 assets/js/09b7d7e1.b8b4d220.js create mode 100644 assets/js/0a185701.3fe6bef4.js delete mode 100644 assets/js/0b745da3.04428ad4.js create mode 100644 assets/js/0b745da3.11825daf.js rename assets/js/{0bf91782.caa55d3c.js => 0bf91782.3e421779.js} (56%) delete mode 100644 assets/js/0dc90373.48fe1927.js create mode 100644 assets/js/0dc90373.eb82127b.js create mode 100644 assets/js/0e7cda11.11e5d9ca.js delete mode 100644 assets/js/0e7cda11.f86c28ee.js delete mode 100644 assets/js/0f1fb433.6680edfb.js create mode 100644 assets/js/0f1fb433.9718efdd.js create mode 100644 assets/js/0f9ab0f2.0598045f.js delete mode 100644 assets/js/0f9ab0f2.af2be204.js create mode 100644 assets/js/1133e639.6d5e2522.js delete mode 100644 assets/js/1133e639.928746f5.js delete mode 100644 assets/js/16d34038.81cad349.js delete mode 100644 assets/js/1759e3b3.75e8d80c.js create mode 100644 assets/js/1759e3b3.c16cd999.js rename assets/js/{17b56dd8.d2019cde.js => 17b56dd8.6a3aeb77.js} (58%) create mode 100644 assets/js/1835c74b.2bfb8617.js delete mode 100644 assets/js/1835c74b.db986336.js delete mode 100644 assets/js/1898401f.c9ca6608.js create mode 100644 assets/js/1898401f.fa90b4f7.js create mode 100644 assets/js/1961a063.3d193eee.js delete mode 100644 assets/js/1961a063.a8071215.js delete mode 100644 assets/js/1977b36b.5f3b145b.js create mode 100644 assets/js/1977b36b.b788d5ee.js create mode 100644 assets/js/19d6fa9a.79cacd6f.js delete mode 100644 assets/js/19d6fa9a.f1b43ebd.js rename assets/js/{19fdd558.96c6b381.js => 19fdd558.e466c4e8.js} (57%) rename assets/js/{1a5f5579.53344ca5.js => 1a5f5579.4a2ddacb.js} (61%) delete mode 100644 assets/js/1aa0cc2e.a3da7fb0.js create mode 100644 assets/js/1aa0cc2e.da5c9ea0.js create mode 100644 assets/js/1aea322a.6265a3e0.js delete mode 100644 assets/js/1aea322a.9a3c594c.js rename assets/js/{1b99e815.2d9143d4.js => 1b99e815.e0cdc2d3.js} (56%) delete mode 100644 assets/js/1c549a2d.333ccd1c.js create mode 100644 assets/js/1c549a2d.aac0a3f6.js create mode 100644 assets/js/1fe9451f.4658cdba.js delete mode 100644 assets/js/1fe9451f.ca1c3b23.js delete mode 100644 assets/js/20d5d8d7.ba287408.js create mode 100644 assets/js/20d5d8d7.cc383b35.js rename assets/js/{2115f1af.f7d9fd25.js => 2115f1af.d9a37f9b.js} (55%) create mode 100644 assets/js/22cda74c.1ecaea8f.js delete mode 100644 assets/js/22cda74c.6ea7132b.js delete mode 100644 assets/js/2353ab8e.6804a17b.js create mode 100644 assets/js/2353ab8e.dcd1b566.js rename assets/js/{237b575e.15551eb2.js => 237b575e.45b6ef1e.js} (59%) delete mode 100644 assets/js/23bbb932.52032b41.js create mode 100644 assets/js/23bbb932.726ad797.js create mode 100644 assets/js/26fe9297.96894e7f.js delete mode 100644 assets/js/26fe9297.bbc7d4f8.js delete mode 100644 assets/js/28005ec6.5b4c5ee5.js create mode 100644 assets/js/28005ec6.6599965d.js create mode 100644 assets/js/281e8991.490faf47.js delete mode 100644 assets/js/281e8991.d6d8d49d.js rename assets/js/{287f5fa1.e7768f6e.js => 287f5fa1.75a3faa3.js} (56%) rename assets/js/{28de08e8.9a8c6761.js => 28de08e8.796c1f89.js} (50%) delete mode 100644 assets/js/2b4be8fd.0ebc72ab.js create mode 100644 assets/js/2b4be8fd.ec338e27.js delete mode 100644 assets/js/2e98070f.462da715.js create mode 100644 assets/js/2e98070f.ba257614.js create mode 100644 assets/js/2e999f74.101389b3.js delete mode 100644 assets/js/2e999f74.a2353f97.js create mode 100644 assets/js/30546e72.9178b7fb.js delete mode 100644 assets/js/30546e72.e9bbd5b0.js rename assets/js/{305bace7.541a67ad.js => 305bace7.a69aabe8.js} (70%) delete mode 100644 assets/js/32000204.2c8aa695.js create mode 100644 assets/js/32000204.61d2178b.js delete mode 100644 assets/js/32956a74.522512e9.js create mode 100644 assets/js/32956a74.6ee24615.js rename assets/js/{33c8bfc8.175f08eb.js => 33c8bfc8.26688612.js} (63%) rename assets/js/{34bf352d.1c76b491.js => 34bf352d.7c19c4b2.js} (58%) delete mode 100644 assets/js/3536e8ef.af8d45ec.js create mode 100644 assets/js/3536e8ef.cc81c73d.js delete mode 100644 assets/js/3712c5a4.2bb652b5.js create mode 100644 assets/js/3712c5a4.cfbc991f.js rename assets/js/{3715f14e.6cadf77f.js => 3715f14e.ab9bba0e.js} (62%) rename assets/js/{376ee327.6f6e1672.js => 376ee327.c6e6e730.js} (79%) delete mode 100644 assets/js/37badd01.452e0e5c.js create mode 100644 assets/js/37badd01.6e9d76a9.js rename assets/js/{39a759e2.003052fb.js => 39a759e2.4f82439b.js} (73%) delete mode 100644 assets/js/3a980746.018d6b6c.js create mode 100644 assets/js/3a980746.cfba503b.js rename assets/js/{3b1f5c9a.4a74a1a0.js => 3b1f5c9a.15db957d.js} (54%) delete mode 100644 assets/js/3ba9be36.02f87a61.js create mode 100644 assets/js/3ba9be36.2230bb4e.js delete mode 100644 assets/js/3bda864c.983d1487.js create mode 100644 assets/js/3bda864c.fb59e54b.js create mode 100644 assets/js/3c3bc024.329f8bb0.js delete mode 100644 assets/js/3c3bc024.dab5524f.js create mode 100644 assets/js/3d3b6af8.83e8c78f.js delete mode 100644 assets/js/3d3b6af8.840d42ce.js rename assets/js/{3de240dc.97be4a01.js => 3de240dc.fbdcaaa2.js} (59%) create mode 100644 assets/js/4032a3e5.3e801b32.js delete mode 100644 assets/js/4032a3e5.8e8b71c9.js create mode 100644 assets/js/407e1392.ea639fd9.js delete mode 100644 assets/js/407e1392.f0923f60.js create mode 100644 assets/js/434d80d9.8389b7c3.js delete mode 100644 assets/js/434d80d9.a0959f68.js rename assets/js/{4406c285.72a024a5.js => 4406c285.c769db72.js} (61%) rename assets/js/{44a7a3de.4a4e8a9d.js => 44a7a3de.3f45a4db.js} (72%) create mode 100644 assets/js/45bfe338.470cc412.js delete mode 100644 assets/js/45bfe338.adb144b4.js delete mode 100644 assets/js/47d45151.18ace9fc.js create mode 100644 assets/js/47d45151.e66857e2.js create mode 100644 assets/js/497c7ba5.6e9bf2ab.js delete mode 100644 assets/js/497c7ba5.a4ee2553.js create mode 100644 assets/js/4a6d5a33.33808d51.js delete mode 100644 assets/js/4a6d5a33.749feba8.js create mode 100644 assets/js/4ac8e691.0fda8509.js delete mode 100644 assets/js/4ac8e691.9bed4cad.js rename assets/js/{4b36b697.b28ddd16.js => 4b36b697.141e98b4.js} (64%) create mode 100644 assets/js/4c493feb.2493bdf2.js delete mode 100644 assets/js/4c493feb.c1159b54.js create mode 100644 assets/js/4d1b877d.4f983a44.js delete mode 100644 assets/js/4d1b877d.bf2731fe.js create mode 100644 assets/js/4df25393.3cb01d89.js delete mode 100644 assets/js/4df25393.dd212270.js rename assets/js/{4e363eb9.4b344b64.js => 4e363eb9.4909794c.js} (57%) create mode 100644 assets/js/50dd26bc.407076be.js delete mode 100644 assets/js/50dd26bc.b1ec5a82.js rename assets/js/{5114ba79.e6452f9d.js => 5114ba79.48a06846.js} (60%) delete mode 100644 assets/js/5276ed9c.c5d1e5be.js create mode 100644 assets/js/5276ed9c.eefa78c9.js create mode 100644 assets/js/55141fa2.1c98af2d.js delete mode 100644 assets/js/55141fa2.6b6b35ce.js create mode 100644 assets/js/551843d2.362a0ef6.js delete mode 100644 assets/js/551843d2.41313eba.js delete mode 100644 assets/js/56362d1e.67075293.js create mode 100644 assets/js/56362d1e.7f27268d.js rename assets/js/{566dbdc9.3f454234.js => 566dbdc9.310585c2.js} (82%) create mode 100644 assets/js/5674e156.7499a6c1.js delete mode 100644 assets/js/5674e156.b028d47e.js create mode 100644 assets/js/56d50f7c.0e2ca84e.js delete mode 100644 assets/js/56d50f7c.bc0aede7.js delete mode 100644 assets/js/595d2708.6fc2fd7a.js create mode 100644 assets/js/595d2708.b1d29a11.js rename assets/js/{5ad344a5.6fa21c2b.js => 5ad344a5.2e48a8bf.js} (54%) create mode 100644 assets/js/5b1b6e2c.2a2121dd.js delete mode 100644 assets/js/5b1b6e2c.b8eb5e1e.js rename assets/js/{5ea39018.20823a8f.js => 5ea39018.92e4ec51.js} (50%) create mode 100644 assets/js/5ec8c180.a1e9f0a7.js create mode 100644 assets/js/5ee164ec.4263c688.js delete mode 100644 assets/js/5ee164ec.7fe6e530.js create mode 100644 assets/js/5f456afb.271ca9f7.js delete mode 100644 assets/js/5f456afb.d7c709c3.js create mode 100644 assets/js/5fff1932.63a9af64.js delete mode 100644 assets/js/5fff1932.64ded398.js delete mode 100644 assets/js/600a00a0.06d75661.js create mode 100644 assets/js/600a00a0.19fc5231.js create mode 100644 assets/js/60cc01db.51acc0e7.js delete mode 100644 assets/js/60cc01db.bd18c39c.js create mode 100644 assets/js/61f95e53.0e8b8130.js delete mode 100644 assets/js/61f95e53.13d744d9.js rename assets/js/{630accb9.4a58b7ec.js => 630accb9.4c8f8a7e.js} (80%) rename assets/js/{640c7392.757dc55f.js => 640c7392.5fc45ad2.js} (69%) create mode 100644 assets/js/69e6dfa6.2a081405.js delete mode 100644 assets/js/69e6dfa6.2fc299cc.js delete mode 100644 assets/js/6a034c6e.25cb7092.js create mode 100644 assets/js/6a034c6e.4dc0c5ac.js create mode 100644 assets/js/6b830420.2351029d.js delete mode 100644 assets/js/6b830420.b5fd3075.js create mode 100644 assets/js/6eb5e412.5292b49c.js delete mode 100644 assets/js/6eb5e412.84c97c04.js create mode 100644 assets/js/6ece4ae7.c4c6fb3f.js delete mode 100644 assets/js/6ece4ae7.ea904ef8.js create mode 100644 assets/js/6fb6dfc9.71c1905c.js delete mode 100644 assets/js/6fb6dfc9.e8920cf5.js rename assets/js/{7062af80.1c782dc5.js => 7062af80.0f6b4260.js} (68%) delete mode 100644 assets/js/70dfc3b7.490b71e4.js create mode 100644 assets/js/70dfc3b7.97f702cd.js rename assets/js/{70fd01e9.8b775c16.js => 70fd01e9.af28bc51.js} (69%) create mode 100644 assets/js/72ae1949.1864e971.js delete mode 100644 assets/js/72ae1949.3f745ef1.js create mode 100644 assets/js/72c158da.6b232634.js delete mode 100644 assets/js/72c158da.eccd5906.js rename assets/js/{735b5664.b44170e2.js => 735b5664.3f93833d.js} (57%) delete mode 100644 assets/js/75071e09.91cf8ea0.js create mode 100644 assets/js/75071e09.bf149714.js rename assets/js/{7590d161.45961935.js => 7590d161.67c28f14.js} (54%) delete mode 100644 assets/js/76b33887.1ab6b263.js create mode 100644 assets/js/76b33887.749220b6.js delete mode 100644 assets/js/7772ebc2.11cd736f.js create mode 100644 assets/js/7772ebc2.e028e064.js create mode 100644 assets/js/77c6b439.613db0a6.js delete mode 100644 assets/js/77c6b439.a486d3a5.js delete mode 100644 assets/js/78ec9a9a.0ec5e5f6.js create mode 100644 assets/js/78ec9a9a.4cdedd58.js create mode 100644 assets/js/79b30505.121a45b0.js delete mode 100644 assets/js/79b30505.afc2508c.js create mode 100644 assets/js/7b92056b.1d96726c.js delete mode 100644 assets/js/7b92056b.b2c99df4.js rename assets/js/{7d19cf58.48b5dd20.js => 7d19cf58.9c4cd7e8.js} (51%) create mode 100644 assets/js/7dad11d2.124f1ab7.js delete mode 100644 assets/js/7dad11d2.2974f534.js create mode 100644 assets/js/7f5c0070.6531cfd8.js delete mode 100644 assets/js/7f5c0070.bac41f7f.js rename assets/js/{82029501.26d61c93.js => 82029501.18008d5b.js} (56%) create mode 100644 assets/js/821c5d9e.0845ce23.js delete mode 100644 assets/js/821c5d9e.cfaf598f.js delete mode 100644 assets/js/82345ec9.bb06a026.js create mode 100644 assets/js/82345ec9.fa9665d4.js delete mode 100644 assets/js/82e833af.89312298.js create mode 100644 assets/js/82e833af.c38d7cc4.js create mode 100644 assets/js/83192466.380d49f8.js delete mode 100644 assets/js/83192466.b599c16b.js create mode 100644 assets/js/837fd906.6bd427c4.js delete mode 100644 assets/js/837fd906.86c0be46.js delete mode 100644 assets/js/83e1f194.98952125.js create mode 100644 assets/js/83e1f194.ad69af40.js create mode 100644 assets/js/8619d2de.06f3901b.js delete mode 100644 assets/js/8619d2de.761efd9a.js rename assets/js/{86764c80.a8f97a1b.js => 86764c80.55f9b4ab.js} (58%) create mode 100644 assets/js/87668920.4aa96a90.js delete mode 100644 assets/js/87668920.57da924c.js delete mode 100644 assets/js/87ed36d5.0da94ca9.js create mode 100644 assets/js/87ed36d5.53343c6e.js create mode 100644 assets/js/8827e5e6.3a01b91b.js delete mode 100644 assets/js/8827e5e6.41c4aebf.js delete mode 100644 assets/js/8a2c5ffd.71805797.js create mode 100644 assets/js/8a2c5ffd.a2f6d36d.js delete mode 100644 assets/js/8b19a93e.8496eafd.js create mode 100644 assets/js/8b19a93e.8979ef6f.js delete mode 100644 assets/js/8b810823.3ca25134.js create mode 100644 assets/js/8b810823.f6490f68.js create mode 100644 assets/js/8d59c070.00f6a67d.js delete mode 100644 assets/js/8d59c070.2ce7053f.js delete mode 100644 assets/js/8e17bf11.5d8d059f.js create mode 100644 assets/js/8e17bf11.c4f869d6.js rename assets/js/{8ebb0243.1fa866ba.js => 8ebb0243.5d1db1a5.js} (51%) rename assets/js/{8f5adede.82d08ed6.js => 8f5adede.89b38597.js} (54%) delete mode 100644 assets/js/8fcded8c.0579ecc9.js create mode 100644 assets/js/8fcded8c.63397745.js rename assets/js/{92e7585f.fd59f9f3.js => 92e7585f.af0bf984.js} (51%) create mode 100644 assets/js/935f2afb.009b227a.js delete mode 100644 assets/js/935f2afb.c61778ca.js create mode 100644 assets/js/9595b411.88e3cf18.js delete mode 100644 assets/js/9595b411.e4151beb.js delete mode 100644 assets/js/9662bf8d.a11ba1b1.js create mode 100644 assets/js/9662bf8d.e0078cb6.js create mode 100644 assets/js/977fdfc4.4b11e617.js delete mode 100644 assets/js/977fdfc4.f3c7fcf1.js create mode 100644 assets/js/97d4b178.23c0f1d6.js delete mode 100644 assets/js/97d4b178.5c4f0b6b.js delete mode 100644 assets/js/99000770.1311682f.js create mode 100644 assets/js/99000770.ffe7dc96.js create mode 100644 assets/js/990e3068.d6055d90.js delete mode 100644 assets/js/990e3068.f5be684b.js delete mode 100644 assets/js/99153eb1.5a891290.js create mode 100644 assets/js/99153eb1.dbb20b4b.js delete mode 100644 assets/js/9aa57586.7b227a3b.js create mode 100644 assets/js/9aa57586.b95d248d.js delete mode 100644 assets/js/9c804087.1dc9d49f.js create mode 100644 assets/js/9c804087.6aaba070.js delete mode 100644 assets/js/9d1d9869.167e28fc.js create mode 100644 assets/js/9d1d9869.7c820359.js rename assets/js/{9e3571d8.38e01710.js => 9e3571d8.57689d11.js} (54%) create mode 100644 assets/js/9f069a65.668f0f89.js delete mode 100644 assets/js/9f069a65.932ffb24.js create mode 100644 assets/js/9fc66687.57aa4047.js delete mode 100644 assets/js/9fc66687.5b4b8dbc.js delete mode 100644 assets/js/a08f9b67.0653218e.js create mode 100644 assets/js/a08f9b67.4e677d30.js rename assets/js/{a121ee0b.4f7f6d44.js => a121ee0b.8eda715d.js} (67%) create mode 100644 assets/js/a27ca0d9.32308675.js delete mode 100644 assets/js/a27ca0d9.d5833bb9.js create mode 100644 assets/js/a28f322c.64c84735.js delete mode 100644 assets/js/a28f322c.efc35126.js delete mode 100644 assets/js/a5969c3a.2e2ca053.js create mode 100644 assets/js/a5969c3a.f64b85e6.js rename assets/js/{a8f9fa37.c668e600.js => a8f9fa37.32f56175.js} (50%) delete mode 100644 assets/js/abc4e0a8.01396e1a.js create mode 100644 assets/js/abc4e0a8.40e42a93.js delete mode 100644 assets/js/ad602bef.54441f42.js create mode 100644 assets/js/ad602bef.d706b590.js create mode 100644 assets/js/adf149f0.635eafd2.js delete mode 100644 assets/js/adf149f0.6a84419c.js delete mode 100644 assets/js/aec48fb4.47698132.js create mode 100644 assets/js/aec48fb4.e21b233c.js create mode 100644 assets/js/af046d03.0c8d20c1.js delete mode 100644 assets/js/af046d03.6f24420a.js delete mode 100644 assets/js/af2e79ee.00cacc63.js create mode 100644 assets/js/af2e79ee.9daf7eac.js create mode 100644 assets/js/b049517a.75e46ed3.js delete mode 100644 assets/js/b049517a.e4ec7dff.js create mode 100644 assets/js/b075c519.7635c071.js delete mode 100644 assets/js/b075c519.ce1d6b1a.js create mode 100644 assets/js/b2f45e36.6ac4def4.js delete mode 100644 assets/js/b2f45e36.99cc16c4.js delete mode 100644 assets/js/b3471d8e.746a2f4c.js create mode 100644 assets/js/b3471d8e.ad00d781.js create mode 100644 assets/js/b34bf6de.6ed79029.js delete mode 100644 assets/js/b34bf6de.838dcca3.js rename assets/js/{5ec8c180.cb041950.js => b44b4ce2.475485ff.js} (75%) delete mode 100644 assets/js/b44b4ce2.a0de6e32.js delete mode 100644 assets/js/b46813dd.364c88b4.js create mode 100644 assets/js/b46813dd.a11fb422.js delete mode 100644 assets/js/b509c81b.aeea8285.js create mode 100644 assets/js/b509c81b.b10ec20a.js delete mode 100644 assets/js/b57a4a2d.04ebf6ac.js create mode 100644 assets/js/b57a4a2d.3b54e102.js delete mode 100644 assets/js/b5d95ae4.69d9052f.js create mode 100644 assets/js/b5d95ae4.abfc5821.js rename assets/js/{b6cf2faa.37ca3985.js => b6cf2faa.183608ed.js} (82%) create mode 100644 assets/js/b6dea0ad.5d55a0d7.js delete mode 100644 assets/js/b6dea0ad.cd24d5b1.js rename assets/js/{b70fdfcb.fb1bde34.js => b70fdfcb.079b5d16.js} (85%) rename assets/js/{b72e870b.04febfb1.js => b72e870b.32e861fd.js} (56%) create mode 100644 assets/js/b7847a20.c0ab7bba.js delete mode 100644 assets/js/b7847a20.d3e7f5b2.js rename assets/js/{b8caf01f.0df1e7b0.js => b8caf01f.de8cdbb9.js} (58%) delete mode 100644 assets/js/b9b61d04.15460c78.js create mode 100644 assets/js/b9b61d04.e07f242c.js create mode 100644 assets/js/baa12f70.132881b4.js delete mode 100644 assets/js/baa12f70.733a15a2.js rename assets/js/{bbff1c36.41c592be.js => bbff1c36.e41b8a00.js} (61%) create mode 100644 assets/js/bc5f1a80.0df8560d.js delete mode 100644 assets/js/bc5f1a80.ee7d23c2.js create mode 100644 assets/js/c02a675f.92d65b30.js delete mode 100644 assets/js/c02a675f.9d8def74.js delete mode 100644 assets/js/c09b0fe7.660076a3.js create mode 100644 assets/js/c09b0fe7.a66e4b54.js create mode 100644 assets/js/c15b59ba.582524dc.js delete mode 100644 assets/js/c15b59ba.ef28dfaa.js create mode 100644 assets/js/c1bf8f22.5cf2e82b.js delete mode 100644 assets/js/c1bf8f22.d2bba25b.js delete mode 100644 assets/js/c2884f74.27697d2b.js create mode 100644 assets/js/c2884f74.d0b0ad50.js delete mode 100644 assets/js/c311d7f4.401ed809.js create mode 100644 assets/js/c311d7f4.d147804d.js create mode 100644 assets/js/c31a6c64.8ec97530.js delete mode 100644 assets/js/c31a6c64.dbba3d47.js rename assets/js/{c3728e1b.46469b73.js => c3728e1b.21bf3d2b.js} (51%) create mode 100644 assets/js/c4ba81c3.2dbc3af6.js delete mode 100644 assets/js/c4ba81c3.cb955b2d.js create mode 100644 assets/js/c5353c60.3e26b543.js delete mode 100644 assets/js/c5353c60.9b747761.js delete mode 100644 assets/js/c5a89df7.1948f9a2.js create mode 100644 assets/js/c5a89df7.f48ef27c.js delete mode 100644 assets/js/c6ae2a42.5cdb0a17.js create mode 100644 assets/js/c6ae2a42.8b27f6a1.js delete mode 100644 assets/js/c7fa01e5.0ccaf230.js create mode 100644 assets/js/c7fa01e5.2ed2e287.js rename assets/js/{cd9e621c.1e08be72.js => cd9e621c.6b430410.js} (55%) create mode 100644 assets/js/d0375dde.535a8363.js delete mode 100644 assets/js/d0375dde.7c666183.js delete mode 100644 assets/js/d05ef132.65b778ef.js create mode 100644 assets/js/d05ef132.ff4dea0a.js delete mode 100644 assets/js/d08bdbd3.29405804.js create mode 100644 assets/js/d08bdbd3.c2a6f40d.js rename assets/js/{d107a415.b51c0c01.js => d107a415.66e33494.js} (55%) create mode 100644 assets/js/d33f5cb2.22228d8c.js delete mode 100644 assets/js/d33f5cb2.8fdce34e.js delete mode 100644 assets/js/d398f178.15ecdd0f.js create mode 100644 assets/js/d398f178.b537c3ee.js create mode 100644 assets/js/d5b05897.a399b999.js delete mode 100644 assets/js/d5b05897.c920e343.js rename assets/js/{d5d68d14.1c4e0780.js => d5d68d14.c5270262.js} (83%) rename assets/js/{d65cad0c.d29f91ad.js => d65cad0c.5f482958.js} (85%) rename assets/js/{d7b729b6.827935fd.js => d7b729b6.96f32350.js} (50%) create mode 100644 assets/js/d9a047ee.31f9d1e2.js delete mode 100644 assets/js/d9a047ee.63be3c37.js create mode 100644 assets/js/da7786fc.6c63c41b.js delete mode 100644 assets/js/da7786fc.bb98a240.js rename assets/js/{db343463.ef5b8864.js => db343463.3da9b571.js} (55%) rename assets/js/{dbbf606f.62860f23.js => dbbf606f.97b635b4.js} (59%) delete mode 100644 assets/js/dc405d94.9417abb8.js create mode 100644 assets/js/dc405d94.9704fa68.js delete mode 100644 assets/js/de200a2a.97fae5c5.js create mode 100644 assets/js/de200a2a.c7ae3379.js delete mode 100644 assets/js/de7874bb.85b47aee.js create mode 100644 assets/js/de7874bb.d96d2922.js delete mode 100644 assets/js/dfc7c90d.2419115f.js create mode 100644 assets/js/dfc7c90d.8a7ed7eb.js create mode 100644 assets/js/e381d75c.bb9d48d2.js delete mode 100644 assets/js/e381d75c.ef4bf99a.js delete mode 100644 assets/js/e4f1eb77.5d5c3e3f.js create mode 100644 assets/js/e4f1eb77.ee805867.js delete mode 100644 assets/js/e6798fa1.59bd1f38.js create mode 100644 assets/js/e6798fa1.86a6cbff.js rename assets/js/{e695a9f3.b7fd9f41.js => e695a9f3.e9c83c36.js} (59%) rename assets/js/{e696141c.fc99a527.js => e696141c.07b0088b.js} (56%) rename assets/js/{e701010f.a002a4c1.js => e701010f.b698b789.js} (53%) delete mode 100644 assets/js/e7e8cb25.6b10ab5e.js create mode 100644 assets/js/e7e8cb25.8655f88d.js delete mode 100644 assets/js/e8149155.9a5b1f0c.js create mode 100644 assets/js/e8149155.d98e2fe2.js rename assets/js/{e877f19f.79dc2d14.js => e877f19f.e3eeb47f.js} (63%) create mode 100644 assets/js/e89e36c0.5babc632.js delete mode 100644 assets/js/e89e36c0.d5a819be.js delete mode 100644 assets/js/ebf27649.a13fb837.js create mode 100644 assets/js/ebf27649.e699151a.js rename assets/js/{ecaa6eee.1683acaa.js => ecaa6eee.eb4b9d9e.js} (54%) create mode 100644 assets/js/ecbd3f41.05abb6bd.js delete mode 100644 assets/js/ecbd3f41.a7744f53.js create mode 100644 assets/js/eccaeac4.538071fd.js delete mode 100644 assets/js/eccaeac4.c95926af.js rename assets/js/{ed2e9c54.8b9e5d08.js => ed2e9c54.ca949112.js} (83%) delete mode 100644 assets/js/ee59e712.905fad65.js create mode 100644 assets/js/ee59e712.f41b3cd0.js delete mode 100644 assets/js/ee68f9c5.3e3baacd.js create mode 100644 assets/js/ee68f9c5.f701e4a5.js rename assets/js/{ee6d0512.ab908c81.js => ee6d0512.1bc64518.js} (81%) create mode 100644 assets/js/f058aa3c.3e6113b2.js delete mode 100644 assets/js/f058aa3c.8ea5185c.js rename assets/js/{f1e404ac.3e9d65b1.js => f1e404ac.481de01c.js} (60%) rename assets/js/{f34acb22.955acd7b.js => f34acb22.6b18f013.js} (65%) delete mode 100644 assets/js/f35beff3.291f9bb5.js create mode 100644 assets/js/f35beff3.6d7affb8.js rename assets/js/{f4eeafd2.4a8b45c3.js => f4eeafd2.fb43806c.js} (82%) rename assets/js/{f655a87f.5fbe324e.js => f655a87f.c0d72261.js} (85%) delete mode 100644 assets/js/f7f2164e.081d3b09.js create mode 100644 assets/js/f7f2164e.9737060e.js create mode 100644 assets/js/f9476b7a.049b6102.js delete mode 100644 assets/js/f9476b7a.add3b000.js delete mode 100644 assets/js/fa47a47e.097ed95e.js create mode 100644 assets/js/fa47a47e.c61f88d3.js create mode 100644 assets/js/fd1fdd14.01b0b155.js delete mode 100644 assets/js/fd1fdd14.915e24d2.js rename assets/js/{fdecbe36.4346cf95.js => fdecbe36.0de627fd.js} (50%) create mode 100644 assets/js/main.3e823d7e.js rename assets/js/{main.bce0811d.js.LICENSE.txt => main.3e823d7e.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.bce0811d.js delete mode 100644 assets/js/runtime~main.884946b6.js create mode 100644 assets/js/runtime~main.b5a7af0a.js delete mode 100644 docs/next/kusion/concepts/backend-configuration/index.html create mode 100644 docs/next/kusion/concepts/backend/index.html diff --git a/404.html b/404.html index e7cf5df9e9b..d8df4e5e340 100644 --- a/404.html +++ b/404.html @@ -13,13 +13,13 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/assets/js/03c33ea8.58c891d5.js b/assets/js/03c33ea8.58c891d5.js deleted file mode 100644 index 2daae01e904..00000000000 --- a/assets/js/03c33ea8.58c891d5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8230],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=p(n),m=r,k=u["".concat(l,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,s(s({ref:t},d),{},{components:n})):a.createElement(k,s({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={sidebar_position:2},s="Deliver the WordPress Application on Kubernetes",i={unversionedId:"kusion/getting-started/deliver-wordpress",id:"version-v0.9/kusion/getting-started/deliver-wordpress",title:"Deliver the WordPress Application on Kubernetes",description:"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.",source:"@site/versioned_docs/version-v0.9/kusion/getting-started/deliver-wordpress.md",sourceDirName:"kusion/getting-started",slug:"/kusion/getting-started/deliver-wordpress",permalink:"/docs/v0.9/kusion/getting-started/deliver-wordpress",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/getting-started/deliver-wordpress.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Install Kusion",permalink:"/docs/v0.9/kusion/getting-started/install-kusion"},next:{title:"Concepts",permalink:"/docs/v0.9/kusion/concepts/"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Config Files",id:"review-config-files",level:3},{value:"Delivery",id:"delivery",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],d={toc:p};function c(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-on-kubernetes"},"Deliver the WordPress Application on Kubernetes"),(0,r.kt)("p",null,"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Before we start to play with this example, we need to have the Kusion CLI installed and run a Kubernetes cluster. Here are some helpful documentations: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"install-kusion"},"Kusion CLI")),(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," CLI and run a ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," cluster. Some light and convenient options for local deployment include ",(0,r.kt)("a",{parentName:"li",href:"https://docs.k3s.io/quick-start"},"k3s"),", ",(0,r.kt)("a",{parentName:"li",href:"https://k3d.io/v5.4.4/#installation"},"k3d"),", and ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"MiniKube"),". ")),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: [Use arrows to move, type to filter]\n code-city Code City metaphor for visualizing Go source code in 3D.\n deployment-multi-stack A minimal kusion project of multiple stacks\n deployment-single-stack A minimal kusion project of single stack\n> wordpress A sample wordpress project\n wordpress-cloud-rds A sample wordpress project with cloud rds\n")),(0,r.kt)("p",null,"Please select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),", after which we will see the hints below and use the default value to config this project and stack. "),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(48024).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress && tree\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress && tree\n.\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n1 directory, 5 files\n\u279c wordpress\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,r.kt)("a",{parentName:"p",href:"../concepts/glossary"},"Concepts"),". ")),(0,r.kt)("h3",{id:"review-config-files"},"Review Config Files"),(0,r.kt)("p",null,"Now let's have a glance at the configuration files at ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k"),": "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.trait as t\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.secret as sec\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.accessories.database as db\n\n# main.k declares reusable configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: db.Database {\n type: "local"\n engine: "mysql"\n version: "8.0"\n }\n}\n')),(0,r.kt)("p",null,"The configuration file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k")," includes an ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress"),". The ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a wordload of type ",(0,r.kt)("inlineCode",{parentName:"p"},"wl.Service"),", which runs on 1 replica and exposes ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," to be accessed. Besides, it declares a local ",(0,r.kt)("inlineCode",{parentName:"p"},"db.Database")," accessory with the engine of ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql:8.0")," for the application. The necessary Kubernetes resources for deploying and using the local database will be generated, and users can get the ",(0,r.kt)("inlineCode",{parentName:"p"},"host address"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"paasword")," through the ",(0,r.kt)("a",{parentName:"p",href:"../reference/model/naming-conventions#sensitive-database-information"},"magic variables for sensitive database information")," of Kusion in application containers. "),(0,r.kt)("p",null,"This model hides the major complexity of Kubernetes resources such as ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Service"),", which providing the concepts that are application-centric and infrastructure-agnostic. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the Models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("h2",{id:"delivery"},"Delivery"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd dev && kusion apply --watch\n")),(0,r.kt)("p",null,"Go to the ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," folder and we will deliver the WordPress application into the Kubernetes cluster with one command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply --watch"),". "),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(11273).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"Check ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment")," status. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n wordpress get deployment\n")),(0,r.kt)("p",null,"The expected output is shown as follows: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl -n wordpress get deploy\nNAME READY UP-TO-DATE AVAILABLE AGE\nwordpress-dev-wordpress 1/1 1 1 2m23s\nwordpress-db-local-deployment 1/1 1 1 2m23s\n")),(0,r.kt)("p",null,"Port-forward our WordPress with the ",(0,r.kt)("inlineCode",{parentName:"p"},"Service"),". "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress service/wordpress-dev-wordpress-private 12345:80\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl port-forward -n wordpress service/wordpress-dev-wordpress-private 12345:80\nForwarding from 127.0.0.1:12345 -> 80\nForwarding from [::1]:12345 -> 80\n\n")),(0,r.kt)("p",null,"Now we can visit ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"http://localhost:12345")," in our browser and enjoy!"),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(85773).Z,width:"1500",height:"803"})),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"We can delete the WordPress application and related database resources using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(82864).Z,width:"2560",height:"1440"})))}c.isMDXComponent=!0},11273:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/apply-wordpress-with-local-db-33e34e0fa75349c20a8d3c561d2d6c5c.gif"},48024:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/init-wordpress-with-local-db-1a3e0c28ac010e686185e787ec2929a3.gif"},85773:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"},82864:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-with-local-db-destroy-9a46e6e09977721984044b31e29b6b78.gif"}}]); \ No newline at end of file diff --git a/assets/js/03c33ea8.ad31b494.js b/assets/js/03c33ea8.ad31b494.js new file mode 100644 index 00000000000..9b1dc608835 --- /dev/null +++ b/assets/js/03c33ea8.ad31b494.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8230],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=p(n),m=r,k=u["".concat(l,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,s(s({ref:t},d),{},{components:n})):a.createElement(k,s({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={sidebar_position:2},s="Deliver the WordPress Application on Kubernetes",i={unversionedId:"kusion/getting-started/deliver-wordpress",id:"version-v0.9/kusion/getting-started/deliver-wordpress",title:"Deliver the WordPress Application on Kubernetes",description:"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.",source:"@site/versioned_docs/version-v0.9/kusion/getting-started/deliver-wordpress.md",sourceDirName:"kusion/getting-started",slug:"/kusion/getting-started/deliver-wordpress",permalink:"/docs/v0.9/kusion/getting-started/deliver-wordpress",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/getting-started/deliver-wordpress.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Install Kusion",permalink:"/docs/v0.9/kusion/getting-started/install-kusion"},next:{title:"Concepts",permalink:"/docs/v0.9/kusion/concepts/"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Config Files",id:"review-config-files",level:3},{value:"Delivery",id:"delivery",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],d={toc:p};function c(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-on-kubernetes"},"Deliver the WordPress Application on Kubernetes"),(0,r.kt)("p",null,"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Before we start to play with this example, we need to have the Kusion CLI installed and run a Kubernetes cluster. Here are some helpful documentations: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"install-kusion"},"Kusion CLI")),(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," CLI and run a ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," cluster. Some light and convenient options for local deployment include ",(0,r.kt)("a",{parentName:"li",href:"https://docs.k3s.io/quick-start"},"k3s"),", ",(0,r.kt)("a",{parentName:"li",href:"https://k3d.io/v5.4.4/#installation"},"k3d"),", and ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"MiniKube"),". ")),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: [Use arrows to move, type to filter]\n code-city Code City metaphor for visualizing Go source code in 3D.\n deployment-multi-stack A minimal kusion project of multiple stacks\n deployment-single-stack A minimal kusion project of single stack\n> wordpress A sample wordpress project\n wordpress-cloud-rds A sample wordpress project with cloud rds\n")),(0,r.kt)("p",null,"Please select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),", after which we will see the hints below and use the default value to config this project and stack. "),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(48024).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress && tree\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress && tree\n.\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n1 directory, 5 files\n\u279c wordpress\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,r.kt)("a",{parentName:"p",href:"../concepts/glossary"},"Concepts"),". ")),(0,r.kt)("h3",{id:"review-config-files"},"Review Config Files"),(0,r.kt)("p",null,"Now let's have a glance at the configuration files at ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k"),": "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.trait as t\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.secret as sec\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.accessories.database as db\n\n# main.k declares reusable configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: db.Database {\n type: "local"\n engine: "mysql"\n version: "8.0"\n }\n}\n')),(0,r.kt)("p",null,"The configuration file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k")," includes an ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress"),". The ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a wordload of type ",(0,r.kt)("inlineCode",{parentName:"p"},"wl.Service"),", which runs on 1 replica and exposes ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," to be accessed. Besides, it declares a local ",(0,r.kt)("inlineCode",{parentName:"p"},"db.Database")," accessory with the engine of ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql:8.0")," for the application. The necessary Kubernetes resources for deploying and using the local database will be generated, and users can get the ",(0,r.kt)("inlineCode",{parentName:"p"},"host address"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"paasword")," through the ",(0,r.kt)("a",{parentName:"p",href:"../reference/model/naming-conventions#sensitive-database-information"},"magic variables for sensitive database information")," of Kusion in application containers. "),(0,r.kt)("p",null,"This model hides the major complexity of Kubernetes resources such as ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Service"),", which providing the concepts that are application-centric and infrastructure-agnostic. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the Models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("h2",{id:"delivery"},"Delivery"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd dev && kusion apply --watch\n")),(0,r.kt)("p",null,"Go to the ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," folder and we will deliver the WordPress application into the Kubernetes cluster with one command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply --watch"),". "),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(11273).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"Check ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment")," status. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n wordpress get deployment\n")),(0,r.kt)("p",null,"The expected output is shown as follows: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl -n wordpress get deploy\nNAME READY UP-TO-DATE AVAILABLE AGE\nwordpress-dev-wordpress 1/1 1 1 2m23s\nwordpress-db-local-deployment 1/1 1 1 2m23s\n")),(0,r.kt)("p",null,"Port-forward our WordPress with the ",(0,r.kt)("inlineCode",{parentName:"p"},"Service"),". "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress service/wordpress-dev-wordpress-private 12345:80\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl port-forward -n wordpress service/wordpress-dev-wordpress-private 12345:80\nForwarding from 127.0.0.1:12345 -> 80\nForwarding from [::1]:12345 -> 80\n\n")),(0,r.kt)("p",null,"Now we can visit ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"http://localhost:12345")," in our browser and enjoy!"),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(85773).Z,width:"1500",height:"803"})),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"We can delete the WordPress application and related database resources using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(82864).Z,width:"2560",height:"1440"})))}c.isMDXComponent=!0},11273:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/apply-wordpress-with-local-db-33e34e0fa75349c20a8d3c561d2d6c5c.gif"},48024:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/init-wordpress-with-local-db-1a3e0c28ac010e686185e787ec2929a3.gif"},85773:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"},82864:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-with-local-db-destroy-9a46e6e09977721984044b31e29b6b78.gif"}}]); \ No newline at end of file diff --git a/assets/js/043680c6.67e00309.js b/assets/js/043680c6.67e00309.js deleted file mode 100644 index 88b22bb6b44..00000000000 --- a/assets/js/043680c6.67e00309.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1753],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,k=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,s(s({ref:t},p),{},{components:n})):r.createElement(k,s({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,s[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const o={id:"secret"},s="Secrets",i={unversionedId:"kusion/configuration-walkthrough/secret",id:"kusion/configuration-walkthrough/secret",title:"Secrets",description:"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers.",source:"@site/docs/kusion/4-configuration-walkthrough/7-secret.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/secret",permalink:"/docs/next/kusion/configuration-walkthrough/secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/7-secret.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"secret"},sidebar:"kusion",previous:{title:"Managed Databases",permalink:"/docs/next/kusion/configuration-walkthrough/databse"},next:{title:"Application Monitoring",permalink:"/docs/next/kusion/configuration-walkthrough/monitoring"}},c={},l=[{value:"Using secrets in workload",id:"using-secrets-in-workload",level:2},{value:"Consume secret in an environment variable",id:"consume-secret-in-an-environment-variable",level:3},{value:"Consume all secret keys as environment variables",id:"consume-all-secret-keys-as-environment-variables",level:3},{value:"Types of secrets",id:"types-of-secrets",level:2},{value:"Basic secrets",id:"basic-secrets",level:3},{value:"Token secrets",id:"token-secrets",level:3},{value:"Opaque secrets",id:"opaque-secrets",level:3},{value:"Certificate secrets",id:"certificate-secrets",level:3},{value:"External secrets",id:"external-secrets",level:3},{value:"Immutable secrets",id:"immutable-secrets",level:2}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secrets"},"Secrets"),(0,a.kt)("p",null,"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers."),(0,a.kt)("p",null,"For application dependent cloud resources that are managed by Kusion, their credentials are automatically managed by Kusion (generated and injected into application runtime environment variable). You shouldn't have to manually create those."),(0,a.kt)("h2",{id:"using-secrets-in-workload"},"Using secrets in workload"),(0,a.kt)("p",null,"Secrets must be defined in AppConfiguration. The values can be generated by Kusion or reference existing secrets stored in third-party vault. Secrets can be consumed in containers by referencing them through the ",(0,a.kt)("inlineCode",{parentName:"p"},"secret:///")," URI syntax."),(0,a.kt)("h3",{id:"consume-secret-in-an-environment-variable"},"Consume secret in an environment variable"),(0,a.kt)("p",null,"You can consume the data in Secrets as environment variable in your container. For example the db container uses an environment variable to set the root password."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport kam.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume db-root-password secret in environment\n "ROOT_PASSWORD": "secret://db-root-password/token"\n }\n }\n }\n # Secrets used to generate token\n secrets: {\n "init-info": sec.Secret {\n type: "token"\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The example shows the secret ",(0,a.kt)("inlineCode",{parentName:"p"},"root-password")," being consumed as an environment variable in the db container. The secret is of type token and will automatically be generated at runtime by Kusion."),(0,a.kt)("h3",{id:"consume-all-secret-keys-as-environment-variables"},"Consume all secret keys as environment variables"),(0,a.kt)("p",null,"Sometimes your secret contains multiple data that need to be consumed as environment variables. The example below shows how to consume all the values in a secret as environment variables named after the keys."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport kam.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume all init-info secret keys as environment variables\n "secret://init-info": ""\n }\n }\n }\n # Secrets used to init mysql instance\n secrets: {\n "init-info": sec.Secret {\n type: "opaque"\n data: {\n "ROOT_PASSWORD": "admin"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,'This will set the environment variable "ROOT_PASSWORD" to the value "admin" in the db container.'),(0,a.kt)("h2",{id:"types-of-secrets"},"Types of secrets"),(0,a.kt)("p",null,"Kusion provides multiple types of secrets to application developers."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Basic: Used to generate and/or store usernames and passwords."),(0,a.kt)("li",{parentName:"ol"},"Token: Used to generate and/or store secret strings for password."),(0,a.kt)("li",{parentName:"ol"},"Opaque: A generic secret that can store arbitrary user-defined data."),(0,a.kt)("li",{parentName:"ol"},"Certificate: Used to store a certificate and its associated key that are typically used for TLS."),(0,a.kt)("li",{parentName:"ol"},"External: Used to retrieve secret form third-party vault.")),(0,a.kt)("h3",{id:"basic-secrets"},"Basic secrets"),(0,a.kt)("p",null,'Basic secrets are defined in the secrets block with the type "basic".'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "auth-info": sec.Secret {\n type: "basic"\n data: {\n "username": "admin"\n "password": "******"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The basic secret type is typically used for basic authentication. The key names must be username and password. If one or both of the fields are defined with a non-empty string, those values will be used. If the empty string, the default value, is used Acorn will generate random values for one or both."),(0,a.kt)("h3",{id:"token-secrets"},"Token secrets"),(0,a.kt)("p",null,"Token secrets are useful for generating a password or secure string used for passwords when the user is already known or not required."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-token": sec.Secret {\n type: "token"\n data: {\n "token": ""\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The token secret type must be defined. The ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," field in the data object is optional and if left empty Kusion will generate the token, which is 54 characters in length by default. If the ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," is defined that value will always be used."),(0,a.kt)("h3",{id:"opaque-secrets"},"Opaque secrets"),(0,a.kt)("p",null,"Opaque secrets have no defined structure and can have arbitrary key value pairs. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "opaque"\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"certificate-secrets"},"Certificate secrets"),(0,a.kt)("p",null,"Certificate secrets are useful for storing a certificate and its associated key. One common use for TLS Secrets is to configure encryption in transit for an Ingress, but you can also use it with other resources or directly in your workload."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "server-cert": sec.Secret {\n type: "certificate"\n data: {\n # Please do not put private keys in configuration files\n "tls.crt": "The cert file content"\n "tls.key": "The key file content"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"external-secrets"},"External secrets"),(0,a.kt)("p",null,"As a general principle, storing secrets in a plain text configuration file is highly discouraged, keeping secrets outside of Git is especially important for future-proofing, even encrypted secrets are not recommended to check into Git. The most common approach is to store secrets in a third-party vault (such as Hashicorp Vault, AWS Secrets Manager and Azure Key Vault, etc) and retrieve the secret in the runtime only. External secrets are used to retrieve sensitive data from external secret store to make it easy to be consumed in containers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-access-token": sec.Secret {\n type: "external"\n data: {\n # Please do not put private keys in configuration files\n "accessToken": "ref://api-auth-info/accessToken?version=1"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The value field in data object follow ",(0,a.kt)("inlineCode",{parentName:"p"},"ref://PATH[?version=]")," URI syntax. ",(0,a.kt)("inlineCode",{parentName:"p"},"PATH")," is the provider-specific path for the secret to be retried. Kusion provides out-of-the-box integration with ",(0,a.kt)("inlineCode",{parentName:"p"},"Hashicorp Vault"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"AWS Secrets Manager"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Azure Key Vault")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Alicloud Secrets Manager"),"."),(0,a.kt)("h2",{id:"immutable-secrets"},"Immutable secrets"),(0,a.kt)("p",null,"You can also declare a secret as immutable to prevent it from being changed accidentally."),(0,a.kt)("p",null,"To declare a secret as immutable:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n # ...\n immutable: True\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"You can change a secret from mutable to immutable but not the other way around. That is because the Kubelet will stop watching secrets that are immutable. As the name suggests, you can only delete and re-create immutable secrets but you cannot change them."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/043680c6.da1f0f15.js b/assets/js/043680c6.da1f0f15.js new file mode 100644 index 00000000000..73b588deb28 --- /dev/null +++ b/assets/js/043680c6.da1f0f15.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1753],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,k=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,s(s({ref:t},p),{},{components:n})):r.createElement(k,s({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,s[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const o={id:"secret"},s="Secrets",i={unversionedId:"kusion/configuration-walkthrough/secret",id:"kusion/configuration-walkthrough/secret",title:"Secrets",description:"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers.",source:"@site/docs/kusion/4-configuration-walkthrough/7-secret.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/secret",permalink:"/docs/next/kusion/configuration-walkthrough/secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/7-secret.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"secret"},sidebar:"kusion",previous:{title:"Managed Databases",permalink:"/docs/next/kusion/configuration-walkthrough/databse"},next:{title:"Application Monitoring",permalink:"/docs/next/kusion/configuration-walkthrough/monitoring"}},c={},l=[{value:"Using secrets in workload",id:"using-secrets-in-workload",level:2},{value:"Consume secret in an environment variable",id:"consume-secret-in-an-environment-variable",level:3},{value:"Consume all secret keys as environment variables",id:"consume-all-secret-keys-as-environment-variables",level:3},{value:"Types of secrets",id:"types-of-secrets",level:2},{value:"Basic secrets",id:"basic-secrets",level:3},{value:"Token secrets",id:"token-secrets",level:3},{value:"Opaque secrets",id:"opaque-secrets",level:3},{value:"Certificate secrets",id:"certificate-secrets",level:3},{value:"External secrets",id:"external-secrets",level:3},{value:"Immutable secrets",id:"immutable-secrets",level:2}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secrets"},"Secrets"),(0,a.kt)("p",null,"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers."),(0,a.kt)("p",null,"For application dependent cloud resources that are managed by Kusion, their credentials are automatically managed by Kusion (generated and injected into application runtime environment variable). You shouldn't have to manually create those."),(0,a.kt)("h2",{id:"using-secrets-in-workload"},"Using secrets in workload"),(0,a.kt)("p",null,"Secrets must be defined in AppConfiguration. The values can be generated by Kusion or reference existing secrets stored in third-party vault. Secrets can be consumed in containers by referencing them through the ",(0,a.kt)("inlineCode",{parentName:"p"},"secret:///")," URI syntax."),(0,a.kt)("h3",{id:"consume-secret-in-an-environment-variable"},"Consume secret in an environment variable"),(0,a.kt)("p",null,"You can consume the data in Secrets as environment variable in your container. For example the db container uses an environment variable to set the root password."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport kam.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume db-root-password secret in environment\n "ROOT_PASSWORD": "secret://db-root-password/token"\n }\n }\n }\n # Secrets used to generate token\n secrets: {\n "init-info": sec.Secret {\n type: "token"\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The example shows the secret ",(0,a.kt)("inlineCode",{parentName:"p"},"root-password")," being consumed as an environment variable in the db container. The secret is of type token and will automatically be generated at runtime by Kusion."),(0,a.kt)("h3",{id:"consume-all-secret-keys-as-environment-variables"},"Consume all secret keys as environment variables"),(0,a.kt)("p",null,"Sometimes your secret contains multiple data that need to be consumed as environment variables. The example below shows how to consume all the values in a secret as environment variables named after the keys."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport kam.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume all init-info secret keys as environment variables\n "secret://init-info": ""\n }\n }\n }\n # Secrets used to init mysql instance\n secrets: {\n "init-info": sec.Secret {\n type: "opaque"\n data: {\n "ROOT_PASSWORD": "admin"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,'This will set the environment variable "ROOT_PASSWORD" to the value "admin" in the db container.'),(0,a.kt)("h2",{id:"types-of-secrets"},"Types of secrets"),(0,a.kt)("p",null,"Kusion provides multiple types of secrets to application developers."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Basic: Used to generate and/or store usernames and passwords."),(0,a.kt)("li",{parentName:"ol"},"Token: Used to generate and/or store secret strings for password."),(0,a.kt)("li",{parentName:"ol"},"Opaque: A generic secret that can store arbitrary user-defined data."),(0,a.kt)("li",{parentName:"ol"},"Certificate: Used to store a certificate and its associated key that are typically used for TLS."),(0,a.kt)("li",{parentName:"ol"},"External: Used to retrieve secret form third-party vault.")),(0,a.kt)("h3",{id:"basic-secrets"},"Basic secrets"),(0,a.kt)("p",null,'Basic secrets are defined in the secrets block with the type "basic".'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "auth-info": sec.Secret {\n type: "basic"\n data: {\n "username": "admin"\n "password": "******"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The basic secret type is typically used for basic authentication. The key names must be username and password. If one or both of the fields are defined with a non-empty string, those values will be used. If the empty string, the default value, is used Acorn will generate random values for one or both."),(0,a.kt)("h3",{id:"token-secrets"},"Token secrets"),(0,a.kt)("p",null,"Token secrets are useful for generating a password or secure string used for passwords when the user is already known or not required."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-token": sec.Secret {\n type: "token"\n data: {\n "token": ""\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The token secret type must be defined. The ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," field in the data object is optional and if left empty Kusion will generate the token, which is 54 characters in length by default. If the ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," is defined that value will always be used."),(0,a.kt)("h3",{id:"opaque-secrets"},"Opaque secrets"),(0,a.kt)("p",null,"Opaque secrets have no defined structure and can have arbitrary key value pairs. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "opaque"\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"certificate-secrets"},"Certificate secrets"),(0,a.kt)("p",null,"Certificate secrets are useful for storing a certificate and its associated key. One common use for TLS Secrets is to configure encryption in transit for an Ingress, but you can also use it with other resources or directly in your workload."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "server-cert": sec.Secret {\n type: "certificate"\n data: {\n # Please do not put private keys in configuration files\n "tls.crt": "The cert file content"\n "tls.key": "The key file content"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"external-secrets"},"External secrets"),(0,a.kt)("p",null,"As a general principle, storing secrets in a plain text configuration file is highly discouraged, keeping secrets outside of Git is especially important for future-proofing, even encrypted secrets are not recommended to check into Git. The most common approach is to store secrets in a third-party vault (such as Hashicorp Vault, AWS Secrets Manager and Azure Key Vault, etc) and retrieve the secret in the runtime only. External secrets are used to retrieve sensitive data from external secret store to make it easy to be consumed in containers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-access-token": sec.Secret {\n type: "external"\n data: {\n # Please do not put private keys in configuration files\n "accessToken": "ref://api-auth-info/accessToken?version=1"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The value field in data object follow ",(0,a.kt)("inlineCode",{parentName:"p"},"ref://PATH[?version=]")," URI syntax. ",(0,a.kt)("inlineCode",{parentName:"p"},"PATH")," is the provider-specific path for the secret to be retried. Kusion provides out-of-the-box integration with ",(0,a.kt)("inlineCode",{parentName:"p"},"Hashicorp Vault"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"AWS Secrets Manager"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Azure Key Vault")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Alicloud Secrets Manager"),"."),(0,a.kt)("h2",{id:"immutable-secrets"},"Immutable secrets"),(0,a.kt)("p",null,"You can also declare a secret as immutable to prevent it from being changed accidentally."),(0,a.kt)("p",null,"To declare a secret as immutable:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n # ...\n immutable: True\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"You can change a secret from mutable to immutable but not the other way around. That is because the Kubelet will stop watching secrets that are immutable. As the name suggests, you can only delete and re-create immutable secrets but you cannot change them."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/048ed126.5e7c39a4.js b/assets/js/048ed126.5e7c39a4.js new file mode 100644 index 00000000000..836896c69f0 --- /dev/null +++ b/assets/js/048ed126.5e7c39a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4368],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(r),m=a,k=p["".concat(s,".").concat(m)]||p[m]||u[m]||l;return r?n.createElement(k,o(o({ref:t},d),{},{components:r})):n.createElement(k,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=p;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>i,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={},o="secret",i={unversionedId:"kusion/reference/modules/catalog-models/internal/secret/secret",id:"kusion/reference/modules/catalog-models/internal/secret/secret",title:"secret",description:"Schema Secret",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/secret",slug:"/kusion/reference/modules/catalog-models/internal/secret/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/network/port"},next:{title:"prometheus",permalink:"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus"}},s={},c=[{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secret"},"secret"),(0,a.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,a.kt)("p",null,"Secrets are used to provide data that is considered sensitive like passwords, API keys,",(0,a.kt)("br",null),"TLS certificates, tokens or other credentials."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "token" ',"|",' "opaque" ',"|",' "certificate" ',"|",' "external"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"params"),(0,a.kt)("br",null),"Collection of parameters used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"data"),(0,a.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"immutable"),(0,a.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/048ed126.a713192f.js b/assets/js/048ed126.a713192f.js deleted file mode 100644 index af035f56d70..00000000000 --- a/assets/js/048ed126.a713192f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4368],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(r),m=a,k=p["".concat(i,".").concat(m)]||p[m]||u[m]||l;return r?n.createElement(k,o(o({ref:t},d),{},{components:r})):n.createElement(k,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=p;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={},o="secret",s={unversionedId:"kusion/reference/modules/catalog-models/internal/secret/secret",id:"kusion/reference/modules/catalog-models/internal/secret/secret",title:"secret",description:"Schema Secret",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/secret",slug:"/kusion/reference/modules/catalog-models/internal/secret/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/network/port"},next:{title:"prometheus",permalink:"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus"}},i={},c=[{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secret"},"secret"),(0,a.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,a.kt)("p",null,"Secrets are used to provide data that is considered sensitive like passwords, API keys,",(0,a.kt)("br",null),"TLS certificates, tokens or other credentials."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "token" ',"|",' "opaque" ',"|",' "certificate" ',"|",' "external"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"params"),(0,a.kt)("br",null),"Collection of parameters used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"data"),(0,a.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"immutable"),(0,a.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/05939e2b.9fedbab2.js b/assets/js/05939e2b.9fedbab2.js new file mode 100644 index 00000000000..cf1cd7b2bac --- /dev/null +++ b/assets/js/05939e2b.9fedbab2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1258],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),f=p(n),m=i,d=f["".concat(l,".").concat(m)]||f[m]||u[m]||o;return n?r.createElement(d,a(a({ref:t},c),{},{components:n})):r.createElement(d,a({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion init",s={unversionedId:"kusion/reference/commands/kusion-init",id:"version-v0.10/kusion/reference/commands/kusion-init",title:"kusion init",description:"Initialize the scaffolding for a project",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-init.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-init",permalink:"/docs/kusion/reference/commands/kusion-init",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-init.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion destroy",permalink:"/docs/kusion/reference/commands/kusion-destroy"},next:{title:"kusion preview",permalink:"/docs/kusion/reference/commands/kusion-preview"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-init"},"kusion init"),(0,i.kt)("p",null,"Initialize the scaffolding for a project"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"This command initializes the scaffolding for a project, generating a project from an appointed template with correct structure."),(0,i.kt)("p",null," The scaffold templates can be retrieved from local or online. The built-in templates are used by default, self-defined templates are also supported by assigning the template repository path."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion init\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," # Initialize a project from internal templates\n kusion init\n \n # Initialize a project from default online templates\n kusion init --online=true\n \n # Initialize a project from a specific online template\n kusion init https://github.com// --online=true\n \n # Initialize a project from a specific local template\n kusion init /path/to/templates\n")),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," --custom-params string Custom params in JSON. If specified, it will be used as the template default value and skip prompts\n --force Force generating the scaffolding files, even if it would change the existing files\n -h, --help help for init\n --online Use templates from online repository to initialize project, or use locally cached templates\n --project-name string Initialize with specified project name. If not specified, a prompt will request it\n --template-name string Initialize with specified template. If not specified, a prompt will request it\n --yes Skip prompts and proceed with default values\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/05939e2b.aaf248e9.js b/assets/js/05939e2b.aaf248e9.js deleted file mode 100644 index bd1296fe547..00000000000 --- a/assets/js/05939e2b.aaf248e9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1258],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),f=p(n),m=i,d=f["".concat(l,".").concat(m)]||f[m]||u[m]||o;return n?r.createElement(d,a(a({ref:t},c),{},{components:n})):r.createElement(d,a({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion init",s={unversionedId:"kusion/reference/commands/kusion-init",id:"version-v0.10/kusion/reference/commands/kusion-init",title:"kusion init",description:"Initialize the scaffolding for a project",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-init.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-init",permalink:"/docs/kusion/reference/commands/kusion-init",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-init.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion destroy",permalink:"/docs/kusion/reference/commands/kusion-destroy"},next:{title:"kusion preview",permalink:"/docs/kusion/reference/commands/kusion-preview"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-init"},"kusion init"),(0,i.kt)("p",null,"Initialize the scaffolding for a project"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"This command initializes the scaffolding for a project, generating a project from an appointed template with correct structure."),(0,i.kt)("p",null," The scaffold templates can be retrieved from local or online. The built-in templates are used by default, self-defined templates are also supported by assigning the template repository path."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion init\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," # Initialize a project from internal templates\n kusion init\n \n # Initialize a project from default online templates\n kusion init --online=true\n \n # Initialize a project from a specific online template\n kusion init https://github.com// --online=true\n \n # Initialize a project from a specific local template\n kusion init /path/to/templates\n")),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," --custom-params string Custom params in JSON. If specified, it will be used as the template default value and skip prompts\n --force Force generating the scaffolding files, even if it would change the existing files\n -h, --help help for init\n --online Use templates from online repository to initialize project, or use locally cached templates\n --project-name string Initialize with specified project name. If not specified, a prompt will request it\n --template-name string Initialize with specified template. If not specified, a prompt will request it\n --yes Skip prompts and proceed with default values\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/05e2121e.e63e6dd9.js b/assets/js/05e2121e.6eadd0e0.js similarity index 55% rename from assets/js/05e2121e.e63e6dd9.js rename to assets/js/05e2121e.6eadd0e0.js index 54bef2da276..42c7eef71c1 100644 --- a/assets/js/05e2121e.e63e6dd9.js +++ b/assets/js/05e2121e.6eadd0e0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1750],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},l={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=u(t),m=o,d=f["".concat(c,".").concat(m)]||f[m]||l[m]||i;return t?r.createElement(d,s(s({ref:n},p),{},{components:t})):r.createElement(d,s({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=f;var a={};for(var c in n)hasOwnProperty.call(n,c)&&(a[c]=n[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var r=t(87462),o=(t(67294),t(3905));const i={},s="kusion version",a={unversionedId:"kusion/reference/commands/kusion-version",id:"kusion/reference/commands/kusion-version",title:"kusion version",description:"Print the Kusion version information for the current context",source:"@site/docs/kusion/6-reference/1-commands/kusion-version.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-version",permalink:"/docs/next/kusion/reference/commands/kusion-version",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-version.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion preview",permalink:"/docs/next/kusion/reference/commands/kusion-preview"},next:{title:"kusion workspace create",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-create"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:u};function l(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-version"},"kusion version"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion version [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Print the Kusion version\n kusion version\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for version\n -o, --output string Output format. Only json format is supported for now\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1750],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},l={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=u(t),m=o,d=f["".concat(c,".").concat(m)]||f[m]||l[m]||i;return t?r.createElement(d,s(s({ref:n},p),{},{components:t})):r.createElement(d,s({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=f;var a={};for(var c in n)hasOwnProperty.call(n,c)&&(a[c]=n[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var r=t(87462),o=(t(67294),t(3905));const i={},s="kusion version",a={unversionedId:"kusion/reference/commands/kusion-version",id:"kusion/reference/commands/kusion-version",title:"kusion version",description:"Print the Kusion version information for the current context",source:"@site/docs/kusion/6-reference/1-commands/kusion-version.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-version",permalink:"/docs/next/kusion/reference/commands/kusion-version",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-version.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion preview",permalink:"/docs/next/kusion/reference/commands/kusion-preview"},next:{title:"kusion workspace create",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-create"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:u};function l(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-version"},"kusion version"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion version [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Print the Kusion version\n kusion version\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for version\n -o, --output string Output format. Only json format is supported for now\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/06519e08.41afbcf4.js b/assets/js/06519e08.41afbcf4.js deleted file mode 100644 index 17caf9c2fff..00000000000 --- a/assets/js/06519e08.41afbcf4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6910],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),p=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(n),u=r,k=m["".concat(i,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(k,l(l({ref:t},d),{},{components:n})):a.createElement(k,l({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:r,l[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={},l="postgres",s={unversionedId:"kusion/reference/modules/catalog-models/database/postgres",id:"kusion/reference/modules/catalog-models/database/postgres",title:"postgres",description:"Schema PostgreSQL",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/postgres",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/mysql"},next:{title:"common",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/common"}},i={},p=[{value:"Schema PostgreSQL",id:"schema-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"postgres"},"postgres"),(0,r.kt)("h2",{id:"schema-postgresql"},"Schema PostgreSQL"),(0,r.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed postgresql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the postgresql database is deployed locally or provided by",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local postgresql database with image version of 14.0. \n\nimport catalog.models.schema.v1.accessories.postgres\n\npostgres: postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/06519e08.583b8469.js b/assets/js/06519e08.583b8469.js new file mode 100644 index 00000000000..c98ef79ed07 --- /dev/null +++ b/assets/js/06519e08.583b8469.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6910],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),p=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(n),u=r,k=m["".concat(i,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(k,l(l({ref:t},d),{},{components:n})):a.createElement(k,l({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:r,l[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={},l="postgres",s={unversionedId:"kusion/reference/modules/catalog-models/database/postgres",id:"kusion/reference/modules/catalog-models/database/postgres",title:"postgres",description:"Schema PostgreSQL",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/postgres",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/mysql"},next:{title:"common",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/common"}},i={},p=[{value:"Schema PostgreSQL",id:"schema-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"postgres"},"postgres"),(0,r.kt)("h2",{id:"schema-postgresql"},"Schema PostgreSQL"),(0,r.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed postgresql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the postgresql database is deployed locally or provided by",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local postgresql database with image version of 14.0. \n\nimport catalog.models.schema.v1.accessories.postgres\n\npostgres: postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/073cf144.05519135.js b/assets/js/073cf144.05519135.js deleted file mode 100644 index 647d9b80c25..00000000000 --- a/assets/js/073cf144.05519135.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7340],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,k=p["".concat(l,".").concat(m)]||p[m]||u[m]||o;return a?n.createElement(k,s(s({ref:t},d),{},{components:a})):n.createElement(k,s({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=p;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.d(t,{Z:()=>s});var n=a(67294),r=a(86010);const o="tabItem_Ymn6";function s(e){let{children:t,hidden:a,className:s}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,s),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>N});var n=a(87462),r=a(67294),o=a(86010),s=a(12466),i=a(76775),l=a(91980),c=a(67392),d=a(50012);function u(e){return function(e){var t;return(null==(t=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function p(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??u(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function m(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function k(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function h(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,o=p(e),[s,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[l,c]=k({queryString:a,groupId:n}),[u,h]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,d.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&o.set(e)}),[a,o])]}({groupId:n}),f=(()=>{const e=l??u;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),h(e)}),[c,h,o]),tabValues:o}}var f=a(72389);const g="tabList__CuJ",w="tabItem_LNqP";function b(e){let{className:t,block:a,selectedValue:i,selectValue:l,tabValues:c}=e;const d=[],{blockElementScrollPositionUntilNextRender:u}=(0,s.o5)(),p=e=>{const t=e.currentTarget,a=d.indexOf(t),n=c[a].value;n!==i&&(u(t),l(n))},m=e=>{var t;let a=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const t=d.indexOf(e.currentTarget)+1;a=d[t]??d[0];break}case"ArrowLeft":{const t=d.indexOf(e.currentTarget)-1;a=d[t]??d[d.length-1];break}}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:s}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>d.push(e),onKeyDown:m,onClick:p},s,{className:(0,o.Z)("tabs__item",w,null==s?void 0:s.className,{"tabs__item--active":i===t})}),a??t)})))}function y(e){let{lazy:t,children:a,selectedValue:n}=e;const o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(b,(0,n.Z)({},e,t)),r.createElement(y,(0,n.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,n.Z)({key:String(t)},e))}},38087:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=a(87462),r=(a(67294),a(3905)),o=a(74866),s=a(85162);const i={},l="Deliver the WordPress Application with Cloud RDS",c={unversionedId:"kusion/user-guides/cloud-resources/database",id:"version-v0.10/kusion/user-guides/cloud-resources/database",title:"Deliver the WordPress Application with Cloud RDS",description:"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/1-database.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/database",permalink:"/docs/kusion/user-guides/cloud-resources/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/1-database.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Operational Rules",permalink:"/docs/kusion/configuration-walkthrough/operational-rules"},next:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/kusion/user-guides/cloud-resources/expose-service"}},d={},u=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Verify WordPress Application",id:"verify-wordpress-application",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],p={toc:u};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-with-cloud-rds"},"Deliver the WordPress Application with Cloud RDS"),(0,r.kt)("p",null,"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"/docs/kusion/getting-started/install-kusion"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},"Deploy ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," or ",(0,r.kt)("a",{parentName:"li",href:"https://kind.sigs.k8s.io/"},"Kind")," or ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")),(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"https://www.terraform.io/"},"Terraform")),(0,r.kt)("li",{parentName:"ul"},"Prepare a cloud service account and create a user with ",(0,r.kt)("inlineCode",{parentName:"li"},"VPCFullAccess")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"RDSFullAccess")," permissions to use the Relational Database Service (RDS). This kind of user can be created and managed in the Identity and Access Management (IAM) console"),(0,r.kt)("li",{parentName:"ul"},"The environment that executes ",(0,r.kt)("inlineCode",{parentName:"li"},"kusion")," need to have connectivity to terraform registry to download the terraform providers")),(0,r.kt)("p",null,"Additionally, we also need to configure the obtained AccessKey and SecretKey as environment variables for specific cloud provider: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws iam account",src:a(24838).Z,width:"2874",height:"1398"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export ALICLOUD_ACCESS_KEY="LTAI5txxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="nxuowIxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud iam account",src:a(73725).Z,width:"1500",height:"629"})))),(0,r.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,r.kt)("p",null,"To deploy the WordPress application with cloud rds, we first need to initiate a ",(0,r.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (here we are using ",(0,r.kt)("inlineCode",{parentName:"p"},"dev"),"). Please copy the following example YAML file to your local ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL configurations for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n'))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL configurations for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))),(0,r.kt)("p",null,"You can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", and if you would like to try creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Alicloud")," RDS instance, you should also replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"[your-subnet-id]")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"modules.mysql.default.subnetID")," field with the Alicloud ",(0,r.kt)("inlineCode",{parentName:"p"},"vSwitchID")," to provision the database in. After that, you can execute the following command line to initiate the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,r.kt)("p",null,"If you already create the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, you can append the Terraform runtime configs and MySQL module configs to your workspace YAML file and use the following command line to update the workspace configuration. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,r.kt)("inlineCode",{parentName:"p"},"Kubernetes")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Terraform")," runtime configs and ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,r.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-cloud-rds A sample wordpress project with cloud rds\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-cloud-rds\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-cloud-rds'\n")),(0,r.kt)("p",null,"Select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),". After that, we will see hints below and use the default values to config this project and stack."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(52811).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-cloud-rds/dev && tree\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-cloud-rds/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/project/overview"},"Project")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/stack/overview"},"Stack"),". ")),(0,r.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,r.kt)("p",null,"Now let's take a look at the configuration files located in ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,r.kt)("p",null,"The configuration file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,r.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,r.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a cloud ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,r.kt)("inlineCode",{parentName:"p"},"8.0")," for the application.\nThe necessary Terraform resources for deploying and using the cloud rds (relational database service) will be generated, and users can get the ",(0,r.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"password")," of the database through the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about Catalog models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,r.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,r.kt)("p",null,"You can complete the delivery of the WordPress application in the folder of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds/dev")," using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with aws rds",src:a(5721).Z,width:"2874",height:"802"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with alicloud rds",src:a(91609).Z,width:"2876",height:"858"})))),(0,r.kt)("p",null,"After all the resources reconciled, we can port-forward our local port (e.g. 12345) to the WordPress frontend service port (80) in the cluster:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-cloud-rds svc/wordpress-cloud-rds-dev-wordpress-private 12345:80\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kubectl port-forward for wordpress",src:a(76831).Z,width:"2874",height:"150"})),(0,r.kt)("h2",{id:"verify-wordpress-application"},"Verify WordPress Application"),(0,r.kt)("p",null,"Next, we will verify the WordPress site service we just delivered, along with the creation of the RDS instance it depends on. We can start using the WordPress site by accessing the link of local-forwarded port ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"(http://localhost:12345)")," we just configured in the browser. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"wordpress site page",src:a(85773).Z,width:"1500",height:"803"})),(0,r.kt)("p",null,"In addition, we can also log in to the cloud service console page to view the RDS instance we just created."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws rds instance",src:a(42229).Z,width:"2298",height:"706"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud rds instance",src:a(99782).Z,width:"2870",height:"616"})))),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"You can delete the WordPress application and related RDS resources using the following command line. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with aws rds",src:a(74068).Z,width:"2874",height:"788"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with alicloud rds",src:a(72557).Z,width:"2874",height:"820"})))))}m.isMDXComponent=!0},91609:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-alicloud-14224502ce1c4d077fa1ed3777b1add9.png"},5721:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-aws-9c72f8fd79000427958c5376085a65b8.png"},24838:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"},99782:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-alicloud-e2062c7a477d445b3decf429105ab3d6.png"},42229:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-aws-64d6371851d55e05fb05353bbd9a19b1.png"},72557:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-alicloud-9c5da68051d92f6a8b3a11db9dd49273.png"},74068:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-aws-04a2cf44dbce1bcac488f8ce3dcdae81.png"},52811:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/init-wordpress-cloud-rds-ae612c3ca0f69fd417abb132fd8bfb78.gif"},73725:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/set-rds-access-9347ae09377aeb94d9f6d1e5d8688ab5.png"},76831:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-cloud-rds-port-forward-611c4f17d055d9ee941b9ff87a0727f5.png"},85773:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/073cf144.ab6fb57e.js b/assets/js/073cf144.ab6fb57e.js new file mode 100644 index 00000000000..b078b5f0c3d --- /dev/null +++ b/assets/js/073cf144.ab6fb57e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7340],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,k=p["".concat(l,".").concat(m)]||p[m]||u[m]||o;return a?n.createElement(k,s(s({ref:t},d),{},{components:a})):n.createElement(k,s({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=p;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.d(t,{Z:()=>s});var n=a(67294),r=a(86010);const o="tabItem_Ymn6";function s(e){let{children:t,hidden:a,className:s}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,s),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>N});var n=a(87462),r=a(67294),o=a(86010),s=a(12466),i=a(76775),l=a(91980),c=a(67392),d=a(50012);function u(e){return function(e){var t;return(null==(t=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function p(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??u(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function m(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function k(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function h(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,o=p(e),[s,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[l,c]=k({queryString:a,groupId:n}),[u,h]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,d.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&o.set(e)}),[a,o])]}({groupId:n}),f=(()=>{const e=l??u;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),h(e)}),[c,h,o]),tabValues:o}}var f=a(72389);const g="tabList__CuJ",w="tabItem_LNqP";function b(e){let{className:t,block:a,selectedValue:i,selectValue:l,tabValues:c}=e;const d=[],{blockElementScrollPositionUntilNextRender:u}=(0,s.o5)(),p=e=>{const t=e.currentTarget,a=d.indexOf(t),n=c[a].value;n!==i&&(u(t),l(n))},m=e=>{var t;let a=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const t=d.indexOf(e.currentTarget)+1;a=d[t]??d[0];break}case"ArrowLeft":{const t=d.indexOf(e.currentTarget)-1;a=d[t]??d[d.length-1];break}}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:s}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>d.push(e),onKeyDown:m,onClick:p},s,{className:(0,o.Z)("tabs__item",w,null==s?void 0:s.className,{"tabs__item--active":i===t})}),a??t)})))}function y(e){let{lazy:t,children:a,selectedValue:n}=e;const o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(b,(0,n.Z)({},e,t)),r.createElement(y,(0,n.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,n.Z)({key:String(t)},e))}},38087:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=a(87462),r=(a(67294),a(3905)),o=a(74866),s=a(85162);const i={},l="Deliver the WordPress Application with Cloud RDS",c={unversionedId:"kusion/user-guides/cloud-resources/database",id:"version-v0.10/kusion/user-guides/cloud-resources/database",title:"Deliver the WordPress Application with Cloud RDS",description:"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/1-database.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/database",permalink:"/docs/kusion/user-guides/cloud-resources/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/1-database.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Operational Rules",permalink:"/docs/kusion/configuration-walkthrough/operational-rules"},next:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/kusion/user-guides/cloud-resources/expose-service"}},d={},u=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Verify WordPress Application",id:"verify-wordpress-application",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],p={toc:u};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-with-cloud-rds"},"Deliver the WordPress Application with Cloud RDS"),(0,r.kt)("p",null,"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"/docs/kusion/getting-started/install-kusion"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},"Deploy ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," or ",(0,r.kt)("a",{parentName:"li",href:"https://kind.sigs.k8s.io/"},"Kind")," or ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")),(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"https://www.terraform.io/"},"Terraform")),(0,r.kt)("li",{parentName:"ul"},"Prepare a cloud service account and create a user with ",(0,r.kt)("inlineCode",{parentName:"li"},"VPCFullAccess")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"RDSFullAccess")," permissions to use the Relational Database Service (RDS). This kind of user can be created and managed in the Identity and Access Management (IAM) console"),(0,r.kt)("li",{parentName:"ul"},"The environment that executes ",(0,r.kt)("inlineCode",{parentName:"li"},"kusion")," need to have connectivity to terraform registry to download the terraform providers")),(0,r.kt)("p",null,"Additionally, we also need to configure the obtained AccessKey and SecretKey as environment variables for specific cloud provider: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws iam account",src:a(24838).Z,width:"2874",height:"1398"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export ALICLOUD_ACCESS_KEY="LTAI5txxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="nxuowIxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud iam account",src:a(73725).Z,width:"1500",height:"629"})))),(0,r.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,r.kt)("p",null,"To deploy the WordPress application with cloud rds, we first need to initiate a ",(0,r.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (here we are using ",(0,r.kt)("inlineCode",{parentName:"p"},"dev"),"). Please copy the following example YAML file to your local ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL configurations for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n'))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL configurations for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))),(0,r.kt)("p",null,"You can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", and if you would like to try creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Alicloud")," RDS instance, you should also replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"[your-subnet-id]")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"modules.mysql.default.subnetID")," field with the Alicloud ",(0,r.kt)("inlineCode",{parentName:"p"},"vSwitchID")," to provision the database in. After that, you can execute the following command line to initiate the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,r.kt)("p",null,"If you already create the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, you can append the Terraform runtime configs and MySQL module configs to your workspace YAML file and use the following command line to update the workspace configuration. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,r.kt)("inlineCode",{parentName:"p"},"Kubernetes")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Terraform")," runtime configs and ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,r.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-cloud-rds A sample wordpress project with cloud rds\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-cloud-rds\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-cloud-rds'\n")),(0,r.kt)("p",null,"Select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),". After that, we will see hints below and use the default values to config this project and stack."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(52811).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-cloud-rds/dev && tree\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-cloud-rds/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/project/overview"},"Project")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/stack/overview"},"Stack"),". ")),(0,r.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,r.kt)("p",null,"Now let's take a look at the configuration files located in ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,r.kt)("p",null,"The configuration file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,r.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,r.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a cloud ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,r.kt)("inlineCode",{parentName:"p"},"8.0")," for the application.\nThe necessary Terraform resources for deploying and using the cloud rds (relational database service) will be generated, and users can get the ",(0,r.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"password")," of the database through the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about Catalog models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,r.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,r.kt)("p",null,"You can complete the delivery of the WordPress application in the folder of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds/dev")," using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with aws rds",src:a(5721).Z,width:"2874",height:"802"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with alicloud rds",src:a(91609).Z,width:"2876",height:"858"})))),(0,r.kt)("p",null,"After all the resources reconciled, we can port-forward our local port (e.g. 12345) to the WordPress frontend service port (80) in the cluster:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-cloud-rds svc/wordpress-cloud-rds-dev-wordpress-private 12345:80\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kubectl port-forward for wordpress",src:a(76831).Z,width:"2874",height:"150"})),(0,r.kt)("h2",{id:"verify-wordpress-application"},"Verify WordPress Application"),(0,r.kt)("p",null,"Next, we will verify the WordPress site service we just delivered, along with the creation of the RDS instance it depends on. We can start using the WordPress site by accessing the link of local-forwarded port ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"(http://localhost:12345)")," we just configured in the browser. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"wordpress site page",src:a(85773).Z,width:"1500",height:"803"})),(0,r.kt)("p",null,"In addition, we can also log in to the cloud service console page to view the RDS instance we just created."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws rds instance",src:a(42229).Z,width:"2298",height:"706"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud rds instance",src:a(99782).Z,width:"2870",height:"616"})))),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"You can delete the WordPress application and related RDS resources using the following command line. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with aws rds",src:a(74068).Z,width:"2874",height:"788"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with alicloud rds",src:a(72557).Z,width:"2874",height:"820"})))))}m.isMDXComponent=!0},91609:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-alicloud-14224502ce1c4d077fa1ed3777b1add9.png"},5721:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-aws-9c72f8fd79000427958c5376085a65b8.png"},24838:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"},99782:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-alicloud-e2062c7a477d445b3decf429105ab3d6.png"},42229:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-aws-64d6371851d55e05fb05353bbd9a19b1.png"},72557:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-alicloud-9c5da68051d92f6a8b3a11db9dd49273.png"},74068:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-aws-04a2cf44dbce1bcac488f8ce3dcdae81.png"},52811:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/init-wordpress-cloud-rds-ae612c3ca0f69fd417abb132fd8bfb78.gif"},73725:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/set-rds-access-9347ae09377aeb94d9f6d1e5d8688ab5.png"},76831:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-cloud-rds-port-forward-611c4f17d055d9ee941b9ff87a0727f5.png"},85773:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/084f87c9.6238ad40.js b/assets/js/084f87c9.da8f5fca.js similarity index 65% rename from assets/js/084f87c9.6238ad40.js rename to assets/js/084f87c9.da8f5fca.js index ad3857c362f..ead41abee6d 100644 --- a/assets/js/084f87c9.6238ad40.js +++ b/assets/js/084f87c9.da8f5fca.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6318],{3905:(e,t,o)=>{o.d(t,{Zo:()=>l,kt:()=>f});var r=o(67294);function n(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var c=r.createContext({}),p=function(e){var t=r.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(o),f=n,v=d["".concat(c,".").concat(f)]||d[f]||u[f]||i;return o?r.createElement(v,a(a({ref:t},l),{},{components:o})):r.createElement(v,a({ref:t},l))}));function f(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=o.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:n,a[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=o(87462),n=(o(67294),o(3905));const i={sidebar_label:"Overview",id:"overview"},a="Overview",s={unversionedId:"kusion/concepts/project/overview",id:"version-v0.10/kusion/concepts/project/overview",title:"Overview",description:"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/1-project/1-overview.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/overview",permalink:"/docs/kusion/concepts/project/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/1-project/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/kusion/getting-started/deliver-wordpress"},next:{title:"Project Configuration",permalink:"/docs/kusion/concepts/project/configuration"}},c={},p=[],l={toc:p};function u(e){let{components:t,...o}=e;return(0,n.kt)("wrapper",(0,r.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"overview"},"Overview"),(0,n.kt)("p",null,"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications."),(0,n.kt)("p",null,"The purpose of the project is to bundle application configurations and refer to a Git repository. Specifically, it organizes logical configurations for internal components to orchestrate the application and assembles these configurations to suit different roles, such as developers and SREs, thereby covering the entire life cycle of application development."),(0,n.kt)("p",null,"From the perspective of the application development life cycle, the configuration delineated by the project is decoupled from the application code. It takes an immutable image as input, allowing users to perform operations and maintain the application within an independent configuration codebase."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6318],{3905:(e,t,o)=>{o.d(t,{Zo:()=>l,kt:()=>f});var r=o(67294);function n(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var c=r.createContext({}),p=function(e){var t=r.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(o),f=n,v=d["".concat(c,".").concat(f)]||d[f]||u[f]||i;return o?r.createElement(v,a(a({ref:t},l),{},{components:o})):r.createElement(v,a({ref:t},l))}));function f(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=o.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:n,a[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=o(87462),n=(o(67294),o(3905));const i={sidebar_label:"Overview",id:"overview"},a="Overview",s={unversionedId:"kusion/concepts/project/overview",id:"version-v0.10/kusion/concepts/project/overview",title:"Overview",description:"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/1-project/1-overview.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/overview",permalink:"/docs/kusion/concepts/project/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/1-project/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/kusion/getting-started/deliver-wordpress"},next:{title:"Project Configuration",permalink:"/docs/kusion/concepts/project/configuration"}},c={},p=[],l={toc:p};function u(e){let{components:t,...o}=e;return(0,n.kt)("wrapper",(0,r.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"overview"},"Overview"),(0,n.kt)("p",null,"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications."),(0,n.kt)("p",null,"The purpose of the project is to bundle application configurations and refer to a Git repository. Specifically, it organizes logical configurations for internal components to orchestrate the application and assembles these configurations to suit different roles, such as developers and SREs, thereby covering the entire life cycle of application development."),(0,n.kt)("p",null,"From the perspective of the application development life cycle, the configuration delineated by the project is decoupled from the application code. It takes an immutable image as input, allowing users to perform operations and maintain the application within an independent configuration codebase."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/091a426a.2be81aad.js b/assets/js/091a426a.2be81aad.js deleted file mode 100644 index 71324919860..00000000000 --- a/assets/js/091a426a.2be81aad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3334],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,k=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return a?n.createElement(k,s(s({ref:t},u),{},{components:a})):n.createElement(k,s({ref:t},u))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=p;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.d(t,{Z:()=>s});var n=a(67294),r=a(86010);const o="tabItem_Ymn6";function s(e){let{children:t,hidden:a,className:s}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,s),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>N});var n=a(87462),r=a(67294),o=a(86010),s=a(12466),i=a(76775),l=a(91980),c=a(67392),u=a(50012);function d(e){return function(e){var t;return(null==(t=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function p(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??d(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function m(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function k(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function h(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,o=p(e),[s,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[l,c]=k({queryString:a,groupId:n}),[d,h]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,u.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&o.set(e)}),[a,o])]}({groupId:n}),f=(()=>{const e=l??d;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),h(e)}),[c,h,o]),tabValues:o}}var f=a(72389);const g="tabList__CuJ",w="tabItem_LNqP";function b(e){let{className:t,block:a,selectedValue:i,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:d}=(0,s.o5)(),p=e=>{const t=e.currentTarget,a=u.indexOf(t),n=c[a].value;n!==i&&(d(t),l(n))},m=e=>{var t;let a=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const t=u.indexOf(e.currentTarget)+1;a=u[t]??u[0];break}case"ArrowLeft":{const t=u.indexOf(e.currentTarget)-1;a=u[t]??u[u.length-1];break}}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:s}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,o.Z)("tabs__item",w,null==s?void 0:s.className,{"tabs__item--active":i===t})}),a??t)})))}function y(e){let{lazy:t,children:a,selectedValue:n}=e;const o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(b,(0,n.Z)({},e,t)),r.createElement(y,(0,n.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,n.Z)({key:String(t)},e))}},45413:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var n=a(87462),r=(a(67294),a(3905)),o=a(74866),s=a(85162);const i={},l="Deliver the WordPress Application with Cloud RDS",c={unversionedId:"kusion/user-guides/cloud-resources/database",id:"kusion/user-guides/cloud-resources/database",title:"Deliver the WordPress Application with Cloud RDS",description:"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.",source:"@site/docs/kusion/5-user-guides/1-cloud-resources/1-database.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/database",permalink:"/docs/next/kusion/user-guides/cloud-resources/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/1-cloud-resources/1-database.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Operational Rules",permalink:"/docs/next/kusion/configuration-walkthrough/operational-rules"},next:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/next/kusion/user-guides/cloud-resources/expose-service"}},u={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Verify WordPress Application",id:"verify-wordpress-application",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],p={toc:d};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-with-cloud-rds"},"Deliver the WordPress Application with Cloud RDS"),(0,r.kt)("p",null,"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"/docs/next/kusion/getting-started/install-kusion"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},"Deploy ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," or ",(0,r.kt)("a",{parentName:"li",href:"https://kind.sigs.k8s.io/"},"Kind")," or ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")),(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"https://www.terraform.io/"},"Terraform")),(0,r.kt)("li",{parentName:"ul"},"Prepare a cloud service account and create a user with ",(0,r.kt)("inlineCode",{parentName:"li"},"VPCFullAccess")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"RDSFullAccess")," permissions to use the Relational Database Service (RDS). This kind of user can be created and managed in the Identity and Access Management (IAM) console"),(0,r.kt)("li",{parentName:"ul"},"The environment that executes ",(0,r.kt)("inlineCode",{parentName:"li"},"kusion")," need to have connectivity to terraform registry to download the terraform providers")),(0,r.kt)("p",null,"Additionally, we also need to configure the obtained AccessKey and SecretKey as environment variables for specific cloud provider: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws iam account",src:a(24838).Z,width:"2874",height:"1398"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export ALICLOUD_ACCESS_KEY="LTAI5txxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="nxuowIxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud iam account",src:a(73725).Z,width:"1500",height:"629"})))),(0,r.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,r.kt)("p",null,"To deploy the WordPress application with cloud rds, we first need to initiate a ",(0,r.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (here we are using ",(0,r.kt)("inlineCode",{parentName:"p"},"dev"),"). Please copy the following example YAML file to your local ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL configurations for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n'))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL configurations for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))),(0,r.kt)("p",null,"You can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", and if you would like to try creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Alicloud")," RDS instance, you should also replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"[your-subnet-id]")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"modules.mysql.default.subnetID")," field with the Alicloud ",(0,r.kt)("inlineCode",{parentName:"p"},"vSwitchID")," to provision the database in. After that, you can execute the following command line to initiate the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,r.kt)("p",null,"If you already create the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, you can append the Terraform runtime configs and MySQL module configs to your workspace YAML file and use the following command line to update the workspace configuration. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,r.kt)("inlineCode",{parentName:"p"},"Kubernetes")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Terraform")," runtime configs and ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,r.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-cloud-rds A sample wordpress project with cloud rds\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-cloud-rds\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-cloud-rds'\n")),(0,r.kt)("p",null,"Select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),". After that, we will see hints below and use the default values to config this project and stack."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(52811).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-cloud-rds/dev && tree\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-cloud-rds/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/project/overview"},"Project")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/stack/overview"},"Stack"),". ")),(0,r.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,r.kt)("p",null,"Now let's take a look at the configuration files located in ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,r.kt)("p",null,"The configuration file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,r.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,r.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a cloud ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,r.kt)("inlineCode",{parentName:"p"},"8.0")," for the application.\nThe necessary Terraform resources for deploying and using the cloud rds (relational database service) will be generated, and users can get the ",(0,r.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"password")," of the database through the ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about Catalog models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,r.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,r.kt)("p",null,"You can complete the delivery of the WordPress application in the folder of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds/dev")," using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with aws rds",src:a(5721).Z,width:"2874",height:"802"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with alicloud rds",src:a(91609).Z,width:"2876",height:"858"})))),(0,r.kt)("p",null,"After all the resources reconciled, we can port-forward our local port (e.g. 12345) to the WordPress frontend service port (80) in the cluster:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-cloud-rds svc/wordpress-cloud-rds-dev-wordpress-private 12345:80\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kubectl port-forward for wordpress",src:a(76831).Z,width:"2874",height:"150"})),(0,r.kt)("h2",{id:"verify-wordpress-application"},"Verify WordPress Application"),(0,r.kt)("p",null,"Next, we will verify the WordPress site service we just delivered, along with the creation of the RDS instance it depends on. We can start using the WordPress site by accessing the link of local-forwarded port ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"(http://localhost:12345)")," we just configured in the browser. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"wordpress site page",src:a(85773).Z,width:"1500",height:"803"})),(0,r.kt)("p",null,"In addition, we can also log in to the cloud service console page to view the RDS instance we just created."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws rds instance",src:a(42229).Z,width:"2298",height:"706"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud rds instance",src:a(99782).Z,width:"2870",height:"616"})))),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"You can delete the WordPress application and related RDS resources using the following command line. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with aws rds",src:a(74068).Z,width:"2874",height:"788"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with alicloud rds",src:a(72557).Z,width:"2874",height:"820"})))))}m.isMDXComponent=!0},91609:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-alicloud-14224502ce1c4d077fa1ed3777b1add9.png"},5721:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-aws-9c72f8fd79000427958c5376085a65b8.png"},24838:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"},99782:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-alicloud-e2062c7a477d445b3decf429105ab3d6.png"},42229:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-aws-64d6371851d55e05fb05353bbd9a19b1.png"},72557:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-alicloud-9c5da68051d92f6a8b3a11db9dd49273.png"},74068:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-aws-04a2cf44dbce1bcac488f8ce3dcdae81.png"},52811:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/init-wordpress-cloud-rds-ae612c3ca0f69fd417abb132fd8bfb78.gif"},73725:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/set-rds-access-9347ae09377aeb94d9f6d1e5d8688ab5.png"},76831:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-cloud-rds-port-forward-611c4f17d055d9ee941b9ff87a0727f5.png"},85773:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/091a426a.411e9eeb.js b/assets/js/091a426a.411e9eeb.js new file mode 100644 index 00000000000..1066b45b949 --- /dev/null +++ b/assets/js/091a426a.411e9eeb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3334],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(a),m=r,k=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return a?n.createElement(k,s(s({ref:t},u),{},{components:a})):n.createElement(k,s({ref:t},u))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=p;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.d(t,{Z:()=>s});var n=a(67294),r=a(86010);const o="tabItem_Ymn6";function s(e){let{children:t,hidden:a,className:s}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,s),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>N});var n=a(87462),r=a(67294),o=a(86010),s=a(12466),i=a(76775),l=a(91980),c=a(67392),u=a(50012);function d(e){return function(e){var t;return(null==(t=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function p(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??d(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function m(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function k(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function h(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,o=p(e),[s,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[l,c]=k({queryString:a,groupId:n}),[d,h]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,u.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&o.set(e)}),[a,o])]}({groupId:n}),f=(()=>{const e=l??d;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),h(e)}),[c,h,o]),tabValues:o}}var f=a(72389);const g="tabList__CuJ",w="tabItem_LNqP";function b(e){let{className:t,block:a,selectedValue:i,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:d}=(0,s.o5)(),p=e=>{const t=e.currentTarget,a=u.indexOf(t),n=c[a].value;n!==i&&(d(t),l(n))},m=e=>{var t;let a=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const t=u.indexOf(e.currentTarget)+1;a=u[t]??u[0];break}case"ArrowLeft":{const t=u.indexOf(e.currentTarget)-1;a=u[t]??u[u.length-1];break}}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:s}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,o.Z)("tabs__item",w,null==s?void 0:s.className,{"tabs__item--active":i===t})}),a??t)})))}function y(e){let{lazy:t,children:a,selectedValue:n}=e;const o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(b,(0,n.Z)({},e,t)),r.createElement(y,(0,n.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,n.Z)({key:String(t)},e))}},45413:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var n=a(87462),r=(a(67294),a(3905)),o=a(74866),s=a(85162);const i={},l="Deliver the WordPress Application with Cloud RDS",c={unversionedId:"kusion/user-guides/cloud-resources/database",id:"kusion/user-guides/cloud-resources/database",title:"Deliver the WordPress Application with Cloud RDS",description:"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.",source:"@site/docs/kusion/5-user-guides/1-cloud-resources/1-database.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/database",permalink:"/docs/next/kusion/user-guides/cloud-resources/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/1-cloud-resources/1-database.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Operational Rules",permalink:"/docs/next/kusion/configuration-walkthrough/operational-rules"},next:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/next/kusion/user-guides/cloud-resources/expose-service"}},u={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Verify WordPress Application",id:"verify-wordpress-application",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],p={toc:d};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-with-cloud-rds"},"Deliver the WordPress Application with Cloud RDS"),(0,r.kt)("p",null,"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"/docs/next/kusion/getting-started/install-kusion"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},"Deploy ",(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," or ",(0,r.kt)("a",{parentName:"li",href:"https://kind.sigs.k8s.io/"},"Kind")," or ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")),(0,r.kt)("li",{parentName:"ul"},"Install ",(0,r.kt)("a",{parentName:"li",href:"https://www.terraform.io/"},"Terraform")),(0,r.kt)("li",{parentName:"ul"},"Prepare a cloud service account and create a user with ",(0,r.kt)("inlineCode",{parentName:"li"},"VPCFullAccess")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"RDSFullAccess")," permissions to use the Relational Database Service (RDS). This kind of user can be created and managed in the Identity and Access Management (IAM) console"),(0,r.kt)("li",{parentName:"ul"},"The environment that executes ",(0,r.kt)("inlineCode",{parentName:"li"},"kusion")," need to have connectivity to terraform registry to download the terraform providers")),(0,r.kt)("p",null,"Additionally, we also need to configure the obtained AccessKey and SecretKey as environment variables for specific cloud provider: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws iam account",src:a(24838).Z,width:"2874",height:"1398"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export ALICLOUD_ACCESS_KEY="LTAI5txxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="nxuowIxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud iam account",src:a(73725).Z,width:"1500",height:"629"})))),(0,r.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,r.kt)("p",null,"To deploy the WordPress application with cloud rds, we first need to initiate a ",(0,r.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (here we are using ",(0,r.kt)("inlineCode",{parentName:"p"},"dev"),"). Please copy the following example YAML file to your local ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL configurations for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n'))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml # Replace with your own kubeconfig file path\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL configurations for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))),(0,r.kt)("p",null,"You can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", and if you would like to try creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Alicloud")," RDS instance, you should also replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"[your-subnet-id]")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"modules.mysql.default.subnetID")," field with the Alicloud ",(0,r.kt)("inlineCode",{parentName:"p"},"vSwitchID")," to provision the database in. After that, you can execute the following command line to initiate the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,r.kt)("p",null,"If you already create the workspace configuration for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, you can append the Terraform runtime configs and MySQL module configs to your workspace YAML file and use the following command line to update the workspace configuration. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,r.kt)("inlineCode",{parentName:"p"},"Kubernetes")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"Terraform")," runtime configs and ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,r.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-cloud-rds A sample wordpress project with cloud rds\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-cloud-rds\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-cloud-rds'\n")),(0,r.kt)("p",null,"Select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),". After that, we will see hints below and use the default values to config this project and stack."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(52811).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-cloud-rds/dev && tree\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-cloud-rds/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/project/overview"},"Project")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/stack/overview"},"Stack"),". ")),(0,r.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,r.kt)("p",null,"Now let's take a look at the configuration files located in ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,r.kt)("p",null,"The configuration file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,r.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,r.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,r.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a cloud ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,r.kt)("inlineCode",{parentName:"p"},"8.0")," for the application.\nThe necessary Terraform resources for deploying and using the cloud rds (relational database service) will be generated, and users can get the ",(0,r.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"password")," of the database through the ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about Catalog models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,r.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,r.kt)("p",null,"You can complete the delivery of the WordPress application in the folder of ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds/dev")," using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with aws rds",src:a(5721).Z,width:"2874",height:"802"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with alicloud rds",src:a(91609).Z,width:"2876",height:"858"})))),(0,r.kt)("p",null,"After all the resources reconciled, we can port-forward our local port (e.g. 12345) to the WordPress frontend service port (80) in the cluster:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-cloud-rds svc/wordpress-cloud-rds-dev-wordpress-private 12345:80\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kubectl port-forward for wordpress",src:a(76831).Z,width:"2874",height:"150"})),(0,r.kt)("h2",{id:"verify-wordpress-application"},"Verify WordPress Application"),(0,r.kt)("p",null,"Next, we will verify the WordPress site service we just delivered, along with the creation of the RDS instance it depends on. We can start using the WordPress site by accessing the link of local-forwarded port ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"(http://localhost:12345)")," we just configured in the browser. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"wordpress site page",src:a(85773).Z,width:"1500",height:"803"})),(0,r.kt)("p",null,"In addition, we can also log in to the cloud service console page to view the RDS instance we just created."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws rds instance",src:a(42229).Z,width:"2298",height:"706"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud rds instance",src:a(99782).Z,width:"2870",height:"616"})))),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"You can delete the WordPress application and related RDS resources using the following command line. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with aws rds",src:a(74068).Z,width:"2874",height:"788"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with alicloud rds",src:a(72557).Z,width:"2874",height:"820"})))))}m.isMDXComponent=!0},91609:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-alicloud-14224502ce1c4d077fa1ed3777b1add9.png"},5721:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-cloud-rds-aws-9c72f8fd79000427958c5376085a65b8.png"},24838:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"},99782:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-alicloud-e2062c7a477d445b3decf429105ab3d6.png"},42229:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cloud-rds-instance-aws-64d6371851d55e05fb05353bbd9a19b1.png"},72557:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-alicloud-9c5da68051d92f6a8b3a11db9dd49273.png"},74068:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/destroy-wordpress-cloud-rds-aws-04a2cf44dbce1bcac488f8ce3dcdae81.png"},52811:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/init-wordpress-cloud-rds-ae612c3ca0f69fd417abb132fd8bfb78.gif"},73725:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/set-rds-access-9347ae09377aeb94d9f6d1e5d8688ab5.png"},76831:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-cloud-rds-port-forward-611c4f17d055d9ee941b9ff87a0727f5.png"},85773:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/09b7d7e1.9b3784fe.js b/assets/js/09b7d7e1.9b3784fe.js new file mode 100644 index 00000000000..6c6d52e2a6e --- /dev/null +++ b/assets/js/09b7d7e1.9b3784fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3617],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),d=o,k=u["".concat(c,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(k,i(i({ref:t},p),{},{components:n})):r.createElement(k,i({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var r=n(87462),o=(n(67294),n(3905));const a={id:"project-stack-config-items",sidebar_label:"Project & Stack Config Items"},i="Project & Stack Config Items",l={unversionedId:"kusion/reference/model/project-stack-config-items",id:"version-v0.9/kusion/reference/model/project-stack-config-items",title:"Project & Stack Config Items",description:"In project.yaml and stack.yaml, users can add config items for their applications such as the project or stack names, generator types, Prometheus monitoring, etc. Below, we will provide the explanations for both config file.",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/project-stack-config-items.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/project-stack-config-items",permalink:"/docs/v0.9/kusion/reference/model/project-stack-config-items",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/project-stack-config-items.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{id:"project-stack-config-items",sidebar_label:"Project & Stack Config Items"},sidebar:"kusion",previous:{title:"Naming Conventions",permalink:"/docs/v0.9/kusion/reference/model/naming-conventions"},next:{title:"Roadmap",permalink:"/docs/v0.9/kusion/reference/roadmap"}},c={},s=[{value:"project.yaml",id:"projectyaml",level:2},{value:"Backend Configuration",id:"backend-configuration",level:3},{value:"stack.yaml",id:"stackyaml",level:2}],p={toc:s};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"project--stack-config-items"},"Project & Stack Config Items"),(0,o.kt)("p",null,"In ",(0,o.kt)("strong",{parentName:"p"},"project.yaml")," and ",(0,o.kt)("strong",{parentName:"p"},"stack.yaml"),", users can add config items for their applications such as the project or stack names, generator types, Prometheus monitoring, etc. Below, we will provide the explanations for both config file. "),(0,o.kt)("h2",{id:"projectyaml"},"project.yaml"),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The project basic info\nname: helloworld\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," are explained below. "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"name"),": The name of the project. "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"prometheus"),": ",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"operatorMode"),": Decides whether Kusion runs Prometheus in ",(0,o.kt)("strong",{parentName:"li"},"Operator")," mode. Kusion will generate a ",(0,o.kt)("strong",{parentName:"li"},"Custom Resource")," if it is ",(0,o.kt)("strong",{parentName:"li"},"true"),", while generate some annotations if it is ",(0,o.kt)("strong",{parentName:"li"},"false"),". "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"monitorType"),": The type of the monitored resource, which can be one of ",(0,o.kt)("inlineCode",{parentName:"li"},"Service")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"Pod"),". ")))),(0,o.kt)("h3",{id:"backend-configuration"},"Backend Configuration"),(0,o.kt)("p",null,"Kusion supports configuring the storage of state through the ",(0,o.kt)("inlineCode",{parentName:"p"},"backend")," field in the ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," file. Detailed instructions can be found in ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration"},"Backend Configuration")),(0,o.kt)("h2",{id:"stackyaml"},"stack.yaml"),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The stack basic info\nname: dev\nkubeConfig: /Users/username/.kube/config\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml")," are explained below. "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"name"),": The name of the stack, typically the environment of the project, e.g. ",(0,o.kt)("inlineCode",{parentName:"li"},"dev"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"pre")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"prod"),". "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"kubeConfig"),": The kubeconfig file path for this stack. ")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeConfig")," field in the ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml")," file only supports ",(0,o.kt)("strong",{parentName:"p"},"absolute path")," and ",(0,o.kt)("strong",{parentName:"p"},"relative path")," with a dot (.) or double dots (..). Expansions for tilde (~) and $HOME are not supported yet. ")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/09b7d7e1.b8b4d220.js b/assets/js/09b7d7e1.b8b4d220.js deleted file mode 100644 index 2ae846ecc94..00000000000 --- a/assets/js/09b7d7e1.b8b4d220.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3617],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),d=o,k=u["".concat(c,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(k,i(i({ref:t},p),{},{components:n})):r.createElement(k,i({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var r=n(87462),o=(n(67294),n(3905));const a={id:"project-stack-config-items",sidebar_label:"Project & Stack Config Items"},i="Project & Stack Config Items",l={unversionedId:"kusion/reference/model/project-stack-config-items",id:"version-v0.9/kusion/reference/model/project-stack-config-items",title:"Project & Stack Config Items",description:"In project.yaml and stack.yaml, users can add config items for their applications such as the project or stack names, generator types, Prometheus monitoring, etc. Below, we will provide the explanations for both config file.",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/project-stack-config-items.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/project-stack-config-items",permalink:"/docs/v0.9/kusion/reference/model/project-stack-config-items",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/project-stack-config-items.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{id:"project-stack-config-items",sidebar_label:"Project & Stack Config Items"},sidebar:"kusion",previous:{title:"Naming Conventions",permalink:"/docs/v0.9/kusion/reference/model/naming-conventions"},next:{title:"Roadmap",permalink:"/docs/v0.9/kusion/reference/roadmap"}},c={},s=[{value:"project.yaml",id:"projectyaml",level:2},{value:"Backend Configuration",id:"backend-configuration",level:3},{value:"stack.yaml",id:"stackyaml",level:2}],p={toc:s};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"project--stack-config-items"},"Project & Stack Config Items"),(0,o.kt)("p",null,"In ",(0,o.kt)("strong",{parentName:"p"},"project.yaml")," and ",(0,o.kt)("strong",{parentName:"p"},"stack.yaml"),", users can add config items for their applications such as the project or stack names, generator types, Prometheus monitoring, etc. Below, we will provide the explanations for both config file. "),(0,o.kt)("h2",{id:"projectyaml"},"project.yaml"),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The project basic info\nname: helloworld\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," are explained below. "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"name"),": The name of the project. "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"prometheus"),": ",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"operatorMode"),": Decides whether Kusion runs Prometheus in ",(0,o.kt)("strong",{parentName:"li"},"Operator")," mode. Kusion will generate a ",(0,o.kt)("strong",{parentName:"li"},"Custom Resource")," if it is ",(0,o.kt)("strong",{parentName:"li"},"true"),", while generate some annotations if it is ",(0,o.kt)("strong",{parentName:"li"},"false"),". "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"monitorType"),": The type of the monitored resource, which can be one of ",(0,o.kt)("inlineCode",{parentName:"li"},"Service")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"Pod"),". ")))),(0,o.kt)("h3",{id:"backend-configuration"},"Backend Configuration"),(0,o.kt)("p",null,"Kusion supports configuring the storage of state through the ",(0,o.kt)("inlineCode",{parentName:"p"},"backend")," field in the ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," file. Detailed instructions can be found in ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration"},"Backend Configuration")),(0,o.kt)("h2",{id:"stackyaml"},"stack.yaml"),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The stack basic info\nname: dev\nkubeConfig: /Users/username/.kube/config\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml")," are explained below. "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"name"),": The name of the stack, typically the environment of the project, e.g. ",(0,o.kt)("inlineCode",{parentName:"li"},"dev"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"pre")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"prod"),". "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"kubeConfig"),": The kubeconfig file path for this stack. ")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeConfig")," field in the ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml")," file only supports ",(0,o.kt)("strong",{parentName:"p"},"absolute path")," and ",(0,o.kt)("strong",{parentName:"p"},"relative path")," with a dot (.) or double dots (..). Expansions for tilde (~) and $HOME are not supported yet. ")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0a185701.3fe6bef4.js b/assets/js/0a185701.3fe6bef4.js new file mode 100644 index 00000000000..e334538a567 --- /dev/null +++ b/assets/js/0a185701.3fe6bef4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[535],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=r(e,["components","mdxType","originalType","parentName"]),k=c(n),u=i,m=k["".concat(l,".").concat(u)]||k[u]||d[u]||o;return n?a.createElement(m,s(s({ref:t},p),{},{components:n})):a.createElement(m,s({ref:t},p))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,s=new Array(o);s[0]=k;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r.mdxType="string"==typeof e?e:i,s[1]=r;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>c});var a=n(87462),i=(n(67294),n(3905));const o={id:"backend",sidebar_label:"Backend"},s="Backend",r={unversionedId:"kusion/concepts/backend",id:"kusion/concepts/backend",title:"Backend",description:"Backend is Kusion's storage, which defines the place to store Workspace, Spec and State. By default, Kusion uses the local type of backend to store the state on the local disk. While in the scenario of team collaboration, the Workspace, Spec and State can be stored on a remote backend, such as mysql, oss and s3, to allow multiple users' access.",source:"@site/docs/kusion/3-concepts/7-backend.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/backend",permalink:"/docs/next/kusion/concepts/backend",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/7-backend.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"backend",sidebar_label:"Backend"},sidebar:"kusion",previous:{title:"Intent",permalink:"/docs/next/kusion/concepts/intent"},next:{title:"Configuration",permalink:"/docs/next/kusion/concepts/configuration"}},l={},c=[{value:"Available Backend Types",id:"available-backend-types",level:2},{value:"local",id:"local",level:3},{value:"mysql",id:"mysql",level:3},{value:"oss",id:"oss",level:3},{value:"s3",id:"s3",level:3},{value:"Setting a Backend",id:"setting-a-backend",level:2},{value:"Setting a Whole Backend",id:"setting-a-whole-backend",level:3},{value:"Setting a Backend Type",id:"setting-a-backend-type",level:3},{value:"Setting a Whole Set of Backend Config Items",id:"setting-a-whole-set-of-backend-config-items",level:3},{value:"Setting a Backend Config Item",id:"setting-a-backend-config-item",level:3},{value:"Unsetting a Backend",id:"unsetting-a-backend",level:2},{value:"Setting the Current Backend",id:"setting-the-current-backend",level:2},{value:"Getting Backend Configuration",id:"getting-backend-configuration",level:2},{value:"Using Backend",id:"using-backend",level:2}],p={toc:c};function d(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"backend"},"Backend"),(0,i.kt)("p",null,"Backend is Kusion's storage, which defines the place to store Workspace, Spec and State. By default, Kusion uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"local")," type of backend to store the state on the local disk. While in the scenario of team collaboration, the Workspace, Spec and State can be stored on a remote backend, such as ",(0,i.kt)("inlineCode",{parentName:"p"},"mysql"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"oss")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"s3"),", to allow multiple users' access. "),(0,i.kt)("p",null,"The command ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config")," is used to configure the backend configuration. Configuring a whole backend or an individual config item are both supported. For the sensitive data, the environment variables are supported, and with higher priority."),(0,i.kt)("p",null,"Furthermore, Kusion provides the operation of setting current backend. Thus, the trouble of specifying backend can be saved when executing operation commands and managing ",(0,i.kt)("inlineCode",{parentName:"p"},"workspace"),". "),(0,i.kt)("h2",{id:"available-backend-types"},"Available Backend Types"),(0,i.kt)("p",null,"There are four available backend types: ",(0,i.kt)("inlineCode",{parentName:"p"},"local"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"mysql"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"oss"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"s3"),"."),(0,i.kt)("h3",{id:"local"},"local"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"local")," type backend uses local file system as storage, which is suitable for local operations, but not ideal for multi-user collaboration. The supported config items are as below."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"path"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"optional"),", specify the directory to store the Workspace, Spec, and State files. The subdirectories ",(0,i.kt)("inlineCode",{parentName:"li"},"workspaces"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"specs")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"states")," are used to store the corresponding files separately. It's recommended to use an empty or a Kusion exclusive directory as the local backend path. If not set, the default path ",(0,i.kt)("inlineCode",{parentName:"li"},"${KUSION_HOME}")," is in use.")),(0,i.kt)("p",null,"The whole local type backend configuration is as below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'{\n "type": "local",\n "configs": {\n "path": "${local_path}" # type string, optional, the directory to store files.\n }\n}\n')),(0,i.kt)("h3",{id:"mysql"},"mysql"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"mysql")," type backend uses mysql database as storage. The supported config items are as below."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"dbName"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", the name of the database."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"user"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", the username of the database. "),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"password"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"optional"),", the password of the database, support declaring by environment variable ",(0,i.kt)("inlineCode",{parentName:"li"},"KUSION_BACKEND_MYSQL_PASSWORD"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"host")," - ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", the access address for the database."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"port")," - ",(0,i.kt)("inlineCode",{parentName:"li"},"type int"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"optional"),", the port of the database. If not set, the default value ",(0,i.kt)("inlineCode",{parentName:"li"},"3306")," will be used.")),(0,i.kt)("p",null,"Please be attention, mysql type are not supported to store Spec for now. For Workspace and State, the table ",(0,i.kt)("inlineCode",{parentName:"p"},"worksapce")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," are used to store the corresponding content separately, whose structures are determinate. The table structures are shown below. "),(0,i.kt)("p",null,"Noted that there are not fields ",(0,i.kt)("inlineCode",{parentName:"p"},"id"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"gmt_create(created_at)"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"gmt_modified(updated_at)"),", etc., which are usually automatically controlled by the database. Kusion does not use these fields, while the existence of them does not affect the normal operation of Kusion. And the length of the varchar can be changed according to the real scenario."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sql"},"-- table workspace\nCREATE TABLE `workspace` (\n `workspace` varchar(127) NOT NULL COMMENT 'workspace name',\n `content` longtext NOT NULL COMMENT 'workspace content, in JSON format',\n `is_current` tinyint(1) DEFAULT NULL COMMENT 'specify is current workspace or not',\n UNIQUE KEY `uk_workspace` (`name`),\n KEY `idx_is_current` (`is_current`)\n);\n\n-- table state\nCREATE TABLE `state` (\n `project` varchar(127) NOT NULL COMMENT 'project name',\n `stack` varchar(127) NOT NULL COMMENT 'stack name',\n `workspace` varchar(127) NOT NULL COMMENT 'workspace name',\n `content` longtext NOT NULL COMMENT 'state content, in JSON format',\n UNIQUE KEY `uk_state` (`project`, `stack`, `worksapce`)\n);\n")),(0,i.kt)("p",null,"The whole mysql type backend configuration is as below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'{\n "type": "mysql",\n "configs": {\n "dbName": "${mysql_db_name}", # type string, required, the database name.\n "user": "${mysql_user}", # type string, required, the database user.\n "password": "${mysql_password}", # type string, optional, the database password.\n "host": "${mysql_host}", # type string, required, the database host.\n "port": "${mysql_port}" # type string, optional, the database port. If not set, use the default port 3306.\n }\n}\n')),(0,i.kt)("p",null,"The supported environment variable is as below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'export KUSION_BACKEND_MYSQL_PASSWORD="${mysql_password}" # configure password\n')),(0,i.kt)("h3",{id:"oss"},"oss"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"oss")," type backend uses the Alicloud Object Storage Service (OSS) as storage. The supported config items are as below."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"endpoint"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the access endpoint for alicloud oss bucket. "),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"accessKeyID"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the alicloud account accessKeyID, support declaring by environment variable ",(0,i.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_ID"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"accessKeySecret"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the alicloud account accessKeySecret, support declaring by environment variable ",(0,i.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_SECRET"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"bucket"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the name of the alicloud oss bucket."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"prefix"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"optional"),", constitute the prefix to store the Workspace, Spec, and State files, whose prefixes are ",(0,i.kt)("inlineCode",{parentName:"li"},"${prefix}/workspaces"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"${prefix}/specs")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"${prefix}/states"),' respectively. Using prefix can create a "dedicated space" for the Kusion data, which is beneficial for the management and reuse of the bucket. If not set, there is no prefix, the files are stored in the root path of the bucket if analogy to a file system.')),(0,i.kt)("p",null,"Noted that ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeyID")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeySecret")," are required for the whole configuration combined by the configuration managed by the command ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config")," and the environment variables. For the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config")," alone, they are not obligatory. And for the safety reason, using environment variables is the recommended way."),(0,i.kt)("p",null,"The whole oss type backend configuration is as below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'{\n "type": "oss",\n "configs": {\n "endpoint": "${oss_endpoint}", # type string, required, the oss endpoint.\n "accessKeyID": "${oss_access_key_id}", # type string, ooptional for the command "kusion config", the oss access key id.\n "accessKeySecret": "${oss_access_key_secret}", # type string, optional for the command "kusion config", the oss access key secret.\n "bucket": "${oss_bucket}", # type string, required, the oss bucket.\n "prefix": "${oss_prefix}" # type string, optional, the prefix to store the files.\n }\n}\n')),(0,i.kt)("p",null,"The supported environment variables are as below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'export OSS_ACCESS_KEY_ID="${oss-access-key-id}" # configure accessKeyID\nexport OSS_ACCESS_KEY_SECRET="${oss-access-key-secret}" # configure accessKeySecret\n')),(0,i.kt)("h3",{id:"s3"},"s3"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," type backend uses the AWS Simple Storage Service (S3) as storage. The supported config items are as below."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"region"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the region of aws s3 bucket, support declaring by environment variable ",(0,i.kt)("inlineCode",{parentName:"li"},"AWS_DEFAULT_REGION")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"AWS_REGION"),", where the latter has higher priority."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"endpoint"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"optional"),", specify the access endpoint for aws s3 bucket."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"accessKeyID"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the aws account accessKeyID, support declaring by environment variable ",(0,i.kt)("inlineCode",{parentName:"li"},"AWS_ACCESS_KEY_ID"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"accessKeySecret"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the aws account.accessKeySecret, support declaring by environment variable ",(0,i.kt)("inlineCode",{parentName:"li"},"AWS_SECRET_ACCESS_KEY"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"bucket"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"required"),", specify the name of the aws s3 bucket."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"prefix"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"type string"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"optional"),", constitute the prefix to store the Workspace, Spec, and State files, whose prefixes are ",(0,i.kt)("inlineCode",{parentName:"li"},"${prefix}/workspaces"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"${prefix}/specs")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"${prefix}/states")," respectively.")),(0,i.kt)("p",null,"Noted that ",(0,i.kt)("inlineCode",{parentName:"p"},"region"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeyID")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeySecret")," are optional for the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config")," command."),(0,i.kt)("p",null,"The whole s3 type backend configuration is as below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'{\n "type": "s3",\n "configs": {\n "region": "${s3_region}", # type string, optional for the command "kusion config", the aws region.\n "endpoint": "${s3_endpoint}", # type string, optional, the aws endpoint. \n "accessKeyID": "${s3_access_key_id}", # type string, optional for the command "kusion config", the aws access key id.\n "accessKeySecret": "${s3_access_key_secret}", # type string, optional for the command "kusion config", the aws access key secret.\n "bucket": "${s3_bucket}", # type string, required, the s3 bucket.\n "prefix": "${s3_prefix}" # type string, optional, the prefix to store the files.\n }\n}\n')),(0,i.kt)("p",null,"The supported environment variables are as below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_DEFAULT_REGION="${s3_region}" # configure region, lower priority than AWS_REGION\nexport AWS_REGION="${s3_region}" # configure region, higher priority than AWS_DEFAULT_REGION\nexport AWS_ACCESS_KEY_ID="${s3_access_key_id}" # configure accessKeyID\nexport AWS_SECRET_ACCESS_KEY="${s3_access_key_secret}" # configure accessKeySecret\n')),(0,i.kt)("h2",{id:"setting-a-backend"},"Setting a Backend"),(0,i.kt)("p",null,"When there is a new backend or the backend configuration needs to update, use the command ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config set ${key} ${value}")," to set a backend. A backend is identified by a unique name, and its whole configuration is made up of the backend type and its corresponding config items. "),(0,i.kt)("p",null,"Be attention, do not confuse backend with backend type. For example, a backend named ",(0,i.kt)("inlineCode",{parentName:"p"},"s3_prod")," uses ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," as its storage, the ",(0,i.kt)("inlineCode",{parentName:"p"},"s3_prod")," is the backend, while the ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," is the backend type."),(0,i.kt)("p",null,"There are four configuration modes:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"setting a whole backend"),(0,i.kt)("li",{parentName:"ul"},"setting a backend type "),(0,i.kt)("li",{parentName:"ul"},"setting a whole set of backend config items"),(0,i.kt)("li",{parentName:"ul"},"setting a backend config item")),(0,i.kt)("p",null,"A unique backend name is required to do the configuration. Take ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," type backend with name ",(0,i.kt)("inlineCode",{parentName:"p"},"s3_prod")," for an example to explain how these modes work."),(0,i.kt)("h3",{id:"setting-a-whole-backend"},"Setting a Whole Backend"),(0,i.kt)("p",null,"The key to configure a whole backend is ",(0,i.kt)("inlineCode",{parentName:"p"},"backends.${name}"),", whose value must be the JSON marshal result in a specified format, which is determined by the backend type. Enclosing the value in single quotation marks is a good choice, which can keep the format correct. "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},'# set a whole backend\nkusion config set backends.s3_prod \'{"type":"s3","configs":{"bucket":"kusion"}}\'\n')),(0,i.kt)("h3",{id:"setting-a-backend-type"},"Setting a Backend Type"),(0,i.kt)("p",null,"The key to set a backend type is ",(0,i.kt)("inlineCode",{parentName:"p"},"backends.${name}.type"),", whose value must be ",(0,i.kt)("inlineCode",{parentName:"p"},"local"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"mysql"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"oss")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"s3"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"# set a backend type\nkusion config set backends.s3_prod.type s3\n")),(0,i.kt)("h3",{id:"setting-a-whole-set-of-backend-config-items"},"Setting a Whole Set of Backend Config Items"),(0,i.kt)("p",null,"The key to set a whole set of backend config items is ",(0,i.kt)("inlineCode",{parentName:"p"},"backends.${name}.configs"),", whose value must be the JSON marshal result in a specified format, which is determined by the backend type. The backend config must be set after the backend type, and corresponds to the backend type."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},'# set a whole backend config\nkusion config set backends.s3_prod.configs \'{"bucket":"kusion"}\'\n')),(0,i.kt)("h3",{id:"setting-a-backend-config-item"},"Setting a Backend Config Item"),(0,i.kt)("p",null,"The key to set a backend config item is ",(0,i.kt)("inlineCode",{parentName:"p"},"backends.${name}.configs.${item}"),". The item name and value type both depend on the backend type. Like the whole backend config, the config item must be valid and set after the backend type."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"# set a backend config item\nkusion config set backends.s3_prod.configs.bucket kusion\n")),(0,i.kt)("p",null,"When executing ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config set"),", the configuration will be stored in a local file. For security reason, the environment variables are supported to configure some config items, such as ",(0,i.kt)("inlineCode",{parentName:"p"},"password"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeyID"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeySecret"),". Using environment variables rather than ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config")," set to set sensitive data is the best practice. If both configured, the environment variables have higher priority. For details about the supported environment variables, please see above."),(0,i.kt)("p",null,"Kusion has a default backend with ",(0,i.kt)("inlineCode",{parentName:"p"},"local")," type and the path is ",(0,i.kt)("inlineCode",{parentName:"p"},"$KUSION_HOME"),", whose name is exactly ",(0,i.kt)("inlineCode",{parentName:"p"},"default"),". The ",(0,i.kt)("inlineCode",{parentName:"p"},"default")," backend is forbidden to modification, that is setting or unsetting the default backend is not allowed. Besides, the keyword ",(0,i.kt)("inlineCode",{parentName:"p"},"current")," is also used by Kusion itself, please do not use it as the backend name."),(0,i.kt)("h2",{id:"unsetting-a-backend"},"Unsetting a Backend"),(0,i.kt)("p",null,"When a backend is not in use, or the configuration is out of date, use the command ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config unset ${key}")," to unset a backend or a specified config item. Same as the setting, there are also four modes of unsetting."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"unsetting a whole backend"),(0,i.kt)("li",{parentName:"ul"},"unsetting a backend type"),(0,i.kt)("li",{parentName:"ul"},"unsetting a whole set of backend config items"),(0,i.kt)("li",{parentName:"ul"},"unsetting a backend config item")),(0,i.kt)("p",null,"When unsetting a whole backend, the backend must not be the current backend. When unsetting the backend type, the config items must be empty and the backend not be the current."),(0,i.kt)("p",null,"Unsetting the ",(0,i.kt)("inlineCode",{parentName:"p"},"default")," backend is forbidden."),(0,i.kt)("h2",{id:"setting-the-current-backend"},"Setting the Current Backend"),(0,i.kt)("p",null,"In order not to specify backend for every operation command. Kusion provides the mechanism of setting current backend, then the current workspace will be use by default. This is very useful when you execute a series of Kusion operation commands, for they usually use the same backend."),(0,i.kt)("p",null,"Use the command ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config set backends.current ${name}")," to set the current backend, where the ",(0,i.kt)("inlineCode",{parentName:"p"},"name")," must be the already set backend."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"# set the current workspace\nkusion config set backends.current s3_prod\n")),(0,i.kt)("p",null,"Setting the current backend to ",(0,i.kt)("inlineCode",{parentName:"p"},"default")," is legal. Actually, if there is no backend related configuration, the current backend is the ",(0,i.kt)("inlineCode",{parentName:"p"},"default")," backend."),(0,i.kt)("h2",{id:"getting-backend-configuration"},"Getting Backend Configuration"),(0,i.kt)("p",null,"Use the command ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config get ${key}")," to get a whole backend configuration or a specified backend config item. The ",(0,i.kt)("inlineCode",{parentName:"p"},"key")," is same as setting and unsetting operation, the whole list can be found in the ",(0,i.kt)("a",{parentName:"p",href:"configuration"},"Configuration"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"# get a whole backend\nkusion config get backends.s3_prod\n\n# get a specified config item\nkusion config get backends.s3_prod.configs.bucekt\n")),(0,i.kt)("p",null,"Besides, the command ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion config list")," can also be used, which returns the whole kusion configuration, while the backend configuration is included."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"# get the whole Kusion configuration \nkusion config list\n")),(0,i.kt)("h2",{id:"using-backend"},"Using Backend"),(0,i.kt)("p",null,"The backend is used to store Workspace, Spec, and State. Thus, the following commands use the backend, shown as below."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"subcommands of ",(0,i.kt)("inlineCode",{parentName:"li"},"kusion workspace"),": use to store the Workspace;"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"kusion generate"),": use to store the Spec;"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"kusion preview"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"kusion apply"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"kusion destroy"),": use to store the State;")),(0,i.kt)("p",null,"For all the commands above, the flag ",(0,i.kt)("inlineCode",{parentName:"p"},"--backend")," is provided to specify the backend, or using the current backend. When using backend, you usually need to specify the sensitive data by environment variables. The example is shown below."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},'# set environment variables of sensitive and other necessary data\nexport AWS_REGION="${s3_region}"\nexport AWS_ACCESS_KEY_ID="${s3_access_key_id}"\nexport AWS_SECRET_ACCESS_KEY="${s3_access_key_secret}"\n\n# use current backend\nkusion apply\n\n# use a specified backend\nkusion apply --backend s3_prod\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0b745da3.04428ad4.js b/assets/js/0b745da3.04428ad4.js deleted file mode 100644 index 9269baf7bbe..00000000000 --- a/assets/js/0b745da3.04428ad4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5498],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),u=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=u(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),d=u(n),m=r,f=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return n?a.createElement(f,i(i({ref:t},s),{},{components:n})):a.createElement(f,i({ref:t},s))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var a=n(87462),r=(n(67294),n(3905));const o={id:"operational-rules"},i="Operational Rules",l={unversionedId:"kusion/configuration-walkthrough/operational-rules",id:"kusion/configuration-walkthrough/operational-rules",title:"Operational Rules",description:"You could also specify the collection of operational rule requirements for the application. That can be achieved via a opsrule module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that. Operational rules are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/docs/kusion/4-configuration-walkthrough/9-operational-rules.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/operational-rules",permalink:"/docs/next/kusion/configuration-walkthrough/operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/9-operational-rules.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{id:"operational-rules"},sidebar:"kusion",previous:{title:"Application Monitoring",permalink:"/docs/next/kusion/configuration-walkthrough/monitoring"},next:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/next/kusion/user-guides/cloud-resources/database"}},p={},u=[{value:"Import",id:"import",level:2},{value:"Max Unavailable Replicas",id:"max-unavailable-replicas",level:2}],s={toc:u};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"operational-rules"},"Operational Rules"),(0,r.kt)("p",null,"You could also specify the collection of operational rule requirements for the application. That can be achieved via a ",(0,r.kt)("inlineCode",{parentName:"p"},"opsrule")," module (or bring-your-own-module) in the ",(0,r.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that. Operational rules are used as a preemptive measure to police and stop any unwanted changes."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,r.kt)("inlineCode",{parentName:"p"},"opsrule")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport opsrule as o\n")),(0,r.kt)("h2",{id:"max-unavailable-replicas"},"Max Unavailable Replicas"),(0,r.kt)("p",null,"Currently, the ",(0,r.kt)("inlineCode",{parentName:"p"},"opsrule")," module supports setting a ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," parameter, which specifies the maximum number of pods that can be rendered unavailable at any time. It can be either a fraction of the total pods for the current application or a fixed number. This operational rule is particularly helpful against unexpected changes or deletes to the workloads. It can also prevent too many workloads from going down during an application upgrade."),(0,r.kt)("p",null,"More rules will be available in future versions of Kusion."),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a percentage of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n }\n accessories: {\n "opsRule": o.OpsRule {\n maxUnavailable: "30%"\n }\n }\n}\n')),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a fixed number of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "opsRule": o.OpsRule {\n maxUnavailable: 2\n }\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0b745da3.11825daf.js b/assets/js/0b745da3.11825daf.js new file mode 100644 index 00000000000..151e6a33123 --- /dev/null +++ b/assets/js/0b745da3.11825daf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5498],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),u=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=u(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),d=u(n),m=r,f=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return n?a.createElement(f,i(i({ref:t},s),{},{components:n})):a.createElement(f,i({ref:t},s))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var a=n(87462),r=(n(67294),n(3905));const o={id:"operational-rules"},i="Operational Rules",l={unversionedId:"kusion/configuration-walkthrough/operational-rules",id:"kusion/configuration-walkthrough/operational-rules",title:"Operational Rules",description:"You could also specify the collection of operational rule requirements for the application. That can be achieved via a opsrule module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that. Operational rules are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/docs/kusion/4-configuration-walkthrough/9-operational-rules.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/operational-rules",permalink:"/docs/next/kusion/configuration-walkthrough/operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/9-operational-rules.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{id:"operational-rules"},sidebar:"kusion",previous:{title:"Application Monitoring",permalink:"/docs/next/kusion/configuration-walkthrough/monitoring"},next:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/next/kusion/user-guides/cloud-resources/database"}},p={},u=[{value:"Import",id:"import",level:2},{value:"Max Unavailable Replicas",id:"max-unavailable-replicas",level:2}],s={toc:u};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"operational-rules"},"Operational Rules"),(0,r.kt)("p",null,"You could also specify the collection of operational rule requirements for the application. That can be achieved via a ",(0,r.kt)("inlineCode",{parentName:"p"},"opsrule")," module (or bring-your-own-module) in the ",(0,r.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that. Operational rules are used as a preemptive measure to police and stop any unwanted changes."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,r.kt)("inlineCode",{parentName:"p"},"opsrule")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport opsrule as o\n")),(0,r.kt)("h2",{id:"max-unavailable-replicas"},"Max Unavailable Replicas"),(0,r.kt)("p",null,"Currently, the ",(0,r.kt)("inlineCode",{parentName:"p"},"opsrule")," module supports setting a ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," parameter, which specifies the maximum number of pods that can be rendered unavailable at any time. It can be either a fraction of the total pods for the current application or a fixed number. This operational rule is particularly helpful against unexpected changes or deletes to the workloads. It can also prevent too many workloads from going down during an application upgrade."),(0,r.kt)("p",null,"More rules will be available in future versions of Kusion."),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a percentage of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n }\n accessories: {\n "opsRule": o.OpsRule {\n maxUnavailable: "30%"\n }\n }\n}\n')),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a fixed number of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "opsRule": o.OpsRule {\n maxUnavailable: 2\n }\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0bf91782.caa55d3c.js b/assets/js/0bf91782.3e421779.js similarity index 56% rename from assets/js/0bf91782.caa55d3c.js rename to assets/js/0bf91782.3e421779.js index 22048703833..ee683db7832 100644 --- a/assets/js/0bf91782.caa55d3c.js +++ b/assets/js/0bf91782.3e421779.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4206],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),m=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=m(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),c=m(r),d=o,h=c["".concat(s,".").concat(d)]||c[d]||u[d]||a;return r?n.createElement(h,l(l({ref:t},p),{},{components:r})):n.createElement(h,l({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=c;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,l[1]=i;for(var m=2;m{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>m});var n=r(87462),o=(r(67294),r(3905));const a={},l="prometheus",i={unversionedId:"kusion/reference/modules/catalog-models/monitoring/prometheus",id:"version-v0.10/kusion/reference/modules/catalog-models/monitoring/prometheus",title:"prometheus",description:"Schema Prometheus",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/monitoring",slug:"/kusion/reference/modules/catalog-models/monitoring/prometheus",permalink:"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"secret",permalink:"/docs/kusion/reference/modules/catalog-models/internal/secret/"},next:{title:"opsrule",permalink:"/docs/kusion/reference/modules/catalog-models/trait/opsrule"}},s={},m=[{value:"Schema Prometheus",id:"schema-prometheus",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:m};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"prometheus"},"prometheus"),(0,o.kt)("h2",{id:"schema-prometheus"},"Schema Prometheus"),(0,o.kt)("p",null,"Prometheus can be used to define monitoring requirements"),(0,o.kt)("h3",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"path"),(0,o.kt)("br",null),"The path to scrape metrics from."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"/metrics"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"port"),(0,o.kt)("br",null),"The port to scrape metrics from. When using Prometheus operator, this needs to be the port NAME. Otherwise, this can be a port name or a number."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"container ports when scraping pod (monitorType is pod) and service port when scraping service (monitorType is service)"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.monitoring as m\n\nmonitoring: m.Prometheus{\n path: "/metrics"\n port: "web"\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4206],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),m=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=m(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),c=m(r),d=o,h=c["".concat(s,".").concat(d)]||c[d]||u[d]||a;return r?n.createElement(h,l(l({ref:t},p),{},{components:r})):n.createElement(h,l({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=c;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,l[1]=i;for(var m=2;m{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>m});var n=r(87462),o=(r(67294),r(3905));const a={},l="prometheus",i={unversionedId:"kusion/reference/modules/catalog-models/monitoring/prometheus",id:"version-v0.10/kusion/reference/modules/catalog-models/monitoring/prometheus",title:"prometheus",description:"Schema Prometheus",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/monitoring",slug:"/kusion/reference/modules/catalog-models/monitoring/prometheus",permalink:"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"secret",permalink:"/docs/kusion/reference/modules/catalog-models/internal/secret/"},next:{title:"opsrule",permalink:"/docs/kusion/reference/modules/catalog-models/trait/opsrule"}},s={},m=[{value:"Schema Prometheus",id:"schema-prometheus",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:m};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"prometheus"},"prometheus"),(0,o.kt)("h2",{id:"schema-prometheus"},"Schema Prometheus"),(0,o.kt)("p",null,"Prometheus can be used to define monitoring requirements"),(0,o.kt)("h3",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"path"),(0,o.kt)("br",null),"The path to scrape metrics from."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"/metrics"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"port"),(0,o.kt)("br",null),"The port to scrape metrics from. When using Prometheus operator, this needs to be the port NAME. Otherwise, this can be a port name or a number."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"container ports when scraping pod (monitorType is pod) and service port when scraping service (monitorType is service)"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.monitoring as m\n\nmonitoring: m.Prometheus{\n path: "/metrics"\n port: "web"\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0dc90373.48fe1927.js b/assets/js/0dc90373.48fe1927.js deleted file mode 100644 index fd60e40ccfb..00000000000 --- a/assets/js/0dc90373.48fe1927.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[181],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="Job",o={unversionedId:"kusion/reference/model/catalog_models/workload/doc_job",id:"version-v0.9/kusion/reference/model/catalog_models/workload/doc_job",title:"Job",description:"Schemas",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_job.md",sourceDirName:"kusion/reference/model/catalog_models/workload",slug:"/kusion/reference/model/catalog_models/workload/doc_job",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_job.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"App Configuration",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration"},next:{title:"Service",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Job",id:"schema-job",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"job"},"Job"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-job"},"Job"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret"))))),(0,r.kt)("h2",{id:"schema-job"},"Schema Job"),(0,r.kt)("p",null,"Job is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),"is typically used for tasks that take from a few seconds to a few days to complete."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"schedule")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a job with busybox image and runs every hour\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\njob: wl.Job {\n containers: {\n "busybox": c.Container{\n image: "busybox:1.28"\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n schedule: "0 * * * *"\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0dc90373.eb82127b.js b/assets/js/0dc90373.eb82127b.js new file mode 100644 index 00000000000..76c033ea1fa --- /dev/null +++ b/assets/js/0dc90373.eb82127b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[181],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="Job",o={unversionedId:"kusion/reference/model/catalog_models/workload/doc_job",id:"version-v0.9/kusion/reference/model/catalog_models/workload/doc_job",title:"Job",description:"Schemas",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_job.md",sourceDirName:"kusion/reference/model/catalog_models/workload",slug:"/kusion/reference/model/catalog_models/workload/doc_job",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_job.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"App Configuration",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration"},next:{title:"Service",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Job",id:"schema-job",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"job"},"Job"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-job"},"Job"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret"))))),(0,r.kt)("h2",{id:"schema-job"},"Schema Job"),(0,r.kt)("p",null,"Job is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),"is typically used for tasks that take from a few seconds to a few days to complete."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"schedule")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a job with busybox image and runs every hour\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\njob: wl.Job {\n containers: {\n "busybox": c.Container{\n image: "busybox:1.28"\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n schedule: "0 * * * *"\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0e7cda11.11e5d9ca.js b/assets/js/0e7cda11.11e5d9ca.js new file mode 100644 index 00000000000..e57a8844f47 --- /dev/null +++ b/assets/js/0e7cda11.11e5d9ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6852],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(t),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||i;return t?o.createElement(k,r(r({ref:n},c),{},{components:t})):o.createElement(k,r({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,r=new Array(i);r[0]=d;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),a=(t(67294),t(3905));const i={},r="Workload",l={unversionedId:"kusion/configuration-walkthrough/workload",id:"version-v0.10/kusion/configuration-walkthrough/workload",title:"Workload",description:"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/4-workload.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/workload",permalink:"/docs/kusion/configuration-walkthrough/workload",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/4-workload.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Base and Override",permalink:"/docs/kusion/configuration-walkthrough/base-override"},next:{title:"Application Networking",permalink:"/docs/kusion/configuration-walkthrough/networking"}},p={},s=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Import",id:"import",level:2},{value:"Types of Workloads",id:"types-of-workloads",level:2},{value:"Configure containers",id:"configure-containers",level:2},{value:"Application image",id:"application-image",level:3},{value:"Resource Requirements",id:"resource-requirements",level:3},{value:"Health Probes",id:"health-probes",level:3},{value:"Lifecycle Hooks",id:"lifecycle-hooks",level:3},{value:"Create Files",id:"create-files",level:3},{value:"Customize container initialization",id:"customize-container-initialization",level:3},{value:"Configure Replicas",id:"configure-replicas",level:2},{value:"Differences between Service and Job",id:"differences-between-service-and-job",level:2},{value:"Exposure",id:"exposure",level:3},{value:"Job Schedule",id:"job-schedule",level:3},{value:"Workload References",id:"workload-references",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"workload"},"Workload"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application."),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," maps to an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance 1:1. If there are more than one workload, they should be considered different applications."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#import"},"Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#types-of-workloads"},"Types of workloads")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-containers"},"Configure containers"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#application-image"},"Application image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#resource-requirements"},"Resource Requirements")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#health-probes"},"Health Probes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#lifecycle-hooks"},"Lifecycle Hooks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#create-files"},"Create Files")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#customize-container-initialization"},"Customize container initialization")))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-replicas"},"Configure Replicas")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#differences-between-service-and-job"},"Differences between Service and Job")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#workload-references"},"Workload References"))),(0,a.kt)("h2",{id:"import"},"Import"),(0,a.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n")),(0,a.kt)("h2",{id:"types-of-workloads"},"Types of Workloads"),(0,a.kt)("p",null,"There are currently two types of workloads:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Service"),', representing a long-running, scalable workload type that should "never" go down and respond to short-lived latency-sensitive requests. This workload type is commonly used for web applications and services that expose APIs.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Job"),", representing batch tasks that take from a few seconds to days to complete and then stop. These are commonly used for batch processing that is less sensitive to short-term performance fluctuations.")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {}\n}\n")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Job {}\n}\n")),(0,a.kt)("p",null,"Of course, the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instances above is not sufficient to describe an application. We still need to provide more details in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," section."),(0,a.kt)("h2",{id:"configure-containers"},"Configure containers"),(0,a.kt)("p",null,"Kusion is built on top of cloud-native philosophies. One of which is that applications should run as loosely coupled microservices on abstract and self-contained software units, such as containers."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute in a workload instance is used to define the behavior for the containers that run application workload. The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is a map, from the name of the container to the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog.models.schema.v1.workload.container.Container")," Object which includes the container configurations."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The name of the container is in the context of the configuration file, so you could refer to it later. It's not referring to the name of the container in the Kubernetes cluster (or any other runtime).")),(0,a.kt)("p",null,"Everything defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is considered an application container, as opposed to a sidecar container. Sidecar containers will be introduced in a different attribute in a future version."),(0,a.kt)("p",null,"In most of the cases, only one application container is needed. Ideally, we recommend mapping an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance to a microservice in the microservice terminology."),(0,a.kt)("p",null,"We will walk through the details of configuring a container using an example of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type."),(0,a.kt)("p",null,"To add an application container:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n }\n }\n}\n')),(0,a.kt)("h3",{id:"application-image"},"Application image"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application image to run. This is the only required field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"To specify an application image:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n }\n }\n}\n')),(0,a.kt)("h3",{id:"resource-requirements"},"Resource Requirements"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"resources")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application resource requirements such as cpu and memory."),(0,a.kt)("p",null,"You can specify an upper limit (which maps to resource limits only) or a range as the resource requirements (which maps to resource requests and limits in Kubernetes)."),(0,a.kt)("p",null,"To specify an upper bound (only resource limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"To specify a range (both resource requests and limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # Sets requests to cpu=250m and memory=256Mi\n # Sets limits to cpu=500m and memory=512Mi\n resources: {\n "cpu": "250m-500m"\n "memory": "256Mi-512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"health-probes"},"Health Probes"),(0,a.kt)("p",null,"There are three types of ",(0,a.kt)("inlineCode",{parentName:"p"},"Probe")," defined in a ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"livenessProbe")," - used to determine if the container is healthy and running"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"readinessProbe")," - used to determine if the container is ready to accept traffic"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," - used to determine if the container has started properly. Liveness and readiness probes don't start until ",(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," succeeds. Commonly used for containers that takes a while to start")),(0,a.kt)("p",null,"The probes are optional. You can only have one Probe of each kind for a given ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),"."),(0,a.kt)("p",null,"To configure a ",(0,a.kt)("inlineCode",{parentName:"p"},"Http")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"readinessProbe")," that probes the health via HTTP request and a ",(0,a.kt)("inlineCode",{parentName:"p"},"Exec")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"livenessProbe")," which executes a command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure an Http type readiness probe at /healthz\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "/healthz"\n }\n initialDelaySeconds: 10\n timeoutSeconds: 5\n periodSeconds: 15\n successThreshold: 3\n failureThreshold: 1\n }\n # Configure an Exec type liveness probe that executes probe.sh\n livenessProbe: p.Probe {\n probeHandler: p.Exec {\n command: ["probe.sh"]\n }\n initialDelaySeconds: 10\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"lifecycle-hooks"},"Lifecycle Hooks"),(0,a.kt)("p",null,"You can also configure lifecycle hooks that triggers in response to container lifecycle events such as liveness/startup probe failure, preemption, resource contention, etc."),(0,a.kt)("p",null,"There are two types that is currently supported:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PreStop")," - triggers before the container is terminated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PostStart")," - triggers after the container is initialized.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure lifecycle hooks\n lifecycle: lc.Lifecycle {\n # Configures an Exec type pre-stop hook that executes preStop.sh\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n # Configures an Http type pre-stop hook at /post-start\n postStart: p.Http {\n url: "/post-start"\n }\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"create-files"},"Create Files"),(0,a.kt)("p",null,"You can also create files on-demand during the container initialization."),(0,a.kt)("p",null,"To create a custom file and mount it to ",(0,a.kt)("inlineCode",{parentName:"p"},"/home/admin/my-file")," when the container starts:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n # Creates a file during container startup\n files: {\n "/home/admin/my-file": c.FileSpec {\n content: "some file contents"\n mode: "0777"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"customize-container-initialization"},"Customize container initialization"),(0,a.kt)("p",null,"You can also customize the container entrypoint via ",(0,a.kt)("inlineCode",{parentName:"p"},"command"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"args"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"workingDir"),". These should ",(0,a.kt)("strong",{parentName:"p"},"most likely not be required"),". In most of the cases, the entrypoint details should be baked into the application image itself."),(0,a.kt)("p",null,"To customize the container entrypoint:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # This command will overwrite the entrypoint set in the image Dockerfile\n command: ["/usr/local/bin/my-init-script.sh"]\n # Extra arguments append to command defined above\n args: [\n "--log-dir=/home/my-app/logs"\n "--timeout=60s"\n ]\n # Run the command as defined above, in the directory "/tmp"\n workingDir: "/tmp"\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"configure-replicas"},"Configure Replicas"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"replicas")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance describes the number of identical copies to run at the same time. It is generally recommended to have multiple replicas in production environments to eliminate any single point of failure. In Kubernetes, this corresponds to the ",(0,a.kt)("inlineCode",{parentName:"p"},"spec.replicas")," field in the relevant workload manifests."),(0,a.kt)("p",null,"To configure a workload to have a replica count of 3:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n replicas: 3\n # ...\n }\n # ...\n}\n")),(0,a.kt)("h2",{id:"differences-between-service-and-job"},"Differences between Service and Job"),(0,a.kt)("p",null,"The two types of workloads, namely ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),", share a majority of the attributes with some minor differences."),(0,a.kt)("h3",{id:"exposure"},"Exposure"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," usually represents a long-running, scalable workload that responds to short-lived latency-sensitive requests and never go down. Hence, a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," has an additional attribute that determines how it is exposed and can be accessed. A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," does NOT have the option to be exposed. We will explore more in the ",(0,a.kt)("a",{parentName:"p",href:"networking"},"application networking walkthrough"),"."),(0,a.kt)("h3",{id:"job-schedule"},"Job Schedule"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," can be configured to run in a recurring manner. In this case, the job will have a cron-format schedule that represents its recurring schedule."),(0,a.kt)("p",null,"To configure a job to run at 21:00 every night:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: wl.Job {\n containers: {\n # ...\n }\n schedule: "0 21 * * *"\n }\n')),(0,a.kt)("h2",{id:"workload-references"},"Workload References"),(0,a.kt)("p",null,"You can find workload references ",(0,a.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/workload/service"},"here"),"."),(0,a.kt)("p",null,"You can find workload schema source ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/schema/v1/workload"},"here"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0e7cda11.f86c28ee.js b/assets/js/0e7cda11.f86c28ee.js deleted file mode 100644 index f64e513d6ba..00000000000 --- a/assets/js/0e7cda11.f86c28ee.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6852],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(t),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||i;return t?o.createElement(k,r(r({ref:n},c),{},{components:t})):o.createElement(k,r({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,r=new Array(i);r[0]=d;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),a=(t(67294),t(3905));const i={},r="Workload",l={unversionedId:"kusion/configuration-walkthrough/workload",id:"version-v0.10/kusion/configuration-walkthrough/workload",title:"Workload",description:"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/4-workload.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/workload",permalink:"/docs/kusion/configuration-walkthrough/workload",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/4-workload.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Base and Override",permalink:"/docs/kusion/configuration-walkthrough/base-override"},next:{title:"Application Networking",permalink:"/docs/kusion/configuration-walkthrough/networking"}},p={},s=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Import",id:"import",level:2},{value:"Types of Workloads",id:"types-of-workloads",level:2},{value:"Configure containers",id:"configure-containers",level:2},{value:"Application image",id:"application-image",level:3},{value:"Resource Requirements",id:"resource-requirements",level:3},{value:"Health Probes",id:"health-probes",level:3},{value:"Lifecycle Hooks",id:"lifecycle-hooks",level:3},{value:"Create Files",id:"create-files",level:3},{value:"Customize container initialization",id:"customize-container-initialization",level:3},{value:"Configure Replicas",id:"configure-replicas",level:2},{value:"Differences between Service and Job",id:"differences-between-service-and-job",level:2},{value:"Exposure",id:"exposure",level:3},{value:"Job Schedule",id:"job-schedule",level:3},{value:"Workload References",id:"workload-references",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"workload"},"Workload"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application."),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," maps to an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance 1:1. If there are more than one workload, they should be considered different applications."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#import"},"Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#types-of-workloads"},"Types of workloads")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-containers"},"Configure containers"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#application-image"},"Application image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#resource-requirements"},"Resource Requirements")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#health-probes"},"Health Probes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#lifecycle-hooks"},"Lifecycle Hooks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#create-files"},"Create Files")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#customize-container-initialization"},"Customize container initialization")))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-replicas"},"Configure Replicas")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#differences-between-service-and-job"},"Differences between Service and Job")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#workload-references"},"Workload References"))),(0,a.kt)("h2",{id:"import"},"Import"),(0,a.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n")),(0,a.kt)("h2",{id:"types-of-workloads"},"Types of Workloads"),(0,a.kt)("p",null,"There are currently two types of workloads:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Service"),', representing a long-running, scalable workload type that should "never" go down and respond to short-lived latency-sensitive requests. This workload type is commonly used for web applications and services that expose APIs.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Job"),", representing batch tasks that take from a few seconds to days to complete and then stop. These are commonly used for batch processing that is less sensitive to short-term performance fluctuations.")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {}\n}\n")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Job {}\n}\n")),(0,a.kt)("p",null,"Of course, the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instances above is not sufficient to describe an application. We still need to provide more details in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," section."),(0,a.kt)("h2",{id:"configure-containers"},"Configure containers"),(0,a.kt)("p",null,"Kusion is built on top of cloud-native philosophies. One of which is that applications should run as loosely coupled microservices on abstract and self-contained software units, such as containers."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute in a workload instance is used to define the behavior for the containers that run application workload. The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is a map, from the name of the container to the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog.models.schema.v1.workload.container.Container")," Object which includes the container configurations."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The name of the container is in the context of the configuration file, so you could refer to it later. It's not referring to the name of the container in the Kubernetes cluster (or any other runtime).")),(0,a.kt)("p",null,"Everything defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is considered an application container, as opposed to a sidecar container. Sidecar containers will be introduced in a different attribute in a future version."),(0,a.kt)("p",null,"In most of the cases, only one application container is needed. Ideally, we recommend mapping an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance to a microservice in the microservice terminology."),(0,a.kt)("p",null,"We will walk through the details of configuring a container using an example of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type."),(0,a.kt)("p",null,"To add an application container:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n }\n }\n}\n')),(0,a.kt)("h3",{id:"application-image"},"Application image"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application image to run. This is the only required field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"To specify an application image:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n }\n }\n}\n')),(0,a.kt)("h3",{id:"resource-requirements"},"Resource Requirements"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"resources")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application resource requirements such as cpu and memory."),(0,a.kt)("p",null,"You can specify an upper limit (which maps to resource limits only) or a range as the resource requirements (which maps to resource requests and limits in Kubernetes)."),(0,a.kt)("p",null,"To specify an upper bound (only resource limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"To specify a range (both resource requests and limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # Sets requests to cpu=250m and memory=256Mi\n # Sets limits to cpu=500m and memory=512Mi\n resources: {\n "cpu": "250m-500m"\n "memory": "256Mi-512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"health-probes"},"Health Probes"),(0,a.kt)("p",null,"There are three types of ",(0,a.kt)("inlineCode",{parentName:"p"},"Probe")," defined in a ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"livenessProbe")," - used to determine if the container is healthy and running"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"readinessProbe")," - used to determine if the container is ready to accept traffic"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," - used to determine if the container has started properly. Liveness and readiness probes don't start until ",(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," succeeds. Commonly used for containers that takes a while to start")),(0,a.kt)("p",null,"The probes are optional. You can only have one Probe of each kind for a given ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),"."),(0,a.kt)("p",null,"To configure a ",(0,a.kt)("inlineCode",{parentName:"p"},"Http")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"readinessProbe")," that probes the health via HTTP request and a ",(0,a.kt)("inlineCode",{parentName:"p"},"Exec")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"livenessProbe")," which executes a command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure an Http type readiness probe at /healthz\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "/healthz"\n }\n initialDelaySeconds: 10\n timeoutSeconds: 5\n periodSeconds: 15\n successThreshold: 3\n failureThreshold: 1\n }\n # Configure an Exec type liveness probe that executes probe.sh\n livenessProbe: p.Probe {\n probeHandler: p.Exec {\n command: ["probe.sh"]\n }\n initialDelaySeconds: 10\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"lifecycle-hooks"},"Lifecycle Hooks"),(0,a.kt)("p",null,"You can also configure lifecycle hooks that triggers in response to container lifecycle events such as liveness/startup probe failure, preemption, resource contention, etc."),(0,a.kt)("p",null,"There are two types that is currently supported:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PreStop")," - triggers before the container is terminated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PostStart")," - triggers after the container is initialized.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure lifecycle hooks\n lifecycle: lc.Lifecycle {\n # Configures an Exec type pre-stop hook that executes preStop.sh\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n # Configures an Http type pre-stop hook at /post-start\n postStart: p.Http {\n url: "/post-start"\n }\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"create-files"},"Create Files"),(0,a.kt)("p",null,"You can also create files on-demand during the container initialization."),(0,a.kt)("p",null,"To create a custom file and mount it to ",(0,a.kt)("inlineCode",{parentName:"p"},"/home/admin/my-file")," when the container starts:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n # Creates a file during container startup\n files: {\n "/home/admin/my-file": c.FileSpec {\n content: "some file contents"\n mode: "0777"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"customize-container-initialization"},"Customize container initialization"),(0,a.kt)("p",null,"You can also customize the container entrypoint via ",(0,a.kt)("inlineCode",{parentName:"p"},"command"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"args"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"workingDir"),". These should ",(0,a.kt)("strong",{parentName:"p"},"most likely not be required"),". In most of the cases, the entrypoint details should be baked into the application image itself."),(0,a.kt)("p",null,"To customize the container entrypoint:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # This command will overwrite the entrypoint set in the image Dockerfile\n command: ["/usr/local/bin/my-init-script.sh"]\n # Extra arguments append to command defined above\n args: [\n "--log-dir=/home/my-app/logs"\n "--timeout=60s"\n ]\n # Run the command as defined above, in the directory "/tmp"\n workingDir: "/tmp"\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"configure-replicas"},"Configure Replicas"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"replicas")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance describes the number of identical copies to run at the same time. It is generally recommended to have multiple replicas in production environments to eliminate any single point of failure. In Kubernetes, this corresponds to the ",(0,a.kt)("inlineCode",{parentName:"p"},"spec.replicas")," field in the relevant workload manifests."),(0,a.kt)("p",null,"To configure a workload to have a replica count of 3:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n replicas: 3\n # ...\n }\n # ...\n}\n")),(0,a.kt)("h2",{id:"differences-between-service-and-job"},"Differences between Service and Job"),(0,a.kt)("p",null,"The two types of workloads, namely ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),", share a majority of the attributes with some minor differences."),(0,a.kt)("h3",{id:"exposure"},"Exposure"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," usually represents a long-running, scalable workload that responds to short-lived latency-sensitive requests and never go down. Hence, a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," has an additional attribute that determines how it is exposed and can be accessed. A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," does NOT have the option to be exposed. We will explore more in the ",(0,a.kt)("a",{parentName:"p",href:"networking"},"application networking walkthrough"),"."),(0,a.kt)("h3",{id:"job-schedule"},"Job Schedule"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," can be configured to run in a recurring manner. In this case, the job will have a cron-format schedule that represents its recurring schedule."),(0,a.kt)("p",null,"To configure a job to run at 21:00 every night:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: wl.Job {\n containers: {\n # ...\n }\n schedule: "0 21 * * *"\n }\n')),(0,a.kt)("h2",{id:"workload-references"},"Workload References"),(0,a.kt)("p",null,"You can find workload references ",(0,a.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/workload/service"},"here"),"."),(0,a.kt)("p",null,"You can find workload schema source ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/schema/v1/workload"},"here"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0f1fb433.6680edfb.js b/assets/js/0f1fb433.6680edfb.js deleted file mode 100644 index afcdd9f02c2..00000000000 --- a/assets/js/0f1fb433.6680edfb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1721],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Deploy Application",l={unversionedId:"kusion/user-guides/working-with-k8s/deploy-application",id:"version-v0.10/kusion/user-guides/working-with-k8s/deploy-application",title:"Deploy Application",description:"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/deploy-application",permalink:"/docs/kusion/user-guides/working-with-k8s/deploy-application",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/kusion/user-guides/cloud-resources/expose-service"},next:{title:"Configure Containers",permalink:"/docs/kusion/user-guides/working-with-k8s/container"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initializing",id:"initializing",level:2},{value:"Initializing workspace configuration",id:"initializing-workspace-configuration",level:2},{value:"Initializing application configuration",id:"initializing-application-configuration",level:2},{value:"kcl.mod",id:"kclmod",level:3},{value:"Building",id:"building",level:2},{value:"Applying",id:"applying",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"deploy-application"},"Deploy Application"),(0,a.kt)("p",null,"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.\nWe call the abstraction of application operation and maintenance configuration as ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", and its instance as ",(0,a.kt)("inlineCode",{parentName:"p"},"Application"),".\nIt is essentially a configuration model that describes an application. The complete definition can be seen ",(0,a.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/app-configuration"},"here"),"."),(0,a.kt)("p",null,"In production, the application generally includes minimally several k8s resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Namespace"),(0,a.kt)("li",{parentName:"ul"},"Deployment"),(0,a.kt)("li",{parentName:"ul"},"Service")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/"},"Namespace")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/services-networking/service/"},"Service")))),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Before we start, we need to complete the following steps:"),(0,a.kt)("p",null,"1\u3001Install Kusion"),(0,a.kt)("p",null,"We recommend using HomeBrew(Mac), Scoop(Windows), or an installation shell script to download and install Kusion.\nSee ",(0,a.kt)("a",{parentName:"p",href:"../../getting-started/install-kusion"},"Download and Install")," for more details."),(0,a.kt)("p",null,"2\u3001Running Kubernetes cluster"),(0,a.kt)("p",null,"There must be a running Kubernetes cluster and a ",(0,a.kt)("a",{parentName:"p",href:"https://Kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," command line tool.\nIf you don't have a cluster yet, you can use ",(0,a.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")," to start one of your own."),(0,a.kt)("h2",{id:"initializing"},"Initializing"),(0,a.kt)("p",null,"This guide is to deploy an app using Kusion, relying on the Kusion CLI and an existing a Kubernetes cluster."),(0,a.kt)("h2",{id:"initializing-workspace-configuration"},"Initializing workspace configuration"),(0,a.kt)("p",null,"In version 0.10.0, we have introduced the new concept of ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspaces"),', which is a logical layer whose configurations represent an opinionated set of defaults, often appointed by the platform team. In most cases workspaces are represented with an "environment" in traditional SDLC terms. These workspaces provide a means to separate the concerns between the application developers who wish to focus on business logic, and a group of platform engineers who wish to standardize the applications on the platform.'),(0,a.kt)("p",null,"Driven by the discipline of Platform Engineering, management of the workspaces, including create/updating/deleting workspaces and their configurations should be done by dedicated platform engineers in a large software organizations to facilitate a more mature and scalable collaboration pattern."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"More on the collaboration pattern can be found in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"design doc"),".")),(0,a.kt)("p",null,"However, if that does NOT apply to your scenario, e.g. if you work in a smaller org without platform engineers or if you are an individual developer, we wish Kusion can still be a value tool to have when delivering an application. In this guide, we are NOT distinctively highlighting the different roles or what the best practices entails (the design doc above has all that) but rather the steps needed to get Kusion tool to work."),(0,a.kt)("p",null,"As of version 0.10.0, workspace configurations in Kusion are managed on the local filesystem and their values are sourced from YAML files. Remotely-managed workspaces will be supported in future versions."),(0,a.kt)("p",null,"To initialize the workspace configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"~/playground$ touch ~/dev.yaml\n~/playground$ kusion workspace create dev -f ~/dev.yaml\ncreate workspace dev successfully\n")),(0,a.kt)("p",null,"To verify the workspace has been created properly:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"~/playground$ kusion workspace list\n- dev\n~/playground$ kusion workspace show dev\n{}\n")),(0,a.kt)("p",null,"Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"show")," command tells us the workspace configuration is currently empty, which is expected because we created the ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," workspace with an empty YAML file. An empty workspace configuration will suffice in some cases, where no platform configurations are needed."),(0,a.kt)("p",null,"We will progressively add more workspace configurations throughout this user guide."),(0,a.kt)("h2",{id:"initializing-application-configuration"},"Initializing application configuration"),(0,a.kt)("p",null,"Now that workspaces are properly initialized, we can begin by initializing the application configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion init\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command will prompt you to enter required parameters, such as project name, project description, image address, etc.\nYou can keep pressing ",(0,a.kt)("em",{parentName:"p"},"Enter")," all the way to use the default values."),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"\u2714 single-stack-sample A minimal kusion project of single stack\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n\u2714 Project Name: simple-service\n\u2714 AppName: helloworld\n\u2714 ProjectName: simple-service\nStack Config: dev\n\u2714 Image: gcr.io/google-samples/gb-frontend:v4\nCreated project 'simple-service'\n")),(0,a.kt)("p",null,"Now, we have successfully initialized a project ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," template, which contains a ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"AppName")," represents the name of the sample application, which is recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"main.k")," as the name of the ",(0,a.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," instance."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProjectName")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Project Name")," represent the name of the sample project, which is used as the generated folder name and then recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Image")," represents the image address of the application container.")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/project/overview"},"Project")," and ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,a.kt)("p",null,"The directory structure is as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"simple-service/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n2 directories, 6 files\n")),(0,a.kt)("p",null,"The project directory has the following files that are automatically generated:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"README.md")," contains the generated README from a template."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml")," represents project-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev")," directory stores the customized stack configuration:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/main.k")," stores configurations in the ",(0,a.kt)("inlineCode",{parentName:"li"},"dev")," stack."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/stack.yaml")," stores stack-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod")," stores stack-level dependencies."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod.lock")," stores version-sensitive dependencies.")))),(0,a.kt)("p",null,"In general, the ",(0,a.kt)("inlineCode",{parentName:"p"},".k")," files are the KCL source code that represents the application configuration, and the ",(0,a.kt)("inlineCode",{parentName:"p"},".yaml")," is the static configuration file that describes behavior at the project or stack level."),(0,a.kt)("h3",{id:"kclmod"},"kcl.mod"),(0,a.kt)("p",null,"There should be a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file generated automatically under the project directory. The ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file describes the dependency for the current project or stack. By default, it should contain a reference to the official ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},(0,a.kt)("inlineCode",{parentName:"a"},"catalog")," repository")," which holds some common model definitions that fits best practices. You can also create your own models library and reference that."),(0,a.kt)("h2",{id:"building"},"Building"),(0,a.kt)("p",null,"At this point, the project has been initialized with the Kusion built-in template.\nThe configuration is written in KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be built to get the final output."),(0,a.kt)("p",null,"Enter stack dir ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service/dev")," and build:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"cd simple-service/dev && kusion build\n")),(0,a.kt)("p",null,"The output is printed to ",(0,a.kt)("inlineCode",{parentName:"p"},"stdout")," by default. You can save it to a file using the ",(0,a.kt)("inlineCode",{parentName:"p"},"-o/--output")," flag when running ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),"."),(0,a.kt)("p",null,"The output of ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build")," is the ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/intent"},"intent")," format."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"For instructions on the kusion command line tool, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion -h"),", or refer to the tool's online ",(0,a.kt)("a",{parentName:"p",href:"../../reference/commands"},"documentation"),".")),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Build is now completed. We can apply the configuration as the next step. In the output from ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),", you can see 3 resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"a Namespace named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")),(0,a.kt)("li",{parentName:"ul"},"a Deployment named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace"),(0,a.kt)("li",{parentName:"ul"},"a Service named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld-private")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace")),(0,a.kt)("p",null,"Execute command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion apply\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Create\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS Create apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nCreate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 3 created, 0 updated, 0 deleted.\n")),(0,a.kt)("p",null,"After the configuration applying successfully, you can use the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," to check the actual status of these resources."),(0,a.kt)("p",null,"1\u3001 Check Namespace"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get ns\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME STATUS AGE\ndefault Active 117d\nsimple-service Active 38s\nkube-system Active 117d\n...\n")),(0,a.kt)("p",null,"2\u3001Check Deployment"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get deploy -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME READY UP-TO-DATE AVAILABLE AGE\nsimple-service-dev-helloworld 1/1 1 1 59s\n")),(0,a.kt)("p",null,"3\u3001Check Service"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get svc -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nsimple-service-dev-helloworld-private ClusterIP 10.98.89.104 80/TCP 79s\n")),(0,a.kt)("p",null,"4\u3001Validate app"),(0,a.kt)("p",null,"Using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," tool, forward native port ",(0,a.kt)("inlineCode",{parentName:"p"},"30000")," to the service port ",(0,a.kt)("inlineCode",{parentName:"p"},"80"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:80\n")),(0,a.kt)("p",null,"Open browser and visit ",(0,a.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),"\uff1a"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}u.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/0f1fb433.9718efdd.js b/assets/js/0f1fb433.9718efdd.js new file mode 100644 index 00000000000..340d661f4f7 --- /dev/null +++ b/assets/js/0f1fb433.9718efdd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1721],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Deploy Application",l={unversionedId:"kusion/user-guides/working-with-k8s/deploy-application",id:"version-v0.10/kusion/user-guides/working-with-k8s/deploy-application",title:"Deploy Application",description:"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/deploy-application",permalink:"/docs/kusion/user-guides/working-with-k8s/deploy-application",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/kusion/user-guides/cloud-resources/expose-service"},next:{title:"Configure Containers",permalink:"/docs/kusion/user-guides/working-with-k8s/container"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initializing",id:"initializing",level:2},{value:"Initializing workspace configuration",id:"initializing-workspace-configuration",level:2},{value:"Initializing application configuration",id:"initializing-application-configuration",level:2},{value:"kcl.mod",id:"kclmod",level:3},{value:"Building",id:"building",level:2},{value:"Applying",id:"applying",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"deploy-application"},"Deploy Application"),(0,a.kt)("p",null,"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.\nWe call the abstraction of application operation and maintenance configuration as ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", and its instance as ",(0,a.kt)("inlineCode",{parentName:"p"},"Application"),".\nIt is essentially a configuration model that describes an application. The complete definition can be seen ",(0,a.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/app-configuration"},"here"),"."),(0,a.kt)("p",null,"In production, the application generally includes minimally several k8s resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Namespace"),(0,a.kt)("li",{parentName:"ul"},"Deployment"),(0,a.kt)("li",{parentName:"ul"},"Service")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/"},"Namespace")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/services-networking/service/"},"Service")))),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Before we start, we need to complete the following steps:"),(0,a.kt)("p",null,"1\u3001Install Kusion"),(0,a.kt)("p",null,"We recommend using HomeBrew(Mac), Scoop(Windows), or an installation shell script to download and install Kusion.\nSee ",(0,a.kt)("a",{parentName:"p",href:"../../getting-started/install-kusion"},"Download and Install")," for more details."),(0,a.kt)("p",null,"2\u3001Running Kubernetes cluster"),(0,a.kt)("p",null,"There must be a running Kubernetes cluster and a ",(0,a.kt)("a",{parentName:"p",href:"https://Kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," command line tool.\nIf you don't have a cluster yet, you can use ",(0,a.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")," to start one of your own."),(0,a.kt)("h2",{id:"initializing"},"Initializing"),(0,a.kt)("p",null,"This guide is to deploy an app using Kusion, relying on the Kusion CLI and an existing a Kubernetes cluster."),(0,a.kt)("h2",{id:"initializing-workspace-configuration"},"Initializing workspace configuration"),(0,a.kt)("p",null,"In version 0.10.0, we have introduced the new concept of ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspaces"),', which is a logical layer whose configurations represent an opinionated set of defaults, often appointed by the platform team. In most cases workspaces are represented with an "environment" in traditional SDLC terms. These workspaces provide a means to separate the concerns between the application developers who wish to focus on business logic, and a group of platform engineers who wish to standardize the applications on the platform.'),(0,a.kt)("p",null,"Driven by the discipline of Platform Engineering, management of the workspaces, including create/updating/deleting workspaces and their configurations should be done by dedicated platform engineers in a large software organizations to facilitate a more mature and scalable collaboration pattern."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"More on the collaboration pattern can be found in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"design doc"),".")),(0,a.kt)("p",null,"However, if that does NOT apply to your scenario, e.g. if you work in a smaller org without platform engineers or if you are an individual developer, we wish Kusion can still be a value tool to have when delivering an application. In this guide, we are NOT distinctively highlighting the different roles or what the best practices entails (the design doc above has all that) but rather the steps needed to get Kusion tool to work."),(0,a.kt)("p",null,"As of version 0.10.0, workspace configurations in Kusion are managed on the local filesystem and their values are sourced from YAML files. Remotely-managed workspaces will be supported in future versions."),(0,a.kt)("p",null,"To initialize the workspace configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"~/playground$ touch ~/dev.yaml\n~/playground$ kusion workspace create dev -f ~/dev.yaml\ncreate workspace dev successfully\n")),(0,a.kt)("p",null,"To verify the workspace has been created properly:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"~/playground$ kusion workspace list\n- dev\n~/playground$ kusion workspace show dev\n{}\n")),(0,a.kt)("p",null,"Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"show")," command tells us the workspace configuration is currently empty, which is expected because we created the ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," workspace with an empty YAML file. An empty workspace configuration will suffice in some cases, where no platform configurations are needed."),(0,a.kt)("p",null,"We will progressively add more workspace configurations throughout this user guide."),(0,a.kt)("h2",{id:"initializing-application-configuration"},"Initializing application configuration"),(0,a.kt)("p",null,"Now that workspaces are properly initialized, we can begin by initializing the application configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion init\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command will prompt you to enter required parameters, such as project name, project description, image address, etc.\nYou can keep pressing ",(0,a.kt)("em",{parentName:"p"},"Enter")," all the way to use the default values."),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"\u2714 single-stack-sample A minimal kusion project of single stack\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n\u2714 Project Name: simple-service\n\u2714 AppName: helloworld\n\u2714 ProjectName: simple-service\nStack Config: dev\n\u2714 Image: gcr.io/google-samples/gb-frontend:v4\nCreated project 'simple-service'\n")),(0,a.kt)("p",null,"Now, we have successfully initialized a project ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," template, which contains a ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"AppName")," represents the name of the sample application, which is recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"main.k")," as the name of the ",(0,a.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," instance."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProjectName")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Project Name")," represent the name of the sample project, which is used as the generated folder name and then recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Image")," represents the image address of the application container.")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/project/overview"},"Project")," and ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,a.kt)("p",null,"The directory structure is as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"simple-service/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n2 directories, 6 files\n")),(0,a.kt)("p",null,"The project directory has the following files that are automatically generated:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"README.md")," contains the generated README from a template."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml")," represents project-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev")," directory stores the customized stack configuration:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/main.k")," stores configurations in the ",(0,a.kt)("inlineCode",{parentName:"li"},"dev")," stack."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/stack.yaml")," stores stack-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod")," stores stack-level dependencies."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod.lock")," stores version-sensitive dependencies.")))),(0,a.kt)("p",null,"In general, the ",(0,a.kt)("inlineCode",{parentName:"p"},".k")," files are the KCL source code that represents the application configuration, and the ",(0,a.kt)("inlineCode",{parentName:"p"},".yaml")," is the static configuration file that describes behavior at the project or stack level."),(0,a.kt)("h3",{id:"kclmod"},"kcl.mod"),(0,a.kt)("p",null,"There should be a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file generated automatically under the project directory. The ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file describes the dependency for the current project or stack. By default, it should contain a reference to the official ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},(0,a.kt)("inlineCode",{parentName:"a"},"catalog")," repository")," which holds some common model definitions that fits best practices. You can also create your own models library and reference that."),(0,a.kt)("h2",{id:"building"},"Building"),(0,a.kt)("p",null,"At this point, the project has been initialized with the Kusion built-in template.\nThe configuration is written in KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be built to get the final output."),(0,a.kt)("p",null,"Enter stack dir ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service/dev")," and build:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"cd simple-service/dev && kusion build\n")),(0,a.kt)("p",null,"The output is printed to ",(0,a.kt)("inlineCode",{parentName:"p"},"stdout")," by default. You can save it to a file using the ",(0,a.kt)("inlineCode",{parentName:"p"},"-o/--output")," flag when running ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),"."),(0,a.kt)("p",null,"The output of ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build")," is the ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/intent"},"intent")," format."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"For instructions on the kusion command line tool, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion -h"),", or refer to the tool's online ",(0,a.kt)("a",{parentName:"p",href:"../../reference/commands"},"documentation"),".")),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Build is now completed. We can apply the configuration as the next step. In the output from ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),", you can see 3 resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"a Namespace named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")),(0,a.kt)("li",{parentName:"ul"},"a Deployment named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace"),(0,a.kt)("li",{parentName:"ul"},"a Service named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld-private")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace")),(0,a.kt)("p",null,"Execute command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion apply\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Create\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS Create apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nCreate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 3 created, 0 updated, 0 deleted.\n")),(0,a.kt)("p",null,"After the configuration applying successfully, you can use the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," to check the actual status of these resources."),(0,a.kt)("p",null,"1\u3001 Check Namespace"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get ns\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME STATUS AGE\ndefault Active 117d\nsimple-service Active 38s\nkube-system Active 117d\n...\n")),(0,a.kt)("p",null,"2\u3001Check Deployment"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get deploy -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME READY UP-TO-DATE AVAILABLE AGE\nsimple-service-dev-helloworld 1/1 1 1 59s\n")),(0,a.kt)("p",null,"3\u3001Check Service"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get svc -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nsimple-service-dev-helloworld-private ClusterIP 10.98.89.104 80/TCP 79s\n")),(0,a.kt)("p",null,"4\u3001Validate app"),(0,a.kt)("p",null,"Using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," tool, forward native port ",(0,a.kt)("inlineCode",{parentName:"p"},"30000")," to the service port ",(0,a.kt)("inlineCode",{parentName:"p"},"80"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:80\n")),(0,a.kt)("p",null,"Open browser and visit ",(0,a.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),"\uff1a"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}u.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/0f9ab0f2.0598045f.js b/assets/js/0f9ab0f2.0598045f.js new file mode 100644 index 00000000000..4f45714afec --- /dev/null +++ b/assets/js/0f9ab0f2.0598045f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3129],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=s(n),u=a,k=p["".concat(c,".").concat(u)]||p[u]||m[u]||o;return n?r.createElement(k,l(l({ref:t},d),{},{components:n})):r.createElement(k,l({ref:t},d))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=p;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="common",i={unversionedId:"kusion/reference/model/catalog_models/internal/doc_common",id:"version-v0.9/kusion/reference/model/catalog_models/internal/doc_common",title:"common",description:"Schema WorkloadBase",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/doc_common.md",sourceDirName:"kusion/reference/model/catalog_models/internal",slug:"/kusion/reference/model/catalog_models/internal/doc_common",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/doc_common.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"probe",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe"},next:{title:"port",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port"}},c={},s=[{value:"Schema WorkloadBase",id:"schema-workloadbase",level:2},{value:"Attributes",id:"attributes",level:3}],d={toc:s};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"common"},"common"),(0,a.kt)("h2",{id:"schema-workloadbase"},"Schema WorkloadBase"),(0,a.kt)("p",null,"WorkloadBase defines set of attributes shared by different workload profile, e.g Service",(0,a.kt)("br",null),"and Job. You can inherit this Schema to reuse these common attributes."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"containers"),(0,a.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container#schema-container"},"container.Container"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"secrets")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret#schema-secret"},"secret.Secret"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0f9ab0f2.af2be204.js b/assets/js/0f9ab0f2.af2be204.js deleted file mode 100644 index a099b7d9033..00000000000 --- a/assets/js/0f9ab0f2.af2be204.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3129],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=s(n),u=a,k=p["".concat(c,".").concat(u)]||p[u]||m[u]||o;return n?r.createElement(k,l(l({ref:t},d),{},{components:n})):r.createElement(k,l({ref:t},d))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=p;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="common",i={unversionedId:"kusion/reference/model/catalog_models/internal/doc_common",id:"version-v0.9/kusion/reference/model/catalog_models/internal/doc_common",title:"common",description:"Schema WorkloadBase",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/doc_common.md",sourceDirName:"kusion/reference/model/catalog_models/internal",slug:"/kusion/reference/model/catalog_models/internal/doc_common",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/doc_common.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"probe",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe"},next:{title:"port",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port"}},c={},s=[{value:"Schema WorkloadBase",id:"schema-workloadbase",level:2},{value:"Attributes",id:"attributes",level:3}],d={toc:s};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"common"},"common"),(0,a.kt)("h2",{id:"schema-workloadbase"},"Schema WorkloadBase"),(0,a.kt)("p",null,"WorkloadBase defines set of attributes shared by different workload profile, e.g Service",(0,a.kt)("br",null),"and Job. You can inherit this Schema to reuse these common attributes."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"containers"),(0,a.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container#schema-container"},"container.Container"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"secrets")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret#schema-secret"},"secret.Secret"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1133e639.6d5e2522.js b/assets/js/1133e639.6d5e2522.js new file mode 100644 index 00000000000..de5b1700423 --- /dev/null +++ b/assets/js/1133e639.6d5e2522.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2494],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion apply",s={unversionedId:"kusion/reference/commands/kusion-apply",id:"version-v0.10/kusion/reference/commands/kusion-apply",title:"kusion apply",description:"Apply the operational intent of various resources to multiple runtimes",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-apply.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-apply",permalink:"/docs/kusion/reference/commands/kusion-apply",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-apply.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Commands",permalink:"/docs/kusion/reference/commands/"},next:{title:"kusion build",permalink:"/docs/kusion/reference/commands/kusion-build"}},p={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-apply"},"kusion apply"),(0,o.kt)("p",null,"Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Apply a series of resource changes within the stack."),(0,o.kt)("p",null," Create, update or delete resources according to the operational intent within a stack. By default, Kusion will generate an execution plan and prompt for your approval before performing any actions. You can review the plan details and make a decision to proceed with the actions or abort them."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion apply [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Apply with specified work directory\n kusion apply -w /path/to/workdir\n \n # Apply with specified arguments\n kusion apply -D name=test -D age=18\n \n # Apply with specified intent file\n kusion apply --intent-file intent.yaml\n \n # Apply with specifying intent file\n kusion apply --intent-file intent.yaml\n \n # Skip interactive approval of plan details before applying\n kusion apply --yes\n \n # Apply without output style and color\n kusion apply --no-style=true\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n --dry-run Preview the execution effect (always successful) without actually applying the changes\n -h, --help help for apply\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n --watch After creating/updating/deleting the requested object, watch for changes\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1133e639.928746f5.js b/assets/js/1133e639.928746f5.js deleted file mode 100644 index 88798edc9ec..00000000000 --- a/assets/js/1133e639.928746f5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2494],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion apply",s={unversionedId:"kusion/reference/commands/kusion-apply",id:"version-v0.10/kusion/reference/commands/kusion-apply",title:"kusion apply",description:"Apply the operational intent of various resources to multiple runtimes",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-apply.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-apply",permalink:"/docs/kusion/reference/commands/kusion-apply",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-apply.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Commands",permalink:"/docs/kusion/reference/commands/"},next:{title:"kusion build",permalink:"/docs/kusion/reference/commands/kusion-build"}},p={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-apply"},"kusion apply"),(0,o.kt)("p",null,"Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Apply a series of resource changes within the stack."),(0,o.kt)("p",null," Create, update or delete resources according to the operational intent within a stack. By default, Kusion will generate an execution plan and prompt for your approval before performing any actions. You can review the plan details and make a decision to proceed with the actions or abort them."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion apply [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Apply with specified work directory\n kusion apply -w /path/to/workdir\n \n # Apply with specified arguments\n kusion apply -D name=test -D age=18\n \n # Apply with specified intent file\n kusion apply --intent-file intent.yaml\n \n # Apply with specifying intent file\n kusion apply --intent-file intent.yaml\n \n # Skip interactive approval of plan details before applying\n kusion apply --yes\n \n # Apply without output style and color\n kusion apply --no-style=true\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n --dry-run Preview the execution effect (always successful) without actually applying the changes\n -h, --help help for apply\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n --watch After creating/updating/deleting the requested object, watch for changes\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/16d34038.81cad349.js b/assets/js/16d34038.81cad349.js deleted file mode 100644 index 852d4c86cd1..00000000000 --- a/assets/js/16d34038.81cad349.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5173],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(t),m=r,k=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return t?a.createElement(k,i(i({ref:n},p),{},{components:t})):a.createElement(k,i({ref:n},p))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var a=t(87462),r=(t(67294),t(3905));const o={id:"backend-configuration",sidebar_label:"Backend Configuration"},i="Backend Configuration",s={unversionedId:"kusion/concepts/backend-configuration",id:"kusion/concepts/backend-configuration",title:"Backend Configuration",description:"The backend configuration defines the place where Kusion stores its state data file. By default, Kusion uses the local type of backend to store the state on the local disk. While for team collaboration projects, the state can be stored on a remote backend, such as mysql, oss and s3 to allow multiple users access it.",source:"@site/docs/kusion/3-concepts/7-backend-configuration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/backend-configuration",permalink:"/docs/next/kusion/concepts/backend-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/7-backend-configuration.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"backend-configuration",sidebar_label:"Backend Configuration"},sidebar:"kusion",previous:{title:"Intent",permalink:"/docs/next/kusion/concepts/intent"},next:{title:"Configuration",permalink:"/docs/next/kusion/concepts/configuration"}},l={},c=[{value:"Configuring State Backend",id:"configuring-state-backend",level:2},{value:"Workspace Configuration File",id:"workspace-configuration-file",level:3},{value:"Environment Variables",id:"environment-variables",level:3},{value:"Command Line Parameters",id:"command-line-parameters",level:3},{value:"Configuration Combination",id:"configuration-combination",level:3},{value:"Available Backend",id:"available-backend",level:2},{value:"local",id:"local",level:3},{value:"mysql",id:"mysql",level:3},{value:"oss",id:"oss",level:3},{value:"s3",id:"s3",level:3}],p={toc:c};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"backend-configuration"},"Backend Configuration"),(0,r.kt)("p",null,"The backend configuration defines the place where Kusion stores its ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," data file. By default, Kusion uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," type of backend to store the state on the local disk. While for team collaboration projects, the state can be stored on a remote backend, such as ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"oss")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"s3")," to allow multiple users access it. "),(0,r.kt)("h2",{id:"configuring-state-backend"},"Configuring State Backend"),(0,r.kt)("p",null,"There are three ways to configure the backend:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"workspace configuration file"),(0,r.kt)("li",{parentName:"ul"},"environment variables"),(0,r.kt)("li",{parentName:"ul"},"command line parameters")),(0,r.kt)("h3",{id:"workspace-configuration-file"},"Workspace Configuration File"),(0,r.kt)("p",null,"Users can configure the storage of the state with the ",(0,r.kt)("inlineCode",{parentName:"p"},"backends")," block in the workspace file, where a map with the backend type as the key and the corresponding config items as the value to declare the backend configuration. Be attention, only one kind of backend type is allowed, more than one backend types are illegal."),(0,r.kt)("p",null,"The following gives an example of the backend configuration of ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"backends:\n mysql:\n dbName: \n user: \n password: \n host: \n port: \n")),(0,r.kt)("h3",{id:"environment-variables"},"Environment Variables"),(0,r.kt)("p",null,"For the sensitive information, Kusion supports configuring them by environment variables. Not all the configuration items are enabled, and the items differ from backend type. For example, users can configure mysql password by environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_BACKEND_MYSQL_PASSWORD"),"."),(0,r.kt)("h3",{id:"command-line-parameters"},"Command Line Parameters"),(0,r.kt)("p",null,"Users can specify the type of backend with the option ",(0,r.kt)("inlineCode",{parentName:"p"},"--backend-type"),", and configure the detailed information with ",(0,r.kt)("inlineCode",{parentName:"p"},"--backend-config")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"-C"),", for instance: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --backend-type mysql -C dbName= -C user= -C password= -C host= -C port=\n")),(0,r.kt)("h3",{id:"configuration-combination"},"Configuration Combination"),(0,r.kt)("p",null,"When more than one configuration methods are in use, Kusion will merge them to generate the whole backend configuration. Workspace configuration file, environment variables, command line parameter: the priority of these three configuration methods increases gradually. If there is no conflict of backend type, the latter will overlay the former by configuration items. If there is conflict of backend type, which only occurs between workspace configuration file and command line parameters, use the backend type specified by command line, and the configuration items from workspace are deprecated."),(0,r.kt)("h2",{id:"available-backend"},"Available Backend"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"local"),(0,r.kt)("li",{parentName:"ul"},"mysql"),(0,r.kt)("li",{parentName:"ul"},"oss"),(0,r.kt)("li",{parentName:"ul"},"s3")),(0,r.kt)("h3",{id:"local"},"local"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the local file system, which is suitable for local operations while not ideal for multi-user collaboration. "),(0,r.kt)("p",null,"There is no configuration items for ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," backend. When neither the workspace configuration file nor the command line parameters declare the backend configuration, Kusion by default uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"local"),"."),(0,r.kt)("h3",{id:"mysql"},"mysql"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," into a ",(0,r.kt)("strong",{parentName:"p"},"mysql database"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackends:\n mysql:\n dbName: \n user: \n password: \n host: \n port: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport KUSION_BACKEND_MYSQL_PASSWORD=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type mysql -C dbName= -C user= -C password= -C host= -C port=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"dbName - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the name of the database"),(0,r.kt)("li",{parentName:"ul"},"user - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the username of the database"),(0,r.kt)("li",{parentName:"ul"},"password - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the password of the database, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"KUSION_BACKEND_MYSQL_PASSWORD")),(0,r.kt)("li",{parentName:"ul"},"host - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the access address for the database"),(0,r.kt)("li",{parentName:"ul"},"port - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the port of the database")),(0,r.kt)("p",null,"Note that the table name in the database used by Kusion is ",(0,r.kt)("strong",{parentName:"p"},"state"),". Below is an example SQL statement for creating this table:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"CREATE TABLE `state` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',\n `tenant` varchar(100) DEFAULT NULL COMMENT 'tenant',\n `project` varchar(100) NOT NULL COMMENT 'project',\n `kusion_version` varchar(50) DEFAULT NULL COMMENT 'kusion version',\n `version` int(10) unsigned NOT NULL COMMENT 'current state format version\uff0cmay upgrade in the future',\n `serial` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'modification times for state\uff0ccan be used in concurrent control',\n `operator` varchar(100) DEFAULT NULL COMMENT 'last modifier',\n `resources` longtext DEFAULT NULL COMMENT 'state of the resources\uff0cjson array',\n `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'creation time',\n `modified_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'update time',\n `stack` varchar(100) DEFAULT NULL COMMENT 'stack',\n `cluster` varchar(100) DEFAULT NULL COMMENT 'logical isolation in a stack\uff0cusually clustername__cellname',\n PRIMARY KEY (`id`),\n UNIQUE KEY `uk_state_latest` (`tenant`, `project`, `stack`, `serial`, `cluster`),\n KEY `idx_tenant` (`tenant`),\n KEY `idx_project` (`project`),\n KEY `idx_kusion_version` (`kusion_version`),\n KEY `idx_version` (`version`),\n KEY `idx_create_time` (`create_time`),\n KEY `idx_modified_time` (`modified_time`),\n KEY `idx_stack` (`stack`),\n KEY `idx_cluster` (`cluster`)\n);\n")),(0,r.kt)("h3",{id:"oss"},"oss"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"oss")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,r.kt)("strong",{parentName:"p"},"Alicloud Object Storage Service (OSS)"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackends:\n oss:\n endpoint: \n bucket: \n accessKeyID: \n access-key-secret: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport OSS_ACCESS_KEY_ID=\nexport OSS_ACCESS_KEY_SECRET=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type oss -C endpoint= -C bucket= -C accessKeyID= -C accessKeySecret=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"endpoint - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the access endpoint for alicloud oss bucket"),(0,r.kt)("li",{parentName:"ul"},"bucket - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the alicloud oss bucket"),(0,r.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeyID, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_ID")),(0,r.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeySecret, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_SECRET"))),(0,r.kt)("h3",{id:"s3"},"s3"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"s3")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,r.kt)("strong",{parentName:"p"},"AWS Simple Storage Service (S3)"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackend: \n s3:\n endpoint: \n bucket: \n accessKeyID: \n access-key-secret: \n region: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport AWS_ACCESS_KEY_ID=\nexport AWS_SECRET_ACCESS_KEY=\nexport AWS_REGION=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type s3 -C endpoint= -C bucket= -C accessKeyID= -C accessKeySecret= -C region=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"endpoint - ",(0,r.kt)("inlineCode",{parentName:"li"},"optional")," specify the access endpoint for aws s3 bucket"),(0,r.kt)("li",{parentName:"ul"},"bucket - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the aws s3 bucket"),(0,r.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeyID, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_ACCESS_KEY_ID")),(0,r.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeySecret, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_SECRET_ACCESS_KEY")),(0,r.kt)("li",{parentName:"ul"},"region - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the region of aws s3 bucket, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_DEFAULT_REGION")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_REGION"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1759e3b3.75e8d80c.js b/assets/js/1759e3b3.75e8d80c.js deleted file mode 100644 index 2e4fdae4c21..00000000000 --- a/assets/js/1759e3b3.75e8d80c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1711],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(f,i(i({ref:t},c),{},{components:n})):a.createElement(f,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(87462),o=(n(67294),n(3905));const r={id:"kusion-vs-x"},i="Kusion vs Other Software",s={unversionedId:"kusion/what-is-kusion/kusion-vs-x",id:"version-v0.10/kusion/what-is-kusion/kusion-vs-x",title:"Kusion vs Other Software",description:"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.",source:"@site/versioned_docs/version-v0.10/kusion/1-what-is-kusion/2-kusion-vs-x.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/kusion/what-is-kusion/kusion-vs-x",permalink:"/docs/kusion/what-is-kusion/kusion-vs-x",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/1-what-is-kusion/2-kusion-vs-x.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kusion-vs-x"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/"},next:{title:"Install Kusion",permalink:"/docs/kusion/getting-started/install-kusion"}},p={},l=[],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-vs-other-software"},"Kusion vs Other Software"),(0,o.kt)("p",null,"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. GitOps (ArgoCD, FluxCD, etc.)")),(0,o.kt)("p",null,"According to the ",(0,o.kt)("a",{parentName:"p",href:"https://opengitops.dev/"},"open GitOps principles"),", GitOps systems typically have its desired state expressed declaratively, continuously observe actual system state and attempt to apply the desired state. In the design of Kusion toolchain, we refer to those principles but have no intention to reinvent any GitOps systems wheel. "),(0,o.kt)("p",null,"Kusion adopts your GitOps process and improves it with richness of features. The declarative ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," model can be used to express desired intent, once intent is declared ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands"},"Kusion CLI")," takes the role to make production match intent as safely as possible. "),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. PaaS (Heroku, Vercel, etc.)")),(0,o.kt)("p",null,"Kusion shares the same goal with traditional PaaS platforms to provide application delivery and management capabilities. The intuitive difference from the full functionality PaaS platforms is that Kusion is a client-side toolchain, not a complete PaaS platform. "),(0,o.kt)("p",null,"Also traditional PaaS platforms typically constrain the type of applications they can run but there is no such constrain for Kusion which means Kusion provides greater flexibility."),(0,o.kt)("p",null,"Kusion allows you to have platform-like features without the constraints of a traditional PaaS. However, Kusion is not attempting to replace any PaaS platforms, instead Kusion can be used to deploy to a platform such as Heroku."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. KubeVela")),(0,o.kt)("p",null,"KubeVela is a modern software delivery and management control plane. KubeVela makes it easier to deploy and operate applications on top of Kubernetes."),(0,o.kt)("p",null,"Kusion is not a control plane. Kusion is a client-side tool for describing application intent in a declarative way and providing consistent workflow to apply that desired state."),(0,o.kt)("p",null,"With proper Generator implementation, the target Spec of ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," can be ",(0,o.kt)("a",{parentName:"p",href:"https://kubevela.io/docs/getting-started/core-concept/"},"KubeVela Application"),' and Kusion can use KubeVela to satisfy the "apply" step.'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Helm")),(0,o.kt)("p",null,"The concept of Helm originates from the ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Package_manager"},"package management")," mechanism of the operating system. It is a package management tool based on templated YAML files and supports the execution and management of resources in the package. "),(0,o.kt)("p",null,"Kusion is not a package manager. Kusion naturally provides a superset of Helm capabilities with the modeled key-value pairs, so that developers can use Kusion directly as a programable alternative to avoid the pain of writing text templates. For users who have adopted Helm, the stack compilation results in Kusion can be packaged and used in Helm format."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Kubernetes")),(0,o.kt)("p",null,'Kubernetes(K8s) is a container scheduling and management runtime widely used around the world, an "operating system" core for containers, and a platform for building platforms. Above the Kubernetes API layer, Kusion aims to provide app-centric ',(0,o.kt)("strong",{parentName:"p"},"abstraction")," and unified ",(0,o.kt)("strong",{parentName:"p"},"workspace"),", better ",(0,o.kt)("strong",{parentName:"p"},"user experience")," and automation ",(0,o.kt)("strong",{parentName:"p"},"workflow"),", and helps developers build the app delivery model easily and collaboratively."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1759e3b3.c16cd999.js b/assets/js/1759e3b3.c16cd999.js new file mode 100644 index 00000000000..3333da183e8 --- /dev/null +++ b/assets/js/1759e3b3.c16cd999.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1711],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(f,i(i({ref:t},c),{},{components:n})):a.createElement(f,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(87462),o=(n(67294),n(3905));const r={id:"kusion-vs-x"},i="Kusion vs Other Software",s={unversionedId:"kusion/what-is-kusion/kusion-vs-x",id:"version-v0.10/kusion/what-is-kusion/kusion-vs-x",title:"Kusion vs Other Software",description:"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.",source:"@site/versioned_docs/version-v0.10/kusion/1-what-is-kusion/2-kusion-vs-x.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/kusion/what-is-kusion/kusion-vs-x",permalink:"/docs/kusion/what-is-kusion/kusion-vs-x",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/1-what-is-kusion/2-kusion-vs-x.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kusion-vs-x"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/"},next:{title:"Install Kusion",permalink:"/docs/kusion/getting-started/install-kusion"}},p={},l=[],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-vs-other-software"},"Kusion vs Other Software"),(0,o.kt)("p",null,"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. GitOps (ArgoCD, FluxCD, etc.)")),(0,o.kt)("p",null,"According to the ",(0,o.kt)("a",{parentName:"p",href:"https://opengitops.dev/"},"open GitOps principles"),", GitOps systems typically have its desired state expressed declaratively, continuously observe actual system state and attempt to apply the desired state. In the design of Kusion toolchain, we refer to those principles but have no intention to reinvent any GitOps systems wheel. "),(0,o.kt)("p",null,"Kusion adopts your GitOps process and improves it with richness of features. The declarative ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," model can be used to express desired intent, once intent is declared ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands"},"Kusion CLI")," takes the role to make production match intent as safely as possible. "),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. PaaS (Heroku, Vercel, etc.)")),(0,o.kt)("p",null,"Kusion shares the same goal with traditional PaaS platforms to provide application delivery and management capabilities. The intuitive difference from the full functionality PaaS platforms is that Kusion is a client-side toolchain, not a complete PaaS platform. "),(0,o.kt)("p",null,"Also traditional PaaS platforms typically constrain the type of applications they can run but there is no such constrain for Kusion which means Kusion provides greater flexibility."),(0,o.kt)("p",null,"Kusion allows you to have platform-like features without the constraints of a traditional PaaS. However, Kusion is not attempting to replace any PaaS platforms, instead Kusion can be used to deploy to a platform such as Heroku."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. KubeVela")),(0,o.kt)("p",null,"KubeVela is a modern software delivery and management control plane. KubeVela makes it easier to deploy and operate applications on top of Kubernetes."),(0,o.kt)("p",null,"Kusion is not a control plane. Kusion is a client-side tool for describing application intent in a declarative way and providing consistent workflow to apply that desired state."),(0,o.kt)("p",null,"With proper Generator implementation, the target Spec of ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," can be ",(0,o.kt)("a",{parentName:"p",href:"https://kubevela.io/docs/getting-started/core-concept/"},"KubeVela Application"),' and Kusion can use KubeVela to satisfy the "apply" step.'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Helm")),(0,o.kt)("p",null,"The concept of Helm originates from the ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Package_manager"},"package management")," mechanism of the operating system. It is a package management tool based on templated YAML files and supports the execution and management of resources in the package. "),(0,o.kt)("p",null,"Kusion is not a package manager. Kusion naturally provides a superset of Helm capabilities with the modeled key-value pairs, so that developers can use Kusion directly as a programable alternative to avoid the pain of writing text templates. For users who have adopted Helm, the stack compilation results in Kusion can be packaged and used in Helm format."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Kubernetes")),(0,o.kt)("p",null,'Kubernetes(K8s) is a container scheduling and management runtime widely used around the world, an "operating system" core for containers, and a platform for building platforms. Above the Kubernetes API layer, Kusion aims to provide app-centric ',(0,o.kt)("strong",{parentName:"p"},"abstraction")," and unified ",(0,o.kt)("strong",{parentName:"p"},"workspace"),", better ",(0,o.kt)("strong",{parentName:"p"},"user experience")," and automation ",(0,o.kt)("strong",{parentName:"p"},"workflow"),", and helps developers build the app delivery model easily and collaboratively."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/17b56dd8.d2019cde.js b/assets/js/17b56dd8.6a3aeb77.js similarity index 58% rename from assets/js/17b56dd8.d2019cde.js rename to assets/js/17b56dd8.6a3aeb77.js index 77f2c6a1390..55cd93c93fc 100644 --- a/assets/js/17b56dd8.d2019cde.js +++ b/assets/js/17b56dd8.6a3aeb77.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2687],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={},i="Controller Mesh",l={unversionedId:"ctrlmesh/intro/intro",id:"version-v0.10/ctrlmesh/intro/intro",title:"Controller Mesh",description:"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.",source:"@site/versioned_docs/version-v0.10/ctrlmesh/intro/intro.md",sourceDirName:"ctrlmesh/intro",slug:"/ctrlmesh/intro/",permalink:"/docs/ctrlmesh/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/intro/intro.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",next:{title:"Concepts",permalink:"/docs/ctrlmesh/concepts/"}},s={},c=[{value:"Key Features",id:"key-features",level:2},{value:"Architecture",id:"architecture",level:2}],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"controller-mesh"},"Controller Mesh"),(0,o.kt)("p",null,"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better."),(0,o.kt)("h2",{id:"key-features"},"Key Features"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Sharding"),": Through relevant configurations, Kubernetes single-point deployed operator applications can be flexibly shard deployed."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Canary upgrade"),": Depends on sharding, the controller instances can be updated in canary progress instead of updated in one time."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Circuit breaker and rate limiter"),": Not only Kubernetes operation requests, but also other external operation requests."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Multicluster routing and sharding")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"And more"),": Fault injection and Observability (Todo).")),(0,o.kt)("h2",{id:"architecture"},"Architecture"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"800",src:r(25723).Z})),(0,o.kt)("p",null,"Visit ",(0,o.kt)("a",{parentName:"p",href:"/docs/ctrlmesh/started/install"},"Installation")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/ctrlmesh/started/try"},"Quick Start"),"."))}u.isMDXComponent=!0},25723:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/mesh-arch-2-d82d2166bfeff6b5e56364fda483e9c2.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2687],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={},i="Controller Mesh",l={unversionedId:"ctrlmesh/intro/intro",id:"version-v0.10/ctrlmesh/intro/intro",title:"Controller Mesh",description:"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.",source:"@site/versioned_docs/version-v0.10/ctrlmesh/intro/intro.md",sourceDirName:"ctrlmesh/intro",slug:"/ctrlmesh/intro/",permalink:"/docs/ctrlmesh/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/intro/intro.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",next:{title:"Concepts",permalink:"/docs/ctrlmesh/concepts/"}},s={},c=[{value:"Key Features",id:"key-features",level:2},{value:"Architecture",id:"architecture",level:2}],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"controller-mesh"},"Controller Mesh"),(0,o.kt)("p",null,"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better."),(0,o.kt)("h2",{id:"key-features"},"Key Features"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Sharding"),": Through relevant configurations, Kubernetes single-point deployed operator applications can be flexibly shard deployed."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Canary upgrade"),": Depends on sharding, the controller instances can be updated in canary progress instead of updated in one time."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Circuit breaker and rate limiter"),": Not only Kubernetes operation requests, but also other external operation requests."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Multicluster routing and sharding")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"And more"),": Fault injection and Observability (Todo).")),(0,o.kt)("h2",{id:"architecture"},"Architecture"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"800",src:r(25723).Z})),(0,o.kt)("p",null,"Visit ",(0,o.kt)("a",{parentName:"p",href:"/docs/ctrlmesh/started/install"},"Installation")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/ctrlmesh/started/try"},"Quick Start"),"."))}u.isMDXComponent=!0},25723:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/mesh-arch-2-d82d2166bfeff6b5e56364fda483e9c2.png"}}]); \ No newline at end of file diff --git a/assets/js/1835c74b.2bfb8617.js b/assets/js/1835c74b.2bfb8617.js new file mode 100644 index 00000000000..1bc1ab979ca --- /dev/null +++ b/assets/js/1835c74b.2bfb8617.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7113],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(n),p=a,k=u["".concat(s,".").concat(p)]||u[p]||m[p]||o;return n?r.createElement(k,l(l({ref:t},d),{},{components:n})):r.createElement(k,l({ref:t},d))}));function p(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="common",i={unversionedId:"kusion/reference/modules/catalog-models/internal/common",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/common",title:"common",description:"Schema WorkloadBase",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal",slug:"/kusion/reference/modules/catalog-models/internal/common",permalink:"/docs/kusion/reference/modules/catalog-models/internal/common",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/kusion/reference/modules/catalog-models/database/postgres"},next:{title:"container",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/"}},s={},c=[{value:"Schema WorkloadBase",id:"schema-workloadbase",level:2},{value:"Attributes",id:"attributes",level:3}],d={toc:c};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"common"},"common"),(0,a.kt)("h2",{id:"schema-workloadbase"},"Schema WorkloadBase"),(0,a.kt)("p",null,"WorkloadBase defines set of attributes shared by different workload profile, e.g Service",(0,a.kt)("br",null),"and Job. You can inherit this Schema to reuse these common attributes."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"containers"),(0,a.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/#schema-container"},"container.Container"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"secrets")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/secret/#schema-secret"},"secret.Secret"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1835c74b.db986336.js b/assets/js/1835c74b.db986336.js deleted file mode 100644 index d683ea3f776..00000000000 --- a/assets/js/1835c74b.db986336.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7113],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(n),p=a,k=u["".concat(s,".").concat(p)]||u[p]||m[p]||o;return n?r.createElement(k,l(l({ref:t},d),{},{components:n})):r.createElement(k,l({ref:t},d))}));function p(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="common",i={unversionedId:"kusion/reference/modules/catalog-models/internal/common",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/common",title:"common",description:"Schema WorkloadBase",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal",slug:"/kusion/reference/modules/catalog-models/internal/common",permalink:"/docs/kusion/reference/modules/catalog-models/internal/common",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/kusion/reference/modules/catalog-models/database/postgres"},next:{title:"container",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/"}},s={},c=[{value:"Schema WorkloadBase",id:"schema-workloadbase",level:2},{value:"Attributes",id:"attributes",level:3}],d={toc:c};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"common"},"common"),(0,a.kt)("h2",{id:"schema-workloadbase"},"Schema WorkloadBase"),(0,a.kt)("p",null,"WorkloadBase defines set of attributes shared by different workload profile, e.g Service",(0,a.kt)("br",null),"and Job. You can inherit this Schema to reuse these common attributes."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"containers"),(0,a.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/#schema-container"},"container.Container"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"secrets")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/secret/#schema-secret"},"secret.Secret"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1898401f.c9ca6608.js b/assets/js/1898401f.c9ca6608.js deleted file mode 100644 index 5fca0ceead2..00000000000 --- a/assets/js/1898401f.c9ca6608.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9366],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=i,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(k,r(r({ref:t},p),{},{components:n})):a.createElement(k,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var a=n(87462),i=(n(67294),n(3905));const o={sidebar_position:1},r="Configuration File Overview",l={unversionedId:"kusion/config-walkthrough/overview",id:"version-v0.9/kusion/config-walkthrough/overview",title:"Configuration File Overview",description:"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/overview.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/overview",permalink:"/docs/v0.9/kusion/config-walkthrough/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/overview.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Intent",permalink:"/docs/v0.9/kusion/concepts/intent"},next:{title:"KCL Basics",permalink:"/docs/v0.9/kusion/config-walkthrough/kcl_basics"}},s={},c=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Directory Structure",id:"directory-structure",level:2},{value:"AppConfiguration Model",id:"appconfiguration-model",level:2},{value:"Authoring Configuration Files",id:"authoring-configuration-files",level:2},{value:"Identifying KCL file",id:"identifying-kcl-file",level:3},{value:"KCL Packages and Import",id:"kcl-packages-and-import",level:3},{value:"Understanding kcl.mod",id:"understanding-kclmod",level:3},{value:"Building Blocks",id:"building-blocks",level:3},{value:"Instantiating an application",id:"instantiating-an-application",level:3},{value:"Using kusion init",id:"using-kusion-init",level:3},{value:"Using references",id:"using-references",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configuration-file-overview"},"Configuration File Overview"),(0,i.kt)("p",null,"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure."),(0,i.kt)("p",null,"This documentation series walks you through the odds and ends of managing such configuration files."),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#directory-structure"},"Directory Structure")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#appconfiguration-model"},"AppConfiguration Model")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#identifying-kcl-file"},"Identifying KCL file")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#kcl-packages-and-import"},"KCL Packages and imports")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#understanding-kclmod"},"Understanding kcl.mod")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#building-blocks"},"Building blocks")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#instantiating-an-application"},"Instantiate an application")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-kusion-init"},"Using kusion init")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-references"},"Using references"))))),(0,i.kt)("h2",{id:"directory-structure"},"Directory Structure"),(0,i.kt)("p",null,"Kusion expects the configuration file to be placed in a certain directory structure because it might need some metadata (that is not stored in the application configuration itself) in order to proceed."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"See ",(0,i.kt)("a",{parentName:"p",href:"../concepts/glossary"},"Glossary")," for more details about Project and Stack.")),(0,i.kt)("p",null,"A sample multi-stack directory structure looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"~/playground$ tree multi-stack-project/\nmulti-stack-project/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 base\n\u2502\xa0\xa0 \u2514\u2500\u2500 base.k\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u251c\u2500\u2500 prod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n")),(0,i.kt)("p",null,"In general, the directory structure follows a hierarchy where the top-level is the project configurations, and the sub-directories represent stack-level configurations."),(0,i.kt)("p",null,"You may notice there is a ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory besides all the stacks. The ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory is not mandatory, but rather a place to store common configurations between different stacks. A common pattern we observed is to use stacks to represent different stages (dev, stage, prod, etc.) in the software development lifecycle, and/or different deployment targets (azure-eastus, aws-us-east-1, etc). A project can have as many stacks as needed."),(0,i.kt)("p",null,"In practice, the applications deployed into dev and prod might very likely end up with a similar set of configurations except a few fields such as the application image (dev might be on newer versions), resource requirements (prod might require more resources), etc."),(0,i.kt)("p",null,"As a general best practice, we recommend managing the common configurations in ",(0,i.kt)("inlineCode",{parentName:"p"},"base.k")," as much as possible to minimize duplicate code. We will cover how override works in ",(0,i.kt)("a",{parentName:"p",href:"base_override"},"Base and Override"),"."),(0,i.kt)("h2",{id:"appconfiguration-model"},"AppConfiguration Model"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is the out-of-the-box model we build that describes an application. It serves as the declarative intent for a given application."),(0,i.kt)("p",null,"The schema for ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is defined in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," repository. It is designed as a unified, application-centric model that encapsulates the comprehensive configuration details and in the meantime, hides the complexity of the infrastructure as much as possible."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," consists of multiple sub-components that each represent either the application workload itself, its dependencies, relevant workflows or operational expectations. We will deep dive into the details on how to author each of these elements in this upcoming documentation series."),(0,i.kt)("p",null,"For more details on the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/pull/420/files"},"design documentation - WIP"),"."),(0,i.kt)("h2",{id:"authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h3",{id:"identifying-kcl-file"},"Identifying KCL file"),(0,i.kt)("p",null,"KCL files are identified with ",(0,i.kt)("inlineCode",{parentName:"p"},".k")," suffix in the filename."),(0,i.kt)("h3",{id:"kcl-packages-and-import"},"KCL Packages and Import"),(0,i.kt)("p",null,"Similar to most modern General Programming Languages (GPLs), KCL packages are used to organize collections of related KCL source files into modular and re-usable units."),(0,i.kt)("p",null,"In the context of Kusion, we use KCL packages to define models that could best abstract the behavior of an application. Specifically, we provide an official out-of-the-box KCL package(will keep iterating) with the name ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog"),". When authoring an application configuration file, you can simply import the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package in the source code and use all the schemas (including AppConfiguration) defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("p",null,"Similarly, if the schemas in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package does not meet your needs, you can always fork it and make modifications, then import the modified package; or create a brand new package altogether and import it."),(0,i.kt)("p",null,"The Kusion ecosystem can be easily expanded in this manner."),(0,i.kt)("p",null,"An example of the import looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"### import from the official catalog package\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\n### import my own modified package\nimport my_own_catalog.models.schema.v1 as moc\nimport my_other_package.schema.v1.redis as myredis\n")),(0,i.kt)("p",null,"Take ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog.models.schema.v1.workload as wl")," as an example, the ",(0,i.kt)("inlineCode",{parentName:"p"},".models.schema.v1.workload")," part after ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog")," represents the relative path of a specific schema to import. In this case, the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas is defined under ",(0,i.kt)("inlineCode",{parentName:"p"},"models/schema/v1/workload")," directory in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("h3",{id:"understanding-kclmod"},"Understanding kcl.mod"),(0,i.kt)("p",null,"Much similar to the concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"go.mod"),", Kusion uses ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," as the source of truth to manage metadata (such as package name, dependencies, etc.) for the current package. Kusion will also auto-generate a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod.lock")," as the dependency lock file."),(0,i.kt)("p",null,"The most common usage for ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," is to manage the dependency of your application configurations. "),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Please note this ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," will be automatically generated if you are using ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," to initialize a project with a template. You will only need to modify this file if you are modifying the project metadata outside the initialization process, such as upgrading the dependency version or adding a new dependency altogether, etc.")),(0,i.kt)("p",null,"There are 3 sections in a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"package"),", representing the metadata for the current package."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"dependencies"),", describing the packages the current package depend on. Supports referencing either a git repository or an OCI artifact."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"profile"),", defining the behavior for Kusion. In the example below, it describes the list of files Kusion should look for when parsing the application configuration.")),(0,i.kt)("p",null,"An example of ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'[package]\nname = "multi-stack-project"\nedition = "0.5.0"\nversion = "0.1.0"\n\n[dependencies]\ncatalog = { git = "https://github.com/KusionStack/catalog.git", tag = "0.1.0" }\n# Uncomment the line below to use your own modified package\n# my-package = ghcr.io/kcl-lang/my-package\n\n[profile]\nentries = ["../base/base.k", "main.k"]\n')),(0,i.kt)("h3",{id:"building-blocks"},"Building Blocks"),(0,i.kt)("p",null,"Configuration files consist of building blocks that are made of instances of schemas. An ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance consists of several child schemas, most of which are optional. The only mandatory one is the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," instance. We will take a closer look in the ",(0,i.kt)("a",{parentName:"p",href:"workload"},"workload walkthrough"),". The order of the building blocks does NOT matter."),(0,i.kt)("p",null,"The major building blocks as of version ",(0,i.kt)("inlineCode",{parentName:"p"},"0.9.0"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n ...\n }\n ports: []\n secrets: {}\n }\n database: d.Database{}\n monitoring: m.Prometheus{}\n opsRule: t.OpsRule {}\n ...\n}\n')),(0,i.kt)("p",null,"We will deep dive into each one of the building blocks in this documentation series."),(0,i.kt)("h3",{id:"instantiating-an-application"},"Instantiating an application"),(0,i.kt)("p",null,"In Kusion's out-of-the-box experience, an application is identified with an instance of ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". You may have more than one application in the same project or stack."),(0,i.kt)("p",null,"Here's an example of a configuration that can be consumed by Kusion (assuming it is placed inside the proper directory structure that includes project and stack configurations, with a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," present):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\ngocity: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "gocity": c.Container {\n image = "howieyuen/gocity:latest"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 4000\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"Don't worry about what ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," stand for at the moment. We will deep dive into each one of them in this upcoming documentation series."),(0,i.kt)("h3",{id:"using-kusion-init"},"Using ",(0,i.kt)("inlineCode",{parentName:"h3"},"kusion init")),(0,i.kt)("p",null,"Kusion offers a ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," sub-command which initializes a new project using some pre-built templates, which saves you from the hassle to manually build the aforementioned directory structure that Kusion expects."),(0,i.kt)("p",null,"There is a built-in template ",(0,i.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," in the kusion binary that can be used offline. "),(0,i.kt)("p",null,"We also maintain a ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion-templates"},"kusion-templates repository")," that hosts a list of more comprehensive project scaffolds. You can access them via ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init --online")," command which requires connectivity to ",(0,i.kt)("inlineCode",{parentName:"p"},"github.com"),"."),(0,i.kt)("p",null,"The pre-built templates are meant to help you get off the ground quickly with some simple out-of-the-box examples. You can refer to the ",(0,i.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"QuickStart documentation")," for some step-by-step tutorials."),(0,i.kt)("h3",{id:"using-references"},"Using references"),(0,i.kt)("p",null,"The reference documentation for the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package is located in ",(0,i.kt)("a",{parentName:"p",href:"../reference/model/catalog_models/doc_app_configuration"},"Reference"),"."),(0,i.kt)("p",null,"If you are using the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package out of the box, the reference documentation provides a comprehensive view for each schema involved, including all the attribute names and description, their types, default value if any, and whether a particular attribute is required or not. There will also be an example attached to each schema reference."),(0,i.kt)("p",null,"We will also deep dive into some common examples in the upcoming sections."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1898401f.fa90b4f7.js b/assets/js/1898401f.fa90b4f7.js new file mode 100644 index 00000000000..b72e4bb2a17 --- /dev/null +++ b/assets/js/1898401f.fa90b4f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9366],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=i,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(k,r(r({ref:t},p),{},{components:n})):a.createElement(k,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var a=n(87462),i=(n(67294),n(3905));const o={sidebar_position:1},r="Configuration File Overview",l={unversionedId:"kusion/config-walkthrough/overview",id:"version-v0.9/kusion/config-walkthrough/overview",title:"Configuration File Overview",description:"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/overview.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/overview",permalink:"/docs/v0.9/kusion/config-walkthrough/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/overview.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Intent",permalink:"/docs/v0.9/kusion/concepts/intent"},next:{title:"KCL Basics",permalink:"/docs/v0.9/kusion/config-walkthrough/kcl_basics"}},s={},c=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Directory Structure",id:"directory-structure",level:2},{value:"AppConfiguration Model",id:"appconfiguration-model",level:2},{value:"Authoring Configuration Files",id:"authoring-configuration-files",level:2},{value:"Identifying KCL file",id:"identifying-kcl-file",level:3},{value:"KCL Packages and Import",id:"kcl-packages-and-import",level:3},{value:"Understanding kcl.mod",id:"understanding-kclmod",level:3},{value:"Building Blocks",id:"building-blocks",level:3},{value:"Instantiating an application",id:"instantiating-an-application",level:3},{value:"Using kusion init",id:"using-kusion-init",level:3},{value:"Using references",id:"using-references",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configuration-file-overview"},"Configuration File Overview"),(0,i.kt)("p",null,"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure."),(0,i.kt)("p",null,"This documentation series walks you through the odds and ends of managing such configuration files."),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#directory-structure"},"Directory Structure")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#appconfiguration-model"},"AppConfiguration Model")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#identifying-kcl-file"},"Identifying KCL file")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#kcl-packages-and-import"},"KCL Packages and imports")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#understanding-kclmod"},"Understanding kcl.mod")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#building-blocks"},"Building blocks")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#instantiating-an-application"},"Instantiate an application")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-kusion-init"},"Using kusion init")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-references"},"Using references"))))),(0,i.kt)("h2",{id:"directory-structure"},"Directory Structure"),(0,i.kt)("p",null,"Kusion expects the configuration file to be placed in a certain directory structure because it might need some metadata (that is not stored in the application configuration itself) in order to proceed."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"See ",(0,i.kt)("a",{parentName:"p",href:"../concepts/glossary"},"Glossary")," for more details about Project and Stack.")),(0,i.kt)("p",null,"A sample multi-stack directory structure looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"~/playground$ tree multi-stack-project/\nmulti-stack-project/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 base\n\u2502\xa0\xa0 \u2514\u2500\u2500 base.k\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u251c\u2500\u2500 prod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n")),(0,i.kt)("p",null,"In general, the directory structure follows a hierarchy where the top-level is the project configurations, and the sub-directories represent stack-level configurations."),(0,i.kt)("p",null,"You may notice there is a ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory besides all the stacks. The ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory is not mandatory, but rather a place to store common configurations between different stacks. A common pattern we observed is to use stacks to represent different stages (dev, stage, prod, etc.) in the software development lifecycle, and/or different deployment targets (azure-eastus, aws-us-east-1, etc). A project can have as many stacks as needed."),(0,i.kt)("p",null,"In practice, the applications deployed into dev and prod might very likely end up with a similar set of configurations except a few fields such as the application image (dev might be on newer versions), resource requirements (prod might require more resources), etc."),(0,i.kt)("p",null,"As a general best practice, we recommend managing the common configurations in ",(0,i.kt)("inlineCode",{parentName:"p"},"base.k")," as much as possible to minimize duplicate code. We will cover how override works in ",(0,i.kt)("a",{parentName:"p",href:"base_override"},"Base and Override"),"."),(0,i.kt)("h2",{id:"appconfiguration-model"},"AppConfiguration Model"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is the out-of-the-box model we build that describes an application. It serves as the declarative intent for a given application."),(0,i.kt)("p",null,"The schema for ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is defined in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," repository. It is designed as a unified, application-centric model that encapsulates the comprehensive configuration details and in the meantime, hides the complexity of the infrastructure as much as possible."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," consists of multiple sub-components that each represent either the application workload itself, its dependencies, relevant workflows or operational expectations. We will deep dive into the details on how to author each of these elements in this upcoming documentation series."),(0,i.kt)("p",null,"For more details on the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/pull/420/files"},"design documentation - WIP"),"."),(0,i.kt)("h2",{id:"authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h3",{id:"identifying-kcl-file"},"Identifying KCL file"),(0,i.kt)("p",null,"KCL files are identified with ",(0,i.kt)("inlineCode",{parentName:"p"},".k")," suffix in the filename."),(0,i.kt)("h3",{id:"kcl-packages-and-import"},"KCL Packages and Import"),(0,i.kt)("p",null,"Similar to most modern General Programming Languages (GPLs), KCL packages are used to organize collections of related KCL source files into modular and re-usable units."),(0,i.kt)("p",null,"In the context of Kusion, we use KCL packages to define models that could best abstract the behavior of an application. Specifically, we provide an official out-of-the-box KCL package(will keep iterating) with the name ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog"),". When authoring an application configuration file, you can simply import the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package in the source code and use all the schemas (including AppConfiguration) defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("p",null,"Similarly, if the schemas in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package does not meet your needs, you can always fork it and make modifications, then import the modified package; or create a brand new package altogether and import it."),(0,i.kt)("p",null,"The Kusion ecosystem can be easily expanded in this manner."),(0,i.kt)("p",null,"An example of the import looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"### import from the official catalog package\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\n### import my own modified package\nimport my_own_catalog.models.schema.v1 as moc\nimport my_other_package.schema.v1.redis as myredis\n")),(0,i.kt)("p",null,"Take ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog.models.schema.v1.workload as wl")," as an example, the ",(0,i.kt)("inlineCode",{parentName:"p"},".models.schema.v1.workload")," part after ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog")," represents the relative path of a specific schema to import. In this case, the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas is defined under ",(0,i.kt)("inlineCode",{parentName:"p"},"models/schema/v1/workload")," directory in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("h3",{id:"understanding-kclmod"},"Understanding kcl.mod"),(0,i.kt)("p",null,"Much similar to the concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"go.mod"),", Kusion uses ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," as the source of truth to manage metadata (such as package name, dependencies, etc.) for the current package. Kusion will also auto-generate a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod.lock")," as the dependency lock file."),(0,i.kt)("p",null,"The most common usage for ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," is to manage the dependency of your application configurations. "),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Please note this ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," will be automatically generated if you are using ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," to initialize a project with a template. You will only need to modify this file if you are modifying the project metadata outside the initialization process, such as upgrading the dependency version or adding a new dependency altogether, etc.")),(0,i.kt)("p",null,"There are 3 sections in a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"package"),", representing the metadata for the current package."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"dependencies"),", describing the packages the current package depend on. Supports referencing either a git repository or an OCI artifact."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"profile"),", defining the behavior for Kusion. In the example below, it describes the list of files Kusion should look for when parsing the application configuration.")),(0,i.kt)("p",null,"An example of ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'[package]\nname = "multi-stack-project"\nedition = "0.5.0"\nversion = "0.1.0"\n\n[dependencies]\ncatalog = { git = "https://github.com/KusionStack/catalog.git", tag = "0.1.0" }\n# Uncomment the line below to use your own modified package\n# my-package = ghcr.io/kcl-lang/my-package\n\n[profile]\nentries = ["../base/base.k", "main.k"]\n')),(0,i.kt)("h3",{id:"building-blocks"},"Building Blocks"),(0,i.kt)("p",null,"Configuration files consist of building blocks that are made of instances of schemas. An ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance consists of several child schemas, most of which are optional. The only mandatory one is the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," instance. We will take a closer look in the ",(0,i.kt)("a",{parentName:"p",href:"workload"},"workload walkthrough"),". The order of the building blocks does NOT matter."),(0,i.kt)("p",null,"The major building blocks as of version ",(0,i.kt)("inlineCode",{parentName:"p"},"0.9.0"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n ...\n }\n ports: []\n secrets: {}\n }\n database: d.Database{}\n monitoring: m.Prometheus{}\n opsRule: t.OpsRule {}\n ...\n}\n')),(0,i.kt)("p",null,"We will deep dive into each one of the building blocks in this documentation series."),(0,i.kt)("h3",{id:"instantiating-an-application"},"Instantiating an application"),(0,i.kt)("p",null,"In Kusion's out-of-the-box experience, an application is identified with an instance of ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". You may have more than one application in the same project or stack."),(0,i.kt)("p",null,"Here's an example of a configuration that can be consumed by Kusion (assuming it is placed inside the proper directory structure that includes project and stack configurations, with a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," present):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\ngocity: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "gocity": c.Container {\n image = "howieyuen/gocity:latest"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 4000\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"Don't worry about what ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," stand for at the moment. We will deep dive into each one of them in this upcoming documentation series."),(0,i.kt)("h3",{id:"using-kusion-init"},"Using ",(0,i.kt)("inlineCode",{parentName:"h3"},"kusion init")),(0,i.kt)("p",null,"Kusion offers a ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," sub-command which initializes a new project using some pre-built templates, which saves you from the hassle to manually build the aforementioned directory structure that Kusion expects."),(0,i.kt)("p",null,"There is a built-in template ",(0,i.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," in the kusion binary that can be used offline. "),(0,i.kt)("p",null,"We also maintain a ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion-templates"},"kusion-templates repository")," that hosts a list of more comprehensive project scaffolds. You can access them via ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init --online")," command which requires connectivity to ",(0,i.kt)("inlineCode",{parentName:"p"},"github.com"),"."),(0,i.kt)("p",null,"The pre-built templates are meant to help you get off the ground quickly with some simple out-of-the-box examples. You can refer to the ",(0,i.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"QuickStart documentation")," for some step-by-step tutorials."),(0,i.kt)("h3",{id:"using-references"},"Using references"),(0,i.kt)("p",null,"The reference documentation for the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package is located in ",(0,i.kt)("a",{parentName:"p",href:"../reference/model/catalog_models/doc_app_configuration"},"Reference"),"."),(0,i.kt)("p",null,"If you are using the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package out of the box, the reference documentation provides a comprehensive view for each schema involved, including all the attribute names and description, their types, default value if any, and whether a particular attribute is required or not. There will also be an example attached to each schema reference."),(0,i.kt)("p",null,"We will also deep dive into some common examples in the upcoming sections."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1961a063.3d193eee.js b/assets/js/1961a063.3d193eee.js new file mode 100644 index 00000000000..ef162041bfa --- /dev/null +++ b/assets/js/1961a063.3d193eee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8025],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(t),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||i;return t?o.createElement(k,r(r({ref:n},c),{},{components:t})):o.createElement(k,r({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,r=new Array(i);r[0]=d;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),a=(t(67294),t(3905));const i={},r="Workload",l={unversionedId:"kusion/configuration-walkthrough/workload",id:"kusion/configuration-walkthrough/workload",title:"Workload",description:"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application.",source:"@site/docs/kusion/4-configuration-walkthrough/4-workload.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/workload",permalink:"/docs/next/kusion/configuration-walkthrough/workload",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/4-workload.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Base and Override",permalink:"/docs/next/kusion/configuration-walkthrough/base-override"},next:{title:"Application Networking",permalink:"/docs/next/kusion/configuration-walkthrough/networking"}},p={},s=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Import",id:"import",level:2},{value:"Types of Workloads",id:"types-of-workloads",level:2},{value:"Configure containers",id:"configure-containers",level:2},{value:"Application image",id:"application-image",level:3},{value:"Resource Requirements",id:"resource-requirements",level:3},{value:"Health Probes",id:"health-probes",level:3},{value:"Lifecycle Hooks",id:"lifecycle-hooks",level:3},{value:"Create Files",id:"create-files",level:3},{value:"Customize container initialization",id:"customize-container-initialization",level:3},{value:"Configure Replicas",id:"configure-replicas",level:2},{value:"Differences between Service and Job",id:"differences-between-service-and-job",level:2},{value:"Exposure",id:"exposure",level:3},{value:"Job Schedule",id:"job-schedule",level:3},{value:"Workload References",id:"workload-references",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"workload"},"Workload"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application."),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," maps to an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance 1:1. If there are more than one workload, they should be considered different applications."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#import"},"Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#types-of-workloads"},"Types of workloads")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-containers"},"Configure containers"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#application-image"},"Application image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#resource-requirements"},"Resource Requirements")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#health-probes"},"Health Probes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#lifecycle-hooks"},"Lifecycle Hooks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#create-files"},"Create Files")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#customize-container-initialization"},"Customize container initialization")))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-replicas"},"Configure Replicas")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#differences-between-service-and-job"},"Differences between Service and Job")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#workload-references"},"Workload References"))),(0,a.kt)("h2",{id:"import"},"Import"),(0,a.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport kam.v1.workload.container.probe as p\nimport kam.v1.workload.container.lifecycle as lc\n")),(0,a.kt)("h2",{id:"types-of-workloads"},"Types of Workloads"),(0,a.kt)("p",null,"There are currently two types of workloads:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Service"),', representing a long-running, scalable workload type that should "never" go down and respond to short-lived latency-sensitive requests. This workload type is commonly used for web applications and services that expose APIs.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Job"),", representing batch tasks that take from a few seconds to days to complete and then stop. These are commonly used for batch processing that is less sensitive to short-term performance fluctuations.")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {}\n}\n")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Job {}\n}\n")),(0,a.kt)("p",null,"Of course, the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instances above is not sufficient to describe an application. We still need to provide more details in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," section."),(0,a.kt)("h2",{id:"configure-containers"},"Configure containers"),(0,a.kt)("p",null,"Kusion is built on top of cloud-native philosophies. One of which is that applications should run as loosely coupled microservices on abstract and self-contained software units, such as containers."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute in a workload instance is used to define the behavior for the containers that run application workload. The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is a map, from the name of the container to the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog.models.schema.v1.workload.container.Container")," Object which includes the container configurations."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The name of the container is in the context of the configuration file, so you could refer to it later. It's not referring to the name of the container in the Kubernetes cluster (or any other runtime).")),(0,a.kt)("p",null,"Everything defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is considered an application container, as opposed to a sidecar container. Sidecar containers will be introduced in a different attribute in a future version."),(0,a.kt)("p",null,"In most of the cases, only one application container is needed. Ideally, we recommend mapping an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance to a microservice in the microservice terminology."),(0,a.kt)("p",null,"We will walk through the details of configuring a container using an example of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type."),(0,a.kt)("p",null,"To add an application container:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n }\n }\n}\n')),(0,a.kt)("h3",{id:"application-image"},"Application image"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application image to run. This is the only required field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"To specify an application image:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n }\n }\n}\n')),(0,a.kt)("h3",{id:"resource-requirements"},"Resource Requirements"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"resources")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application resource requirements such as cpu and memory."),(0,a.kt)("p",null,"You can specify an upper limit (which maps to resource limits only) or a range as the resource requirements (which maps to resource requests and limits in Kubernetes)."),(0,a.kt)("p",null,"To specify an upper bound (only resource limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"To specify a range (both resource requests and limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # Sets requests to cpu=250m and memory=256Mi\n # Sets limits to cpu=500m and memory=512Mi\n resources: {\n "cpu": "250m-500m"\n "memory": "256Mi-512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"health-probes"},"Health Probes"),(0,a.kt)("p",null,"There are three types of ",(0,a.kt)("inlineCode",{parentName:"p"},"Probe")," defined in a ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"livenessProbe")," - used to determine if the container is healthy and running"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"readinessProbe")," - used to determine if the container is ready to accept traffic"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," - used to determine if the container has started properly. Liveness and readiness probes don't start until ",(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," succeeds. Commonly used for containers that takes a while to start")),(0,a.kt)("p",null,"The probes are optional. You can only have one Probe of each kind for a given ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),"."),(0,a.kt)("p",null,"To configure a ",(0,a.kt)("inlineCode",{parentName:"p"},"Http")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"readinessProbe")," that probes the health via HTTP request and a ",(0,a.kt)("inlineCode",{parentName:"p"},"Exec")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"livenessProbe")," which executes a command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure an Http type readiness probe at /healthz\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "/healthz"\n }\n initialDelaySeconds: 10\n timeoutSeconds: 5\n periodSeconds: 15\n successThreshold: 3\n failureThreshold: 1\n }\n # Configure an Exec type liveness probe that executes probe.sh\n livenessProbe: p.Probe {\n probeHandler: p.Exec {\n command: ["probe.sh"]\n }\n initialDelaySeconds: 10\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"lifecycle-hooks"},"Lifecycle Hooks"),(0,a.kt)("p",null,"You can also configure lifecycle hooks that triggers in response to container lifecycle events such as liveness/startup probe failure, preemption, resource contention, etc."),(0,a.kt)("p",null,"There are two types that is currently supported:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PreStop")," - triggers before the container is terminated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PostStart")," - triggers after the container is initialized.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure lifecycle hooks\n lifecycle: lc.Lifecycle {\n # Configures an Exec type pre-stop hook that executes preStop.sh\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n # Configures an Http type pre-stop hook at /post-start\n postStart: p.Http {\n url: "/post-start"\n }\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"create-files"},"Create Files"),(0,a.kt)("p",null,"You can also create files on-demand during the container initialization."),(0,a.kt)("p",null,"To create a custom file and mount it to ",(0,a.kt)("inlineCode",{parentName:"p"},"/home/admin/my-file")," when the container starts:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n # Creates a file during container startup\n files: {\n "/home/admin/my-file": c.FileSpec {\n content: "some file contents"\n mode: "0777"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"customize-container-initialization"},"Customize container initialization"),(0,a.kt)("p",null,"You can also customize the container entrypoint via ",(0,a.kt)("inlineCode",{parentName:"p"},"command"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"args"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"workingDir"),". These should ",(0,a.kt)("strong",{parentName:"p"},"most likely not be required"),". In most of the cases, the entrypoint details should be baked into the application image itself."),(0,a.kt)("p",null,"To customize the container entrypoint:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # This command will overwrite the entrypoint set in the image Dockerfile\n command: ["/usr/local/bin/my-init-script.sh"]\n # Extra arguments append to command defined above\n args: [\n "--log-dir=/home/my-app/logs"\n "--timeout=60s"\n ]\n # Run the command as defined above, in the directory "/tmp"\n workingDir: "/tmp"\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"configure-replicas"},"Configure Replicas"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"replicas")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance describes the number of identical copies to run at the same time. It is generally recommended to have multiple replicas in production environments to eliminate any single point of failure. In Kubernetes, this corresponds to the ",(0,a.kt)("inlineCode",{parentName:"p"},"spec.replicas")," field in the relevant workload manifests."),(0,a.kt)("p",null,"To configure a workload to have a replica count of 3:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n replicas: 3\n # ...\n }\n # ...\n}\n")),(0,a.kt)("h2",{id:"differences-between-service-and-job"},"Differences between Service and Job"),(0,a.kt)("p",null,"The two types of workloads, namely ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),", share a majority of the attributes with some minor differences."),(0,a.kt)("h3",{id:"exposure"},"Exposure"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," usually represents a long-running, scalable workload that responds to short-lived latency-sensitive requests and never go down. Hence, a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," has an additional attribute that determines how it is exposed and can be accessed. A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," does NOT have the option to be exposed. We will explore more in the ",(0,a.kt)("a",{parentName:"p",href:"networking"},"application networking walkthrough"),"."),(0,a.kt)("h3",{id:"job-schedule"},"Job Schedule"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," can be configured to run in a recurring manner. In this case, the job will have a cron-format schedule that represents its recurring schedule."),(0,a.kt)("p",null,"To configure a job to run at 21:00 every night:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myjob: ac.AppConfiguration {\n workload: wl.Job {\n containers: {\n "busybox": c.Container {\n image: "busybox:1.28"\n # Run the following command as defined\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n # Run every hour.\n schedule: "0 * * * *"\n }\n}\n')),(0,a.kt)("h2",{id:"workload-references"},"Workload References"),(0,a.kt)("p",null,"You can find workload references ",(0,a.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/workload/service"},"here"),"."),(0,a.kt)("p",null,"You can find workload schema source ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/schema/v1/workload"},"here"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1961a063.a8071215.js b/assets/js/1961a063.a8071215.js deleted file mode 100644 index b9e5920a4be..00000000000 --- a/assets/js/1961a063.a8071215.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8025],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(t),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||i;return t?o.createElement(k,r(r({ref:n},c),{},{components:t})):o.createElement(k,r({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,r=new Array(i);r[0]=d;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),a=(t(67294),t(3905));const i={},r="Workload",l={unversionedId:"kusion/configuration-walkthrough/workload",id:"kusion/configuration-walkthrough/workload",title:"Workload",description:"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application.",source:"@site/docs/kusion/4-configuration-walkthrough/4-workload.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/workload",permalink:"/docs/next/kusion/configuration-walkthrough/workload",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/4-workload.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Base and Override",permalink:"/docs/next/kusion/configuration-walkthrough/base-override"},next:{title:"Application Networking",permalink:"/docs/next/kusion/configuration-walkthrough/networking"}},p={},s=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Import",id:"import",level:2},{value:"Types of Workloads",id:"types-of-workloads",level:2},{value:"Configure containers",id:"configure-containers",level:2},{value:"Application image",id:"application-image",level:3},{value:"Resource Requirements",id:"resource-requirements",level:3},{value:"Health Probes",id:"health-probes",level:3},{value:"Lifecycle Hooks",id:"lifecycle-hooks",level:3},{value:"Create Files",id:"create-files",level:3},{value:"Customize container initialization",id:"customize-container-initialization",level:3},{value:"Configure Replicas",id:"configure-replicas",level:2},{value:"Differences between Service and Job",id:"differences-between-service-and-job",level:2},{value:"Exposure",id:"exposure",level:3},{value:"Job Schedule",id:"job-schedule",level:3},{value:"Workload References",id:"workload-references",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"workload"},"Workload"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application."),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," maps to an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance 1:1. If there are more than one workload, they should be considered different applications."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#import"},"Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#types-of-workloads"},"Types of workloads")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-containers"},"Configure containers"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#application-image"},"Application image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#resource-requirements"},"Resource Requirements")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#health-probes"},"Health Probes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#lifecycle-hooks"},"Lifecycle Hooks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#create-files"},"Create Files")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#customize-container-initialization"},"Customize container initialization")))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-replicas"},"Configure Replicas")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#differences-between-service-and-job"},"Differences between Service and Job")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#workload-references"},"Workload References"))),(0,a.kt)("h2",{id:"import"},"Import"),(0,a.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport kam.v1.workload.container.probe as p\nimport kam.v1.workload.container.lifecycle as lc\n")),(0,a.kt)("h2",{id:"types-of-workloads"},"Types of Workloads"),(0,a.kt)("p",null,"There are currently two types of workloads:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Service"),', representing a long-running, scalable workload type that should "never" go down and respond to short-lived latency-sensitive requests. This workload type is commonly used for web applications and services that expose APIs.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Job"),", representing batch tasks that take from a few seconds to days to complete and then stop. These are commonly used for batch processing that is less sensitive to short-term performance fluctuations.")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {}\n}\n")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Job {}\n}\n")),(0,a.kt)("p",null,"Of course, the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instances above is not sufficient to describe an application. We still need to provide more details in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," section."),(0,a.kt)("h2",{id:"configure-containers"},"Configure containers"),(0,a.kt)("p",null,"Kusion is built on top of cloud-native philosophies. One of which is that applications should run as loosely coupled microservices on abstract and self-contained software units, such as containers."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute in a workload instance is used to define the behavior for the containers that run application workload. The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is a map, from the name of the container to the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog.models.schema.v1.workload.container.Container")," Object which includes the container configurations."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The name of the container is in the context of the configuration file, so you could refer to it later. It's not referring to the name of the container in the Kubernetes cluster (or any other runtime).")),(0,a.kt)("p",null,"Everything defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is considered an application container, as opposed to a sidecar container. Sidecar containers will be introduced in a different attribute in a future version."),(0,a.kt)("p",null,"In most of the cases, only one application container is needed. Ideally, we recommend mapping an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance to a microservice in the microservice terminology."),(0,a.kt)("p",null,"We will walk through the details of configuring a container using an example of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type."),(0,a.kt)("p",null,"To add an application container:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n }\n }\n}\n')),(0,a.kt)("h3",{id:"application-image"},"Application image"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application image to run. This is the only required field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"To specify an application image:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n }\n }\n}\n')),(0,a.kt)("h3",{id:"resource-requirements"},"Resource Requirements"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"resources")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application resource requirements such as cpu and memory."),(0,a.kt)("p",null,"You can specify an upper limit (which maps to resource limits only) or a range as the resource requirements (which maps to resource requests and limits in Kubernetes)."),(0,a.kt)("p",null,"To specify an upper bound (only resource limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"To specify a range (both resource requests and limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # Sets requests to cpu=250m and memory=256Mi\n # Sets limits to cpu=500m and memory=512Mi\n resources: {\n "cpu": "250m-500m"\n "memory": "256Mi-512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"health-probes"},"Health Probes"),(0,a.kt)("p",null,"There are three types of ",(0,a.kt)("inlineCode",{parentName:"p"},"Probe")," defined in a ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"livenessProbe")," - used to determine if the container is healthy and running"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"readinessProbe")," - used to determine if the container is ready to accept traffic"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," - used to determine if the container has started properly. Liveness and readiness probes don't start until ",(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," succeeds. Commonly used for containers that takes a while to start")),(0,a.kt)("p",null,"The probes are optional. You can only have one Probe of each kind for a given ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),"."),(0,a.kt)("p",null,"To configure a ",(0,a.kt)("inlineCode",{parentName:"p"},"Http")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"readinessProbe")," that probes the health via HTTP request and a ",(0,a.kt)("inlineCode",{parentName:"p"},"Exec")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"livenessProbe")," which executes a command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure an Http type readiness probe at /healthz\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "/healthz"\n }\n initialDelaySeconds: 10\n timeoutSeconds: 5\n periodSeconds: 15\n successThreshold: 3\n failureThreshold: 1\n }\n # Configure an Exec type liveness probe that executes probe.sh\n livenessProbe: p.Probe {\n probeHandler: p.Exec {\n command: ["probe.sh"]\n }\n initialDelaySeconds: 10\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"lifecycle-hooks"},"Lifecycle Hooks"),(0,a.kt)("p",null,"You can also configure lifecycle hooks that triggers in response to container lifecycle events such as liveness/startup probe failure, preemption, resource contention, etc."),(0,a.kt)("p",null,"There are two types that is currently supported:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PreStop")," - triggers before the container is terminated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PostStart")," - triggers after the container is initialized.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure lifecycle hooks\n lifecycle: lc.Lifecycle {\n # Configures an Exec type pre-stop hook that executes preStop.sh\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n # Configures an Http type pre-stop hook at /post-start\n postStart: p.Http {\n url: "/post-start"\n }\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"create-files"},"Create Files"),(0,a.kt)("p",null,"You can also create files on-demand during the container initialization."),(0,a.kt)("p",null,"To create a custom file and mount it to ",(0,a.kt)("inlineCode",{parentName:"p"},"/home/admin/my-file")," when the container starts:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n # Creates a file during container startup\n files: {\n "/home/admin/my-file": c.FileSpec {\n content: "some file contents"\n mode: "0777"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"customize-container-initialization"},"Customize container initialization"),(0,a.kt)("p",null,"You can also customize the container entrypoint via ",(0,a.kt)("inlineCode",{parentName:"p"},"command"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"args"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"workingDir"),". These should ",(0,a.kt)("strong",{parentName:"p"},"most likely not be required"),". In most of the cases, the entrypoint details should be baked into the application image itself."),(0,a.kt)("p",null,"To customize the container entrypoint:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # This command will overwrite the entrypoint set in the image Dockerfile\n command: ["/usr/local/bin/my-init-script.sh"]\n # Extra arguments append to command defined above\n args: [\n "--log-dir=/home/my-app/logs"\n "--timeout=60s"\n ]\n # Run the command as defined above, in the directory "/tmp"\n workingDir: "/tmp"\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"configure-replicas"},"Configure Replicas"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"replicas")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance describes the number of identical copies to run at the same time. It is generally recommended to have multiple replicas in production environments to eliminate any single point of failure. In Kubernetes, this corresponds to the ",(0,a.kt)("inlineCode",{parentName:"p"},"spec.replicas")," field in the relevant workload manifests."),(0,a.kt)("p",null,"To configure a workload to have a replica count of 3:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n replicas: 3\n # ...\n }\n # ...\n}\n")),(0,a.kt)("h2",{id:"differences-between-service-and-job"},"Differences between Service and Job"),(0,a.kt)("p",null,"The two types of workloads, namely ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),", share a majority of the attributes with some minor differences."),(0,a.kt)("h3",{id:"exposure"},"Exposure"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," usually represents a long-running, scalable workload that responds to short-lived latency-sensitive requests and never go down. Hence, a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," has an additional attribute that determines how it is exposed and can be accessed. A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," does NOT have the option to be exposed. We will explore more in the ",(0,a.kt)("a",{parentName:"p",href:"networking"},"application networking walkthrough"),"."),(0,a.kt)("h3",{id:"job-schedule"},"Job Schedule"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," can be configured to run in a recurring manner. In this case, the job will have a cron-format schedule that represents its recurring schedule."),(0,a.kt)("p",null,"To configure a job to run at 21:00 every night:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myjob: ac.AppConfiguration {\n workload: wl.Job {\n containers: {\n "busybox": c.Container {\n image: "busybox:1.28"\n # Run the following command as defined\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n # Run every hour.\n schedule: "0 * * * *"\n }\n}\n')),(0,a.kt)("h2",{id:"workload-references"},"Workload References"),(0,a.kt)("p",null,"You can find workload references ",(0,a.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/workload/service"},"here"),"."),(0,a.kt)("p",null,"You can find workload schema source ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/schema/v1/workload"},"here"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1977b36b.5f3b145b.js b/assets/js/1977b36b.5f3b145b.js deleted file mode 100644 index f2549cd5412..00000000000 --- a/assets/js/1977b36b.5f3b145b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5434],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var m=a.createContext({}),p=function(t){var e=a.useContext(m),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},s=function(t){var e=p(t.components);return a.createElement(m.Provider,{value:e},t.children)},d={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(n),c=r,k=u["".concat(m,".").concat(c)]||u[c]||d[c]||l;return n?a.createElement(k,i(i({ref:e},s),{},{components:n})):a.createElement(k,i({ref:e},s))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var p=2;p{n.r(e),n.d(e,{assets:()=>m,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:1},i="Installation",o={unversionedId:"ctrlmesh/started/install",id:"version-v0.10/ctrlmesh/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.10/ctrlmesh/started/install.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/install",permalink:"/docs/ctrlmesh/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/started/install.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Concepts",permalink:"/docs/ctrlmesh/concepts/"},next:{title:"Try a Sample",permalink:"/docs/ctrlmesh/started/try"}},m={},p=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3}],s={toc:p};function d(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Upgrade to the latest version \n$ helm upgrade ctrlmesh kusionstack/ctrlmesh \n\n# Uninstall\n$ helm uninstall ctrlmesh\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for controller mesh installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"ctrlmesh"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.replicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of ctrlmesh-manager deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"2"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-manager"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"512Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-proxy image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-proxy"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-init image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-init"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-init"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"shardingGroupVersionKinds")),(0,r.kt)("td",{parentName:"tr",align:null},"Sharding resource lists\uff08yaml\uff09"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("p",null,"config ",(0,r.kt)("inlineCode",{parentName:"p"},"groupVersionKinds")," in file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"ctrlmesh.kusionstack.io/v1alpha1:\n- '*'\nv1:\n- Pod\n- PersistentVolumeClaim\n- Service\n- ConfigMap\n- Endpoint\napps/v1:\n- StatefulSet\n- ReplicaSet\n- ControllerRevision\n")),(0,r.kt)("p",null,"Specify each parameter using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--set key=value")," argument to ",(0,r.kt)("inlineCode",{parentName:"p"},"helm install")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1977b36b.b788d5ee.js b/assets/js/1977b36b.b788d5ee.js new file mode 100644 index 00000000000..17229f547be --- /dev/null +++ b/assets/js/1977b36b.b788d5ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5434],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var m=a.createContext({}),p=function(t){var e=a.useContext(m),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},s=function(t){var e=p(t.components);return a.createElement(m.Provider,{value:e},t.children)},d={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(n),c=r,k=u["".concat(m,".").concat(c)]||u[c]||d[c]||l;return n?a.createElement(k,i(i({ref:e},s),{},{components:n})):a.createElement(k,i({ref:e},s))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var p=2;p{n.r(e),n.d(e,{assets:()=>m,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:1},i="Installation",o={unversionedId:"ctrlmesh/started/install",id:"version-v0.10/ctrlmesh/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.10/ctrlmesh/started/install.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/install",permalink:"/docs/ctrlmesh/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/started/install.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Concepts",permalink:"/docs/ctrlmesh/concepts/"},next:{title:"Try a Sample",permalink:"/docs/ctrlmesh/started/try"}},m={},p=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3}],s={toc:p};function d(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Upgrade to the latest version \n$ helm upgrade ctrlmesh kusionstack/ctrlmesh \n\n# Uninstall\n$ helm uninstall ctrlmesh\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for controller mesh installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"ctrlmesh"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.replicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of ctrlmesh-manager deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"2"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-manager"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"512Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-proxy image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-proxy"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-init image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-init"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-init"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"shardingGroupVersionKinds")),(0,r.kt)("td",{parentName:"tr",align:null},"Sharding resource lists\uff08yaml\uff09"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("p",null,"config ",(0,r.kt)("inlineCode",{parentName:"p"},"groupVersionKinds")," in file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"ctrlmesh.kusionstack.io/v1alpha1:\n- '*'\nv1:\n- Pod\n- PersistentVolumeClaim\n- Service\n- ConfigMap\n- Endpoint\napps/v1:\n- StatefulSet\n- ReplicaSet\n- ControllerRevision\n")),(0,r.kt)("p",null,"Specify each parameter using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--set key=value")," argument to ",(0,r.kt)("inlineCode",{parentName:"p"},"helm install")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/19d6fa9a.79cacd6f.js b/assets/js/19d6fa9a.79cacd6f.js new file mode 100644 index 00000000000..63a3b472e6b --- /dev/null +++ b/assets/js/19d6fa9a.79cacd6f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6987],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),d=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=d(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=r,k=u["".concat(p,".").concat(m)]||u[m]||c[m]||l;return n?a.createElement(k,o(o({ref:t},s),{},{components:n})):a.createElement(k,o({ref:t},s))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=u;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="probe",i={unversionedId:"kusion/reference/modules/catalog-models/internal/container/probe/probe",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/container/probe/probe",title:"probe",description:"Schema Probe",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/probe",slug:"/kusion/reference/modules/catalog-models/internal/container/probe/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"lifecycle",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/"},next:{title:"port",permalink:"/docs/kusion/reference/modules/catalog-models/internal/network/port"}},p={},d=[{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3}],s={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"probe"},"probe"),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/19d6fa9a.f1b43ebd.js b/assets/js/19d6fa9a.f1b43ebd.js deleted file mode 100644 index 56f82bd9056..00000000000 --- a/assets/js/19d6fa9a.f1b43ebd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6987],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),d=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=d(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=r,k=u["".concat(p,".").concat(m)]||u[m]||c[m]||l;return n?a.createElement(k,o(o({ref:t},s),{},{components:n})):a.createElement(k,o({ref:t},s))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=u;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="probe",i={unversionedId:"kusion/reference/modules/catalog-models/internal/container/probe/probe",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/container/probe/probe",title:"probe",description:"Schema Probe",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/probe",slug:"/kusion/reference/modules/catalog-models/internal/container/probe/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"lifecycle",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/"},next:{title:"port",permalink:"/docs/kusion/reference/modules/catalog-models/internal/network/port"}},p={},d=[{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3}],s={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"probe"},"probe"),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/19fdd558.96c6b381.js b/assets/js/19fdd558.e466c4e8.js similarity index 57% rename from assets/js/19fdd558.96c6b381.js rename to assets/js/19fdd558.e466c4e8.js index d4038b53c2e..338c98756b6 100644 --- a/assets/js/19fdd558.96c6b381.js +++ b/assets/js/19fdd558.e466c4e8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1061],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),f=u(r),d=o,m=f["".concat(p,".").concat(d)]||f[d]||l[d]||a;return r?n.createElement(m,s(s({ref:t},c),{},{components:r})):n.createElement(m,s({ref:t},c))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=f;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var n=r(87462),o=(r(67294),r(3905));const a={},s="FAQ",i={unversionedId:"kusion/support/support",id:"version-v0.9/kusion/support/support",title:"FAQ",description:"KusionStack frequently asked questions.",source:"@site/versioned_docs/version-v0.9/kusion/support/support.md",sourceDirName:"kusion/support",slug:"/kusion/support/",permalink:"/docs/v0.9/kusion/support/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/support/support.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Roadmap",permalink:"/docs/v0.9/kusion/reference/roadmap"},next:{title:"Installation",permalink:"/docs/v0.9/kusion/support/install-error"}},p={},u=[],c={toc:u};function l(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"),(0,o.kt)("p",null,"KusionStack frequently asked questions."))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1061],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),f=u(r),d=o,m=f["".concat(p,".").concat(d)]||f[d]||l[d]||a;return r?n.createElement(m,i(i({ref:t},c),{},{components:r})):n.createElement(m,i({ref:t},c))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var n=r(87462),o=(r(67294),r(3905));const a={},i="FAQ",s={unversionedId:"kusion/support/support",id:"version-v0.9/kusion/support/support",title:"FAQ",description:"KusionStack frequently asked questions.",source:"@site/versioned_docs/version-v0.9/kusion/support/support.md",sourceDirName:"kusion/support",slug:"/kusion/support/",permalink:"/docs/v0.9/kusion/support/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/support/support.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Roadmap",permalink:"/docs/v0.9/kusion/reference/roadmap"},next:{title:"Installation",permalink:"/docs/v0.9/kusion/support/install-error"}},p={},u=[],c={toc:u};function l(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"),(0,o.kt)("p",null,"KusionStack frequently asked questions."))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1a5f5579.53344ca5.js b/assets/js/1a5f5579.4a2ddacb.js similarity index 61% rename from assets/js/1a5f5579.53344ca5.js rename to assets/js/1a5f5579.4a2ddacb.js index ecbd861f0cf..f74bc2b6e4f 100644 --- a/assets/js/1a5f5579.53344ca5.js +++ b/assets/js/1a5f5579.4a2ddacb.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2253],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),u=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||i;return n?o.createElement(f,a(a({ref:t},l),{},{components:n})):o.createElement(f,a({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:1},a="Community",s={unversionedId:"community/intro/intro",id:"version-v0.9/community/intro/intro",title:"Community",description:"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.",source:"@site/versioned_docs/version-v0.9/community/intro/intro.md",sourceDirName:"community/intro",slug:"/community/intro/",permalink:"/docs/v0.9/community/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/community/intro/intro.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"community"},c={},u=[],l={toc:u};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"community"},"Community"),(0,r.kt)("p",null,"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/orgs/KusionStack/discussions"},"Open a New Discussions on GitHub")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://app.slack.com/client/T03H6QE4VL0/setup-welcome"},"Contact Us on Slack"))),(0,r.kt)("h1",{id:"contributing"},"CONTRIBUTING"),(0,r.kt)("p",null,"We appreciate contributions from the community! To submit changes, please refer to the contributing file in the corresponding KusionStack repository. The files are available at the following links:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion/blob/main/docs/contributing.md"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/operating/blob/main/docs/contributing.md"},"Operating"))),(0,r.kt)("h1",{id:"code-of-conduct"},"CODE OF CONDUCT"),(0,r.kt)("p",null,"To make KusionStack a welcoming and harassment-free experience for everyone, we follow the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/CODE_OF_CONDUCT.md"},"KusionStack Code of Conduct"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2253],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),u=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||i;return n?o.createElement(f,a(a({ref:t},l),{},{components:n})):o.createElement(f,a({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:1},a="Community",s={unversionedId:"community/intro/intro",id:"version-v0.9/community/intro/intro",title:"Community",description:"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.",source:"@site/versioned_docs/version-v0.9/community/intro/intro.md",sourceDirName:"community/intro",slug:"/community/intro/",permalink:"/docs/v0.9/community/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/community/intro/intro.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"community"},c={},u=[],l={toc:u};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"community"},"Community"),(0,r.kt)("p",null,"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/orgs/KusionStack/discussions"},"Open a New Discussions on GitHub")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://app.slack.com/client/T03H6QE4VL0/setup-welcome"},"Contact Us on Slack"))),(0,r.kt)("h1",{id:"contributing"},"CONTRIBUTING"),(0,r.kt)("p",null,"We appreciate contributions from the community! To submit changes, please refer to the contributing file in the corresponding KusionStack repository. The files are available at the following links:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion/blob/main/docs/contributing.md"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/operating/blob/main/docs/contributing.md"},"Operating"))),(0,r.kt)("h1",{id:"code-of-conduct"},"CODE OF CONDUCT"),(0,r.kt)("p",null,"To make KusionStack a welcoming and harassment-free experience for everyone, we follow the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/CODE_OF_CONDUCT.md"},"KusionStack Code of Conduct"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1aa0cc2e.a3da7fb0.js b/assets/js/1aa0cc2e.a3da7fb0.js deleted file mode 100644 index 9bb00a10db9..00000000000 --- a/assets/js/1aa0cc2e.a3da7fb0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[38],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Deploy Application",l={unversionedId:"kusion/user-guides/working-with-k8s/deploy-application",id:"kusion/user-guides/working-with-k8s/deploy-application",title:"Deploy Application",description:"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/deploy-application",permalink:"/docs/next/kusion/user-guides/working-with-k8s/deploy-application",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/next/kusion/user-guides/cloud-resources/expose-service"},next:{title:"Configure Containers",permalink:"/docs/next/kusion/user-guides/working-with-k8s/container"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initializing",id:"initializing",level:2},{value:"Initializing workspace configuration",id:"initializing-workspace-configuration",level:2},{value:"Initializing application configuration",id:"initializing-application-configuration",level:2},{value:"kcl.mod",id:"kclmod",level:3},{value:"Building",id:"building",level:2},{value:"Applying",id:"applying",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"deploy-application"},"Deploy Application"),(0,a.kt)("p",null,"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.\nWe call the abstraction of application operation and maintenance configuration as ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", and its instance as ",(0,a.kt)("inlineCode",{parentName:"p"},"Application"),".\nIt is essentially a configuration model that describes an application. The complete definition can be seen ",(0,a.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/app-configuration"},"here"),"."),(0,a.kt)("p",null,"In production, the application generally includes minimally several k8s resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Namespace"),(0,a.kt)("li",{parentName:"ul"},"Deployment"),(0,a.kt)("li",{parentName:"ul"},"Service")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/"},"Namespace")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/services-networking/service/"},"Service")))),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Before we start, we need to complete the following steps:"),(0,a.kt)("p",null,"1\u3001Install Kusion"),(0,a.kt)("p",null,"We recommend using HomeBrew(Mac), Scoop(Windows), or an installation shell script to download and install Kusion.\nSee ",(0,a.kt)("a",{parentName:"p",href:"../../getting-started/install-kusion"},"Download and Install")," for more details."),(0,a.kt)("p",null,"2\u3001Running Kubernetes cluster"),(0,a.kt)("p",null,"There must be a running Kubernetes cluster and a ",(0,a.kt)("a",{parentName:"p",href:"https://Kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," command line tool.\nIf you don't have a cluster yet, you can use ",(0,a.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")," to start one of your own."),(0,a.kt)("h2",{id:"initializing"},"Initializing"),(0,a.kt)("p",null,"This guide is to deploy an app using Kusion, relying on the Kusion CLI and an existing a Kubernetes cluster."),(0,a.kt)("h2",{id:"initializing-workspace-configuration"},"Initializing workspace configuration"),(0,a.kt)("p",null,"In version 0.10.0, we have introduced the new concept of ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspaces"),', which is a logical layer whose configurations represent an opinionated set of defaults, often appointed by the platform team. In most cases workspaces are represented with an "environment" in traditional SDLC terms. These workspaces provide a means to separate the concerns between the application developers who wish to focus on business logic, and a group of platform engineers who wish to standardize the applications on the platform.'),(0,a.kt)("p",null,"Driven by the discipline of Platform Engineering, management of the workspaces, including create/updating/deleting workspaces and their configurations should be done by dedicated platform engineers in a large software organizations to facilitate a more mature and scalable collaboration pattern."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"More on the collaboration pattern can be found in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"design doc"),".")),(0,a.kt)("p",null,"However, if that does NOT apply to your scenario, e.g. if you work in a smaller org without platform engineers or if you are an individual developer, we wish Kusion can still be a value tool to have when delivering an application. In this guide, we are NOT distinctively highlighting the different roles or what the best practices entails (the design doc above has all that) but rather the steps needed to get Kusion tool to work."),(0,a.kt)("p",null,"As of version 0.10.0, workspace configurations in Kusion are managed on the local filesystem and their values are sourced from YAML files. Remotely-managed workspaces will be supported in future versions."),(0,a.kt)("p",null,"To initialize the workspace configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"~/playground$ touch ~/dev.yaml\n~/playground$ kusion workspace create dev -f ~/dev.yaml\ncreate workspace dev successfully\n")),(0,a.kt)("p",null,"To verify the workspace has been created properly:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"~/playground$ kusion workspace list\n- dev\n~/playground$ kusion workspace show dev\n{}\n")),(0,a.kt)("p",null,"Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"show")," command tells us the workspace configuration is currently empty, which is expected because we created the ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," workspace with an empty YAML file. An empty workspace configuration will suffice in some cases, where no platform configurations are needed."),(0,a.kt)("p",null,"We will progressively add more workspace configurations throughout this user guide."),(0,a.kt)("h2",{id:"initializing-application-configuration"},"Initializing application configuration"),(0,a.kt)("p",null,"Now that workspaces are properly initialized, we can begin by initializing the application configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion init\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command will prompt you to enter required parameters, such as project name, project description, image address, etc.\nYou can keep pressing ",(0,a.kt)("em",{parentName:"p"},"Enter")," all the way to use the default values."),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"\u2714 single-stack-sample A minimal kusion project of single stack\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n\u2714 Project Name: simple-service\n\u2714 AppName: helloworld\n\u2714 ProjectName: simple-service\nStack Config: dev\n\u2714 Image: gcr.io/google-samples/gb-frontend:v4\nCreated project 'simple-service'\n")),(0,a.kt)("p",null,"Now, we have successfully initialized a project ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," template, which contains a ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"AppName")," represents the name of the sample application, which is recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"main.k")," as the name of the ",(0,a.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," instance."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProjectName")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Project Name")," represent the name of the sample project, which is used as the generated folder name and then recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Image")," represents the image address of the application container.")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/project/overview"},"Project")," and ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,a.kt)("p",null,"The directory structure is as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"simple-service/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n2 directories, 6 files\n")),(0,a.kt)("p",null,"The project directory has the following files that are automatically generated:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"README.md")," contains the generated README from a template."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml")," represents project-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev")," directory stores the customized stack configuration:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/main.k")," stores configurations in the ",(0,a.kt)("inlineCode",{parentName:"li"},"dev")," stack."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/stack.yaml")," stores stack-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod")," stores stack-level dependencies."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod.lock")," stores version-sensitive dependencies.")))),(0,a.kt)("p",null,"In general, the ",(0,a.kt)("inlineCode",{parentName:"p"},".k")," files are the KCL source code that represents the application configuration, and the ",(0,a.kt)("inlineCode",{parentName:"p"},".yaml")," is the static configuration file that describes behavior at the project or stack level."),(0,a.kt)("h3",{id:"kclmod"},"kcl.mod"),(0,a.kt)("p",null,"There should be a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file generated automatically under the project directory. The ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file describes the dependency for the current project or stack. By default, it should contain a reference to the official ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},(0,a.kt)("inlineCode",{parentName:"a"},"catalog")," repository")," which holds some common model definitions that fits best practices. You can also create your own models library and reference that."),(0,a.kt)("h2",{id:"building"},"Building"),(0,a.kt)("p",null,"At this point, the project has been initialized with the Kusion built-in template.\nThe configuration is written in KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be built to get the final output."),(0,a.kt)("p",null,"Enter stack dir ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service/dev")," and build:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"cd simple-service/dev && kusion build\n")),(0,a.kt)("p",null,"The output is printed to ",(0,a.kt)("inlineCode",{parentName:"p"},"stdout")," by default. You can save it to a file using the ",(0,a.kt)("inlineCode",{parentName:"p"},"-o/--output")," flag when running ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),"."),(0,a.kt)("p",null,"The output of ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build")," is the ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/intent"},"intent")," format."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"For instructions on the kusion command line tool, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion -h"),", or refer to the tool's online ",(0,a.kt)("a",{parentName:"p",href:"../../reference/commands"},"documentation"),".")),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Build is now completed. We can apply the configuration as the next step. In the output from ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),", you can see 3 resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"a Namespace named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")),(0,a.kt)("li",{parentName:"ul"},"a Deployment named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace"),(0,a.kt)("li",{parentName:"ul"},"a Service named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld-private")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace")),(0,a.kt)("p",null,"Execute command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion apply\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Create\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS Create apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nCreate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 3 created, 0 updated, 0 deleted.\n")),(0,a.kt)("p",null,"After the configuration applying successfully, you can use the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," to check the actual status of these resources."),(0,a.kt)("p",null,"1\u3001 Check Namespace"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get ns\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME STATUS AGE\ndefault Active 117d\nsimple-service Active 38s\nkube-system Active 117d\n...\n")),(0,a.kt)("p",null,"2\u3001Check Deployment"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get deploy -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME READY UP-TO-DATE AVAILABLE AGE\nsimple-service-dev-helloworld 1/1 1 1 59s\n")),(0,a.kt)("p",null,"3\u3001Check Service"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get svc -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nsimple-service-dev-helloworld-private ClusterIP 10.98.89.104 80/TCP 79s\n")),(0,a.kt)("p",null,"4\u3001Validate app"),(0,a.kt)("p",null,"Using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," tool, forward native port ",(0,a.kt)("inlineCode",{parentName:"p"},"30000")," to the service port ",(0,a.kt)("inlineCode",{parentName:"p"},"80"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:80\n")),(0,a.kt)("p",null,"Open browser and visit ",(0,a.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),"\uff1a"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}u.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/1aa0cc2e.da5c9ea0.js b/assets/js/1aa0cc2e.da5c9ea0.js new file mode 100644 index 00000000000..dd3984fd2b7 --- /dev/null +++ b/assets/js/1aa0cc2e.da5c9ea0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[38],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Deploy Application",l={unversionedId:"kusion/user-guides/working-with-k8s/deploy-application",id:"kusion/user-guides/working-with-k8s/deploy-application",title:"Deploy Application",description:"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/deploy-application",permalink:"/docs/next/kusion/user-guides/working-with-k8s/deploy-application",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/next/kusion/user-guides/cloud-resources/expose-service"},next:{title:"Configure Containers",permalink:"/docs/next/kusion/user-guides/working-with-k8s/container"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initializing",id:"initializing",level:2},{value:"Initializing workspace configuration",id:"initializing-workspace-configuration",level:2},{value:"Initializing application configuration",id:"initializing-application-configuration",level:2},{value:"kcl.mod",id:"kclmod",level:3},{value:"Building",id:"building",level:2},{value:"Applying",id:"applying",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"deploy-application"},"Deploy Application"),(0,a.kt)("p",null,"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.\nWe call the abstraction of application operation and maintenance configuration as ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", and its instance as ",(0,a.kt)("inlineCode",{parentName:"p"},"Application"),".\nIt is essentially a configuration model that describes an application. The complete definition can be seen ",(0,a.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/app-configuration"},"here"),"."),(0,a.kt)("p",null,"In production, the application generally includes minimally several k8s resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Namespace"),(0,a.kt)("li",{parentName:"ul"},"Deployment"),(0,a.kt)("li",{parentName:"ul"},"Service")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/"},"Namespace")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/services-networking/service/"},"Service")))),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Before we start, we need to complete the following steps:"),(0,a.kt)("p",null,"1\u3001Install Kusion"),(0,a.kt)("p",null,"We recommend using HomeBrew(Mac), Scoop(Windows), or an installation shell script to download and install Kusion.\nSee ",(0,a.kt)("a",{parentName:"p",href:"../../getting-started/install-kusion"},"Download and Install")," for more details."),(0,a.kt)("p",null,"2\u3001Running Kubernetes cluster"),(0,a.kt)("p",null,"There must be a running Kubernetes cluster and a ",(0,a.kt)("a",{parentName:"p",href:"https://Kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," command line tool.\nIf you don't have a cluster yet, you can use ",(0,a.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")," to start one of your own."),(0,a.kt)("h2",{id:"initializing"},"Initializing"),(0,a.kt)("p",null,"This guide is to deploy an app using Kusion, relying on the Kusion CLI and an existing a Kubernetes cluster."),(0,a.kt)("h2",{id:"initializing-workspace-configuration"},"Initializing workspace configuration"),(0,a.kt)("p",null,"In version 0.10.0, we have introduced the new concept of ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspaces"),', which is a logical layer whose configurations represent an opinionated set of defaults, often appointed by the platform team. In most cases workspaces are represented with an "environment" in traditional SDLC terms. These workspaces provide a means to separate the concerns between the application developers who wish to focus on business logic, and a group of platform engineers who wish to standardize the applications on the platform.'),(0,a.kt)("p",null,"Driven by the discipline of Platform Engineering, management of the workspaces, including create/updating/deleting workspaces and their configurations should be done by dedicated platform engineers in a large software organizations to facilitate a more mature and scalable collaboration pattern."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"More on the collaboration pattern can be found in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"design doc"),".")),(0,a.kt)("p",null,"However, if that does NOT apply to your scenario, e.g. if you work in a smaller org without platform engineers or if you are an individual developer, we wish Kusion can still be a value tool to have when delivering an application. In this guide, we are NOT distinctively highlighting the different roles or what the best practices entails (the design doc above has all that) but rather the steps needed to get Kusion tool to work."),(0,a.kt)("p",null,"As of version 0.10.0, workspace configurations in Kusion are managed on the local filesystem and their values are sourced from YAML files. Remotely-managed workspaces will be supported in future versions."),(0,a.kt)("p",null,"To initialize the workspace configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"~/playground$ touch ~/dev.yaml\n~/playground$ kusion workspace create dev -f ~/dev.yaml\ncreate workspace dev successfully\n")),(0,a.kt)("p",null,"To verify the workspace has been created properly:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"~/playground$ kusion workspace list\n- dev\n~/playground$ kusion workspace show dev\n{}\n")),(0,a.kt)("p",null,"Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"show")," command tells us the workspace configuration is currently empty, which is expected because we created the ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," workspace with an empty YAML file. An empty workspace configuration will suffice in some cases, where no platform configurations are needed."),(0,a.kt)("p",null,"We will progressively add more workspace configurations throughout this user guide."),(0,a.kt)("h2",{id:"initializing-application-configuration"},"Initializing application configuration"),(0,a.kt)("p",null,"Now that workspaces are properly initialized, we can begin by initializing the application configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion init\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command will prompt you to enter required parameters, such as project name, project description, image address, etc.\nYou can keep pressing ",(0,a.kt)("em",{parentName:"p"},"Enter")," all the way to use the default values."),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"\u2714 single-stack-sample A minimal kusion project of single stack\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n\u2714 Project Name: simple-service\n\u2714 AppName: helloworld\n\u2714 ProjectName: simple-service\nStack Config: dev\n\u2714 Image: gcr.io/google-samples/gb-frontend:v4\nCreated project 'simple-service'\n")),(0,a.kt)("p",null,"Now, we have successfully initialized a project ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," template, which contains a ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"AppName")," represents the name of the sample application, which is recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"main.k")," as the name of the ",(0,a.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," instance."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProjectName")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Project Name")," represent the name of the sample project, which is used as the generated folder name and then recorded in the generated ",(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Image")," represents the image address of the application container.")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/project/overview"},"Project")," and ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,a.kt)("p",null,"The directory structure is as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"simple-service/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n2 directories, 6 files\n")),(0,a.kt)("p",null,"The project directory has the following files that are automatically generated:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"README.md")," contains the generated README from a template."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"project.yaml")," represents project-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev")," directory stores the customized stack configuration:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/main.k")," stores configurations in the ",(0,a.kt)("inlineCode",{parentName:"li"},"dev")," stack."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/stack.yaml")," stores stack-level configurations."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod")," stores stack-level dependencies."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod.lock")," stores version-sensitive dependencies.")))),(0,a.kt)("p",null,"In general, the ",(0,a.kt)("inlineCode",{parentName:"p"},".k")," files are the KCL source code that represents the application configuration, and the ",(0,a.kt)("inlineCode",{parentName:"p"},".yaml")," is the static configuration file that describes behavior at the project or stack level."),(0,a.kt)("h3",{id:"kclmod"},"kcl.mod"),(0,a.kt)("p",null,"There should be a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file generated automatically under the project directory. The ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file describes the dependency for the current project or stack. By default, it should contain a reference to the official ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},(0,a.kt)("inlineCode",{parentName:"a"},"catalog")," repository")," which holds some common model definitions that fits best practices. You can also create your own models library and reference that."),(0,a.kt)("h2",{id:"building"},"Building"),(0,a.kt)("p",null,"At this point, the project has been initialized with the Kusion built-in template.\nThe configuration is written in KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be built to get the final output."),(0,a.kt)("p",null,"Enter stack dir ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service/dev")," and build:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"cd simple-service/dev && kusion build\n")),(0,a.kt)("p",null,"The output is printed to ",(0,a.kt)("inlineCode",{parentName:"p"},"stdout")," by default. You can save it to a file using the ",(0,a.kt)("inlineCode",{parentName:"p"},"-o/--output")," flag when running ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),"."),(0,a.kt)("p",null,"The output of ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build")," is the ",(0,a.kt)("a",{parentName:"p",href:"../../concepts/intent"},"intent")," format."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"For instructions on the kusion command line tool, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion -h"),", or refer to the tool's online ",(0,a.kt)("a",{parentName:"p",href:"../../reference/commands"},"documentation"),".")),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Build is now completed. We can apply the configuration as the next step. In the output from ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion build"),", you can see 3 resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"a Namespace named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")),(0,a.kt)("li",{parentName:"ul"},"a Deployment named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace"),(0,a.kt)("li",{parentName:"ul"},"a Service named ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service-dev-helloworld-private")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"simple-service")," namespace")),(0,a.kt)("p",null,"Execute command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion apply\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Create\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS Create apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nCreate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 3 created, 0 updated, 0 deleted.\n")),(0,a.kt)("p",null,"After the configuration applying successfully, you can use the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," to check the actual status of these resources."),(0,a.kt)("p",null,"1\u3001 Check Namespace"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get ns\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME STATUS AGE\ndefault Active 117d\nsimple-service Active 38s\nkube-system Active 117d\n...\n")),(0,a.kt)("p",null,"2\u3001Check Deployment"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get deploy -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME READY UP-TO-DATE AVAILABLE AGE\nsimple-service-dev-helloworld 1/1 1 1 59s\n")),(0,a.kt)("p",null,"3\u3001Check Service"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get svc -n simple-service\n")),(0,a.kt)("p",null,"The output is similar to:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nsimple-service-dev-helloworld-private ClusterIP 10.98.89.104 80/TCP 79s\n")),(0,a.kt)("p",null,"4\u3001Validate app"),(0,a.kt)("p",null,"Using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," tool, forward native port ",(0,a.kt)("inlineCode",{parentName:"p"},"30000")," to the service port ",(0,a.kt)("inlineCode",{parentName:"p"},"80"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:80\n")),(0,a.kt)("p",null,"Open browser and visit ",(0,a.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),"\uff1a"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}u.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/1aea322a.6265a3e0.js b/assets/js/1aea322a.6265a3e0.js new file mode 100644 index 00000000000..11a2d3470e9 --- /dev/null +++ b/assets/js/1aea322a.6265a3e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8686],{3905:(t,e,n)=>{n.d(e,{Zo:()=>d,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var p=a.createContext({}),s=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},d=function(t){var e=s(t.components);return a.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(n),c=r,g=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return n?a.createElement(g,i(i({ref:e},d),{},{components:n})):a.createElement(g,i({ref:e},d))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{n.r(e),n.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:2},i="Installation",o={unversionedId:"operating/started/install",id:"version-v0.9/operating/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.9/operating/started/install.md",sourceDirName:"operating/started",slug:"/operating/started/install",permalink:"/docs/v0.9/operating/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/started/install.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"What is KusionStack Operating?",permalink:"/docs/v0.9/operating/introduction/"},next:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/v0.9/operating/started/demo-graceful-operation"}},p={},s=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Uninstall",id:"uninstall",level:3}],d={toc:s};function m(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"KusionStack Operating requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install operating kusionstack/operating \n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for Operating installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack-system"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"managerReplicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of Operating deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"3"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for operating image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/operating"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for operating-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"128Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))))),(0,r.kt)("h3",{id:"upgrade"},"Upgrade"),(0,r.kt)("p",null,"Run following command to upgrade KusionStack Operating to the latest version."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Upgrade to the latest version \n$ helm upgrade operating kusionstack/operating \n")),(0,r.kt)("h3",{id:"uninstall"},"Uninstall"),(0,r.kt)("p",null,"Run following command to uninstall KusionStack Operating."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Uninstall\n$ helm uninstall operating\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1aea322a.9a3c594c.js b/assets/js/1aea322a.9a3c594c.js deleted file mode 100644 index 337b85a47b1..00000000000 --- a/assets/js/1aea322a.9a3c594c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8686],{3905:(t,e,n)=>{n.d(e,{Zo:()=>d,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var p=a.createContext({}),s=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},d=function(t){var e=s(t.components);return a.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(n),c=r,g=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return n?a.createElement(g,i(i({ref:e},d),{},{components:n})):a.createElement(g,i({ref:e},d))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{n.r(e),n.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:2},i="Installation",o={unversionedId:"operating/started/install",id:"version-v0.9/operating/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.9/operating/started/install.md",sourceDirName:"operating/started",slug:"/operating/started/install",permalink:"/docs/v0.9/operating/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/started/install.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"What is KusionStack Operating?",permalink:"/docs/v0.9/operating/introduction/"},next:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/v0.9/operating/started/demo-graceful-operation"}},p={},s=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Uninstall",id:"uninstall",level:3}],d={toc:s};function m(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"KusionStack Operating requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install operating kusionstack/operating \n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for Operating installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack-system"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"managerReplicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of Operating deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"3"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for operating image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/operating"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for operating-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"128Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))))),(0,r.kt)("h3",{id:"upgrade"},"Upgrade"),(0,r.kt)("p",null,"Run following command to upgrade KusionStack Operating to the latest version."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Upgrade to the latest version \n$ helm upgrade operating kusionstack/operating \n")),(0,r.kt)("h3",{id:"uninstall"},"Uninstall"),(0,r.kt)("p",null,"Run following command to uninstall KusionStack Operating."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Uninstall\n$ helm uninstall operating\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1b99e815.2d9143d4.js b/assets/js/1b99e815.e0cdc2d3.js similarity index 56% rename from assets/js/1b99e815.2d9143d4.js rename to assets/js/1b99e815.e0cdc2d3.js index 280558f1a0f..0abceef74e4 100644 --- a/assets/js/1b99e815.2d9143d4.js +++ b/assets/js/1b99e815.e0cdc2d3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9516],{3905:(e,n,o)=>{o.d(n,{Zo:()=>l,kt:()=>k});var r=o(67294);function t(e,n,o){return n in e?Object.defineProperty(e,n,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[n]=o,e}function a(e,n){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),o.push.apply(o,r)}return o}function s(e){for(var n=1;n=0||(t[o]=e[o]);return t}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(t[o]=e[o])}return t}var c=r.createContext({}),p=function(e){var n=r.useContext(c),o=n;return e&&(o="function"==typeof e?e(n):s(s({},n),e)),o},l=function(e){var n=p(e.components);return r.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var o=e.components,t=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(o),k=t,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return o?r.createElement(m,s(s({ref:n},l),{},{components:o})):r.createElement(m,s({ref:n},l))}));function k(e,n){var o=arguments,t=n&&n.mdxType;if("string"==typeof e||t){var a=o.length,s=new Array(a);s[0]=d;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i.mdxType="string"==typeof e?e:t,s[1]=i;for(var p=2;p{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=o(87462),t=(o(67294),o(3905));const a={},s="kusion workspace show",i={unversionedId:"kusion/reference/commands/kusion-workspace-show",id:"version-v0.10/kusion/reference/commands/kusion-workspace-show",title:"kusion workspace show",description:"Show a workspace configuration",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-show.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-show",permalink:"/docs/kusion/reference/commands/kusion-workspace-show",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-show.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace list",permalink:"/docs/kusion/reference/commands/kusion-workspace-list"},next:{title:"kusion workspace update",permalink:"/docs/kusion/reference/commands/kusion-workspace-update"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:n,...o}=e;return(0,t.kt)("wrapper",(0,r.Z)({},l,o,{components:n,mdxType:"MDXLayout"}),(0,t.kt)("h1",{id:"kusion-workspace-show"},"kusion workspace show"),(0,t.kt)("p",null,"Show a workspace configuration"),(0,t.kt)("h3",{id:"synopsis"},"Synopsis"),(0,t.kt)("p",null,"This command gets a specified workspace configuration."),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"},"kusion workspace show\n")),(0,t.kt)("h3",{id:"examples"},"Examples"),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"}," # Show a workspace configuration\n kusion workspace show dev\n")),(0,t.kt)("h3",{id:"options"},"Options"),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"}," -h, --help help for show\n")),(0,t.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,t.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,t.kt)("ul",null,(0,t.kt)("li",{parentName:"ul"},(0,t.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,t.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9516],{3905:(e,n,o)=>{o.d(n,{Zo:()=>l,kt:()=>k});var r=o(67294);function t(e,n,o){return n in e?Object.defineProperty(e,n,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[n]=o,e}function a(e,n){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),o.push.apply(o,r)}return o}function s(e){for(var n=1;n=0||(t[o]=e[o]);return t}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(t[o]=e[o])}return t}var c=r.createContext({}),p=function(e){var n=r.useContext(c),o=n;return e&&(o="function"==typeof e?e(n):s(s({},n),e)),o},l=function(e){var n=p(e.components);return r.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var o=e.components,t=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(o),k=t,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return o?r.createElement(m,s(s({ref:n},l),{},{components:o})):r.createElement(m,s({ref:n},l))}));function k(e,n){var o=arguments,t=n&&n.mdxType;if("string"==typeof e||t){var a=o.length,s=new Array(a);s[0]=d;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i.mdxType="string"==typeof e?e:t,s[1]=i;for(var p=2;p{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=o(87462),t=(o(67294),o(3905));const a={},s="kusion workspace show",i={unversionedId:"kusion/reference/commands/kusion-workspace-show",id:"version-v0.10/kusion/reference/commands/kusion-workspace-show",title:"kusion workspace show",description:"Show a workspace configuration",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-show.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-show",permalink:"/docs/kusion/reference/commands/kusion-workspace-show",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-show.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace list",permalink:"/docs/kusion/reference/commands/kusion-workspace-list"},next:{title:"kusion workspace update",permalink:"/docs/kusion/reference/commands/kusion-workspace-update"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:n,...o}=e;return(0,t.kt)("wrapper",(0,r.Z)({},l,o,{components:n,mdxType:"MDXLayout"}),(0,t.kt)("h1",{id:"kusion-workspace-show"},"kusion workspace show"),(0,t.kt)("p",null,"Show a workspace configuration"),(0,t.kt)("h3",{id:"synopsis"},"Synopsis"),(0,t.kt)("p",null,"This command gets a specified workspace configuration."),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"},"kusion workspace show\n")),(0,t.kt)("h3",{id:"examples"},"Examples"),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"}," # Show a workspace configuration\n kusion workspace show dev\n")),(0,t.kt)("h3",{id:"options"},"Options"),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"}," -h, --help help for show\n")),(0,t.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,t.kt)("pre",null,(0,t.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,t.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,t.kt)("ul",null,(0,t.kt)("li",{parentName:"ul"},(0,t.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,t.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1c549a2d.333ccd1c.js b/assets/js/1c549a2d.333ccd1c.js deleted file mode 100644 index d8797b92ca9..00000000000 --- a/assets/js/1c549a2d.333ccd1c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2717],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="job",o={unversionedId:"kusion/reference/modules/catalog-models/workload/job",id:"kusion/reference/modules/catalog-models/workload/job",title:"job",description:"Schemas",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/job",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule"},next:{title:"service",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/service"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Job",id:"schema-job",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"job"},"job"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-job"},"Job"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret"))))),(0,r.kt)("h2",{id:"schema-job"},"Schema Job"),(0,r.kt)("p",null,"Job is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),"is typically used for tasks that take from a few seconds to a few days to complete."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"schedule")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a job with busybox image and runs every hour\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\njob: wl.Job {\n containers: {\n "busybox": c.Container{\n image: "busybox:1.28"\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n schedule: "0 * * * *"\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1c549a2d.aac0a3f6.js b/assets/js/1c549a2d.aac0a3f6.js new file mode 100644 index 00000000000..751d81d1944 --- /dev/null +++ b/assets/js/1c549a2d.aac0a3f6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2717],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="job",o={unversionedId:"kusion/reference/modules/catalog-models/workload/job",id:"kusion/reference/modules/catalog-models/workload/job",title:"job",description:"Schemas",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/job",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule"},next:{title:"service",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/service"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Job",id:"schema-job",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"job"},"job"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-job"},"Job"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret"))))),(0,r.kt)("h2",{id:"schema-job"},"Schema Job"),(0,r.kt)("p",null,"Job is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),"is typically used for tasks that take from a few seconds to a few days to complete."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"schedule")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a job with busybox image and runs every hour\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\njob: wl.Job {\n containers: {\n "busybox": c.Container{\n image: "busybox:1.28"\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n schedule: "0 * * * *"\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1fe9451f.4658cdba.js b/assets/js/1fe9451f.4658cdba.js new file mode 100644 index 00000000000..0991951fe4a --- /dev/null +++ b/assets/js/1fe9451f.4658cdba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3897],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=p(n),u=r,g=m["".concat(s,".").concat(u)]||m[u]||d[u]||o;return n?a.createElement(g,l(l({ref:t},c),{},{components:n})):a.createElement(g,l({ref:t},c))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={},l="appconfiguration",i={unversionedId:"kusion/reference/modules/catalog-models/app-configuration",id:"kusion/reference/modules/catalog-models/app-configuration",title:"appconfiguration",description:"Schema AppConfiguration",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models",slug:"/kusion/reference/modules/catalog-models/app-configuration",permalink:"/docs/next/kusion/reference/modules/catalog-models/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Modules",permalink:"/docs/next/kusion/reference/modules/"},next:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/mysql"}},s={},p=[{value:"Schema AppConfiguration",id:"schema-appconfiguration",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],c={toc:p};function d(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"appconfiguration"},"appconfiguration"),(0,r.kt)("h2",{id:"schema-appconfiguration"},"Schema AppConfiguration"),(0,r.kt)("p",null,"AppConfiguration is a developer-centric definition that describes how to run an Application.",(0,r.kt)("br",null),"This application model builds upon a decade of experience at AntGroup running super large scale",(0,r.kt)("br",null),"internal developer platform, combined with best-of-breed ideas and practices from the community."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workload"),(0,r.kt)("br",null),"Workload defines how to run your application code. Currently supported workload profile",(0,r.kt)("br",null),"includes Service and Job."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/service#schema-service"},"workload.Service")," \\ "),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/job#schema-job"},"workload.Job")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"opsRule"),(0,r.kt)("br",null),"OpsRule specifies collection of rules that will be checked for Day-2 operation."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"trait/opsrule#schema-opsrule"},"trait.OpsRule")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"database"),(0,r.kt)("br",null),"Database describes a locally deployed or a cloud provider managed database instance for the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"database/mysql#schema-mysql"},"mysql.MySQL")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"database/postgres#schema-postgresql"},"postgres.PostgreSQL"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"monitoring")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"monitoring/prometheus#schema-prometheus"},"monitoring.Prometheus")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate an App with a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.accessories.database as db\nimport catalog.models.schema.v1.accessories.monitoring as m\nimport catalog.models.schema.v1.accessories.trait as t\n\nappConfiguration = ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n type: "CollaSet"\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n database: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1fe9451f.ca1c3b23.js b/assets/js/1fe9451f.ca1c3b23.js deleted file mode 100644 index d28c7b4a2e2..00000000000 --- a/assets/js/1fe9451f.ca1c3b23.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3897],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=p(n),u=r,g=m["".concat(s,".").concat(u)]||m[u]||d[u]||o;return n?a.createElement(g,l(l({ref:t},c),{},{components:n})):a.createElement(g,l({ref:t},c))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={},l="appconfiguration",i={unversionedId:"kusion/reference/modules/catalog-models/app-configuration",id:"kusion/reference/modules/catalog-models/app-configuration",title:"appconfiguration",description:"Schema AppConfiguration",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models",slug:"/kusion/reference/modules/catalog-models/app-configuration",permalink:"/docs/next/kusion/reference/modules/catalog-models/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Modules",permalink:"/docs/next/kusion/reference/modules/"},next:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/mysql"}},s={},p=[{value:"Schema AppConfiguration",id:"schema-appconfiguration",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],c={toc:p};function d(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"appconfiguration"},"appconfiguration"),(0,r.kt)("h2",{id:"schema-appconfiguration"},"Schema AppConfiguration"),(0,r.kt)("p",null,"AppConfiguration is a developer-centric definition that describes how to run an Application.",(0,r.kt)("br",null),"This application model builds upon a decade of experience at AntGroup running super large scale",(0,r.kt)("br",null),"internal developer platform, combined with best-of-breed ideas and practices from the community."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workload"),(0,r.kt)("br",null),"Workload defines how to run your application code. Currently supported workload profile",(0,r.kt)("br",null),"includes Service and Job."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/service#schema-service"},"workload.Service")," \\ "),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/job#schema-job"},"workload.Job")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"opsRule"),(0,r.kt)("br",null),"OpsRule specifies collection of rules that will be checked for Day-2 operation."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"trait/opsrule#schema-opsrule"},"trait.OpsRule")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"database"),(0,r.kt)("br",null),"Database describes a locally deployed or a cloud provider managed database instance for the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"database/mysql#schema-mysql"},"mysql.MySQL")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"database/postgres#schema-postgresql"},"postgres.PostgreSQL"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"monitoring")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"monitoring/prometheus#schema-prometheus"},"monitoring.Prometheus")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate an App with a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.accessories.database as db\nimport catalog.models.schema.v1.accessories.monitoring as m\nimport catalog.models.schema.v1.accessories.trait as t\n\nappConfiguration = ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n type: "CollaSet"\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n database: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/20d5d8d7.ba287408.js b/assets/js/20d5d8d7.ba287408.js deleted file mode 100644 index fa1651a80c4..00000000000 --- a/assets/js/20d5d8d7.ba287408.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5101],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=r,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return t?a.createElement(m,i(i({ref:n},c),{},{components:t})):a.createElement(m,i({ref:n},c))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={},i="Using KusionStack Operating to operate Pods gracefully",l={unversionedId:"operating/started/demo-graceful-operation",id:"version-v0.10/operating/started/demo-graceful-operation",title:"Using KusionStack Operating to operate Pods gracefully",description:"Applications always provide its service along with traffic routing.",source:"@site/versioned_docs/version-v0.10/operating/started/demo-graceful-operation.md",sourceDirName:"operating/started",slug:"/operating/started/demo-graceful-operation",permalink:"/docs/operating/started/demo-graceful-operation",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/started/demo-graceful-operation.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",previous:{title:"Installation",permalink:"/docs/operating/started/install"},next:{title:"PodOpsLifecycle",permalink:"/docs/operating/concepts/podopslifecycle"}},s={},p=[{value:"Preparing",id:"preparing",level:2},{value:"Get started",id:"get-started",level:2},{value:"Create a new namespace",id:"create-a-new-namespace",level:3},{value:"Provision Pods and Services",id:"provision-pods-and-services",level:3},{value:"Provision a client",id:"provision-a-client",level:3},{value:"Update Pod revision",id:"update-pod-revision",level:3},{value:"Provision PodTransistionRule",id:"provision-podtransistionrule",level:3},{value:"Clean tutorial namespace",id:"clean-tutorial-namespace",level:3},{value:"Comparison with the Native Approach",id:"comparison-with-the-native-approach",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-kusionstack-operating-to-operate-pods-gracefully"},"Using KusionStack Operating to operate Pods gracefully"),(0,r.kt)("p",null,"Applications always provide its service along with traffic routing.\nOn Kubernetes, they should be a set of Pods and a corresponding Kubernetes Service resource to expose the service."),(0,r.kt)("p",null,"However, during operations such as updating Pod revisions,\nthere is a risk that client request traffic may be lost. This can lead to a poor user experience for developers."),(0,r.kt)("p",null,"This tutorial will demonstrate how to operate Pods gracefully in a KusionStack Operating way on Aliyun ACK\nwith SLB as a Service backend provider."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"You can also get the same point from ",(0,r.kt)("a",{parentName:"p",href:"https://www.bilibili.com/video/BV1n8411q7sP/?t=15.7"},"this video"),",\nwhich shows the same case using both KusionStack Kusion and Operating.\nThe sample used in this video can be found from ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/samples/wordpress"},"KusionStack Catalog"),".")),(0,r.kt)("h2",{id:"preparing"},"Preparing"),(0,r.kt)("p",null,"First, ensure that you have an Aliyun ACK Kubernetes cluster set up in order to provision an Aliyun SLB."),(0,r.kt)("p",null,"Next, install KusionStack Operating on this Kubernetes cluster\nfollowing ",(0,r.kt)("a",{parentName:"p",href:"https://kusionstack.io/docs/operating/started/install"},"installation doc"),"."),(0,r.kt)("h2",{id:"get-started"},"Get started"),(0,r.kt)("h3",{id:"create-a-new-namespace"},"Create a new namespace"),(0,r.kt)("p",null,"To begin, create a new namespace for this tutorial:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl create ns operating-tutorial\n")),(0,r.kt)("h3",{id:"provision-pods-and-services"},"Provision Pods and Services"),(0,r.kt)("p",null,"You can create a set of Pods to run up a demo application service\nby creating CollaSet resource using following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: server\n command:\n - /server\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"There should be 3 Pods created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nserver-c5lsr 1/1 Running 0 2m23s\nserver-p6wrx 1/1 Running 0 2m23s\nserver-zn62c 1/1 Running 0 2m23s\n")),(0,r.kt)("p",null,"Then create a Kubernetes Service by running following command,\nwhich will provision Aliyun SLB to expose service."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: v1\nkind: Service\nmetadata:\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n service.beta.kubernetes.io/backend-type: eni\n labels:\n kusionstack.io/control: \"true\" # this label is required\n name: server\nspec:\n ports:\n - port: 80\n protocol: TCP\n targetPort: 8080\n selector:\n app: server\n type: LoadBalancer\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"A service with external IP should be provisioned."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get svc server\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nserver LoadBalancer 192.168.225.55 47.101.49.182 80:30146/TCP 51s\n")),(0,r.kt)("p",null,"The label ",(0,r.kt)("inlineCode",{parentName:"p"},'kusionstack.io/control: "true"')," on Service is very important.\nIt means this service resource will be recognized by ResourceConsist framework, and then participate in PodOpsLifecycle\nto control the Aliyun SLB to switch off traffic before updating each Pod and switch on traffic after it finished,\nin order to protect the service."),(0,r.kt)("h3",{id:"provision-a-client"},"Provision a client"),(0,r.kt)("p",null,"Then we will provision a client to access the service we created before.\nPlease replace ",(0,r.kt)("inlineCode",{parentName:"p"},"")," in the following CollaSet yaml with the external IP from Kubernetes Service created above, and apply again."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: client\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: client\n template:\n metadata:\n labels:\n app: client\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: nginx\n command:\n - /client\n args:\n - -url\n - http:///echo # EXTERNAL_IP should be replaced\n - -m\n - POST\n - d\n - operating-tutorial\n - -qps\n - "10"\n - -worker\n - "10"\n - -timeout\n - "10000"\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"A client Pod should be created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-nc426 1/1 Running 0 30s\nserver-c5lsr 1/1 Running 0 19m\nserver-p6wrx 1/1 Running 0 19m\nserver-zn62c 1/1 Running 0 19m\n")),(0,r.kt)("p",null,"This client will continuously access the service using the configuration provided in the command.\nYou can monitor the response codes from its logs:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial logs -f client-nc426\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\n")),(0,r.kt)("p",null,"The accesses are all successful."),(0,r.kt)("h3",{id:"update-pod-revision"},"Update Pod revision"),(0,r.kt)("p",null,"To trigger a Pod revision update, run the following command\nto edit the container image and command in the PodTemplate of CollaSet:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.2\n name: server\n command:\n - /app/echo\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"It will trigger all Pods updated simultaneously. So the application ",(0,r.kt)("inlineCode",{parentName:"p"},"server")," has no Pod to serve.\nWe can observe the error from client logs."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'worker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:54040->47.101.49.182:80: read: connection reset by peer\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:34438->47.101.49.182:80: read: connection reset by peer\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 another loop, request: 20, failed: 3\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 another loop, request: 20, failed: 3\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n')),(0,r.kt)("h3",{id:"provision-podtransistionrule"},"Provision PodTransistionRule"),(0,r.kt)("p",null,"To avoid this problem, provision a PodTransitionRule with a maxUnavailable 50% rule by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n labels:\n name: server\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n selector:\n matchLabels:\n app: server\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"After updating the CollaSet of the server to trigger an update, you will see the Pods rolling update one by one,\nensuring that at least one Pod is always available to serve."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-rrfbj 1/1 Running 0 25s\nserver-457sn 0/1 Running 0 5s\nserver-bd5sz 0/1 Running 0 5s\nserver-l842s 1/1 Running 0 2m4s\n")),(0,r.kt)("p",null,"You can see from the client logs that no access requests fail during this update."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"worker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\n")),(0,r.kt)("h3",{id:"clean-tutorial-namespace"},"Clean tutorial namespace"),(0,r.kt)("p",null,"At the end of this tutorial, you can clean up the resources by deleting the namespace:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl delete ns operating-tutorial\n")),(0,r.kt)("h2",{id:"comparison-with-the-native-approach"},"Comparison with the Native Approach"),(0,r.kt)("p",null,"Kubernetes provides ",(0,r.kt)("inlineCode",{parentName:"p"},"preStop")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postStart")," hook in each container, by which users can also interact with service outside\nKubernetes like Aliyun SLB service. However, KusionStack Operating offers several advantages:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Pod level vs Container level")),(0,r.kt)("p",null,"Operating offers a Pod level hooks which have more complete information than one container,\nespecially there are several containers in one Pod."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Plugin-able")),(0,r.kt)("p",null,"Through KusionStack Operating, you can decouple operations executed before or after Pods actually change.\nFor example, traffic control can be added or removed without modifying the Pod's preStop configuration."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Rollback option")),(0,r.kt)("p",null,"In case of issues, rollback becomes a viable option when using the Operating approach to update Pods.\nSince Operating does not modify the Pods or their containers during the update,\nif the traffic service experiences problems, there is an opportunity to cancel the update."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/20d5d8d7.cc383b35.js b/assets/js/20d5d8d7.cc383b35.js new file mode 100644 index 00000000000..1db82b917cb --- /dev/null +++ b/assets/js/20d5d8d7.cc383b35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5101],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=r,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return t?a.createElement(m,i(i({ref:n},c),{},{components:t})):a.createElement(m,i({ref:n},c))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={},i="Using KusionStack Operating to operate Pods gracefully",l={unversionedId:"operating/started/demo-graceful-operation",id:"version-v0.10/operating/started/demo-graceful-operation",title:"Using KusionStack Operating to operate Pods gracefully",description:"Applications always provide its service along with traffic routing.",source:"@site/versioned_docs/version-v0.10/operating/started/demo-graceful-operation.md",sourceDirName:"operating/started",slug:"/operating/started/demo-graceful-operation",permalink:"/docs/operating/started/demo-graceful-operation",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/started/demo-graceful-operation.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",previous:{title:"Installation",permalink:"/docs/operating/started/install"},next:{title:"PodOpsLifecycle",permalink:"/docs/operating/concepts/podopslifecycle"}},s={},p=[{value:"Preparing",id:"preparing",level:2},{value:"Get started",id:"get-started",level:2},{value:"Create a new namespace",id:"create-a-new-namespace",level:3},{value:"Provision Pods and Services",id:"provision-pods-and-services",level:3},{value:"Provision a client",id:"provision-a-client",level:3},{value:"Update Pod revision",id:"update-pod-revision",level:3},{value:"Provision PodTransistionRule",id:"provision-podtransistionrule",level:3},{value:"Clean tutorial namespace",id:"clean-tutorial-namespace",level:3},{value:"Comparison with the Native Approach",id:"comparison-with-the-native-approach",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-kusionstack-operating-to-operate-pods-gracefully"},"Using KusionStack Operating to operate Pods gracefully"),(0,r.kt)("p",null,"Applications always provide its service along with traffic routing.\nOn Kubernetes, they should be a set of Pods and a corresponding Kubernetes Service resource to expose the service."),(0,r.kt)("p",null,"However, during operations such as updating Pod revisions,\nthere is a risk that client request traffic may be lost. This can lead to a poor user experience for developers."),(0,r.kt)("p",null,"This tutorial will demonstrate how to operate Pods gracefully in a KusionStack Operating way on Aliyun ACK\nwith SLB as a Service backend provider."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"You can also get the same point from ",(0,r.kt)("a",{parentName:"p",href:"https://www.bilibili.com/video/BV1n8411q7sP/?t=15.7"},"this video"),",\nwhich shows the same case using both KusionStack Kusion and Operating.\nThe sample used in this video can be found from ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/samples/wordpress"},"KusionStack Catalog"),".")),(0,r.kt)("h2",{id:"preparing"},"Preparing"),(0,r.kt)("p",null,"First, ensure that you have an Aliyun ACK Kubernetes cluster set up in order to provision an Aliyun SLB."),(0,r.kt)("p",null,"Next, install KusionStack Operating on this Kubernetes cluster\nfollowing ",(0,r.kt)("a",{parentName:"p",href:"https://kusionstack.io/docs/operating/started/install"},"installation doc"),"."),(0,r.kt)("h2",{id:"get-started"},"Get started"),(0,r.kt)("h3",{id:"create-a-new-namespace"},"Create a new namespace"),(0,r.kt)("p",null,"To begin, create a new namespace for this tutorial:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl create ns operating-tutorial\n")),(0,r.kt)("h3",{id:"provision-pods-and-services"},"Provision Pods and Services"),(0,r.kt)("p",null,"You can create a set of Pods to run up a demo application service\nby creating CollaSet resource using following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: server\n command:\n - /server\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"There should be 3 Pods created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nserver-c5lsr 1/1 Running 0 2m23s\nserver-p6wrx 1/1 Running 0 2m23s\nserver-zn62c 1/1 Running 0 2m23s\n")),(0,r.kt)("p",null,"Then create a Kubernetes Service by running following command,\nwhich will provision Aliyun SLB to expose service."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: v1\nkind: Service\nmetadata:\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n service.beta.kubernetes.io/backend-type: eni\n labels:\n kusionstack.io/control: \"true\" # this label is required\n name: server\nspec:\n ports:\n - port: 80\n protocol: TCP\n targetPort: 8080\n selector:\n app: server\n type: LoadBalancer\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"A service with external IP should be provisioned."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get svc server\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nserver LoadBalancer 192.168.225.55 47.101.49.182 80:30146/TCP 51s\n")),(0,r.kt)("p",null,"The label ",(0,r.kt)("inlineCode",{parentName:"p"},'kusionstack.io/control: "true"')," on Service is very important.\nIt means this service resource will be recognized by ResourceConsist framework, and then participate in PodOpsLifecycle\nto control the Aliyun SLB to switch off traffic before updating each Pod and switch on traffic after it finished,\nin order to protect the service."),(0,r.kt)("h3",{id:"provision-a-client"},"Provision a client"),(0,r.kt)("p",null,"Then we will provision a client to access the service we created before.\nPlease replace ",(0,r.kt)("inlineCode",{parentName:"p"},"")," in the following CollaSet yaml with the external IP from Kubernetes Service created above, and apply again."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: client\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: client\n template:\n metadata:\n labels:\n app: client\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: nginx\n command:\n - /client\n args:\n - -url\n - http:///echo # EXTERNAL_IP should be replaced\n - -m\n - POST\n - d\n - operating-tutorial\n - -qps\n - "10"\n - -worker\n - "10"\n - -timeout\n - "10000"\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"A client Pod should be created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-nc426 1/1 Running 0 30s\nserver-c5lsr 1/1 Running 0 19m\nserver-p6wrx 1/1 Running 0 19m\nserver-zn62c 1/1 Running 0 19m\n")),(0,r.kt)("p",null,"This client will continuously access the service using the configuration provided in the command.\nYou can monitor the response codes from its logs:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial logs -f client-nc426\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\n")),(0,r.kt)("p",null,"The accesses are all successful."),(0,r.kt)("h3",{id:"update-pod-revision"},"Update Pod revision"),(0,r.kt)("p",null,"To trigger a Pod revision update, run the following command\nto edit the container image and command in the PodTemplate of CollaSet:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.2\n name: server\n command:\n - /app/echo\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"It will trigger all Pods updated simultaneously. So the application ",(0,r.kt)("inlineCode",{parentName:"p"},"server")," has no Pod to serve.\nWe can observe the error from client logs."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'worker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:54040->47.101.49.182:80: read: connection reset by peer\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:34438->47.101.49.182:80: read: connection reset by peer\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 another loop, request: 20, failed: 3\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 another loop, request: 20, failed: 3\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n')),(0,r.kt)("h3",{id:"provision-podtransistionrule"},"Provision PodTransistionRule"),(0,r.kt)("p",null,"To avoid this problem, provision a PodTransitionRule with a maxUnavailable 50% rule by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n labels:\n name: server\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n selector:\n matchLabels:\n app: server\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"After updating the CollaSet of the server to trigger an update, you will see the Pods rolling update one by one,\nensuring that at least one Pod is always available to serve."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-rrfbj 1/1 Running 0 25s\nserver-457sn 0/1 Running 0 5s\nserver-bd5sz 0/1 Running 0 5s\nserver-l842s 1/1 Running 0 2m4s\n")),(0,r.kt)("p",null,"You can see from the client logs that no access requests fail during this update."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"worker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\n")),(0,r.kt)("h3",{id:"clean-tutorial-namespace"},"Clean tutorial namespace"),(0,r.kt)("p",null,"At the end of this tutorial, you can clean up the resources by deleting the namespace:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl delete ns operating-tutorial\n")),(0,r.kt)("h2",{id:"comparison-with-the-native-approach"},"Comparison with the Native Approach"),(0,r.kt)("p",null,"Kubernetes provides ",(0,r.kt)("inlineCode",{parentName:"p"},"preStop")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postStart")," hook in each container, by which users can also interact with service outside\nKubernetes like Aliyun SLB service. However, KusionStack Operating offers several advantages:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Pod level vs Container level")),(0,r.kt)("p",null,"Operating offers a Pod level hooks which have more complete information than one container,\nespecially there are several containers in one Pod."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Plugin-able")),(0,r.kt)("p",null,"Through KusionStack Operating, you can decouple operations executed before or after Pods actually change.\nFor example, traffic control can be added or removed without modifying the Pod's preStop configuration."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Rollback option")),(0,r.kt)("p",null,"In case of issues, rollback becomes a viable option when using the Operating approach to update Pods.\nSince Operating does not modify the Pods or their containers during the update,\nif the traffic service experiences problems, there is an opportunity to cancel the update."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2115f1af.f7d9fd25.js b/assets/js/2115f1af.d9a37f9b.js similarity index 55% rename from assets/js/2115f1af.f7d9fd25.js rename to assets/js/2115f1af.d9a37f9b.js index 2aebcc0843a..25a2c4ff60b 100644 --- a/assets/js/2115f1af.f7d9fd25.js +++ b/assets/js/2115f1af.d9a37f9b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8989],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||l[f]||a;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},i="kusion workspace update",s={unversionedId:"kusion/reference/commands/kusion-workspace-update",id:"kusion/reference/commands/kusion-workspace-update",title:"kusion workspace update",description:"Update a workspace configuration",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-update.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-update",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-update",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-update.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace show",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-show"},next:{title:"kusion workspace",permalink:"/docs/next/kusion/reference/commands/kusion-workspace"}},p={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],u={toc:c};function l(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-update"},"kusion workspace update"),(0,o.kt)("p",null,"Update a workspace configuration"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command updates a workspace configuration with specified configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace update\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Update a workspace configuration\n kusion workspace update dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for update\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8989],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||l[f]||a;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},i="kusion workspace update",s={unversionedId:"kusion/reference/commands/kusion-workspace-update",id:"kusion/reference/commands/kusion-workspace-update",title:"kusion workspace update",description:"Update a workspace configuration",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-update.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-update",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-update",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-update.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace show",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-show"},next:{title:"kusion workspace",permalink:"/docs/next/kusion/reference/commands/kusion-workspace"}},p={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],u={toc:c};function l(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-update"},"kusion workspace update"),(0,o.kt)("p",null,"Update a workspace configuration"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command updates a workspace configuration with specified configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace update\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Update a workspace configuration\n kusion workspace update dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for update\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/22cda74c.1ecaea8f.js b/assets/js/22cda74c.1ecaea8f.js new file mode 100644 index 00000000000..a0f32bcc685 --- /dev/null +++ b/assets/js/22cda74c.1ecaea8f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9394],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=u(n),m=a,k=c["".concat(i,".").concat(m)]||c[m]||p[m]||l;return n?r.createElement(k,o(o({ref:t},d),{},{components:n})):r.createElement(k,o({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=c;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>p,frontMatter:()=>l,metadata:()=>s,toc:()=>u});var r=n(87462),a=(n(67294),n(3905));const l={},o="mysql",s={unversionedId:"kusion/reference/modules/workspace-configs/database/mysql",id:"version-v0.10/kusion/reference/modules/workspace-configs/database/mysql",title:"mysql",description:"Module MySQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/mysql",permalink:"/docs/kusion/reference/modules/workspace-configs/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"service",permalink:"/docs/kusion/reference/modules/catalog-models/workload/service"},next:{title:"postgres",permalink:"/docs/kusion/reference/modules/workspace-configs/database/postgres"}},i={},u=[{value:"Module MySQL",id:"module-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:u};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"mysql"},"mysql"),(0,a.kt)("h2",{id:"module-mysql"},"Module MySQL"),(0,a.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider managed mysql database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the mysql database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud mysql instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the mysql instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud mysql instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL workspace configs for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL workspace configs for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/22cda74c.6ea7132b.js b/assets/js/22cda74c.6ea7132b.js deleted file mode 100644 index 86736407a8a..00000000000 --- a/assets/js/22cda74c.6ea7132b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9394],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=u(n),m=a,k=c["".concat(i,".").concat(m)]||c[m]||p[m]||l;return n?r.createElement(k,o(o({ref:t},d),{},{components:n})):r.createElement(k,o({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=c;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>p,frontMatter:()=>l,metadata:()=>s,toc:()=>u});var r=n(87462),a=(n(67294),n(3905));const l={},o="mysql",s={unversionedId:"kusion/reference/modules/workspace-configs/database/mysql",id:"version-v0.10/kusion/reference/modules/workspace-configs/database/mysql",title:"mysql",description:"Module MySQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/mysql",permalink:"/docs/kusion/reference/modules/workspace-configs/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"service",permalink:"/docs/kusion/reference/modules/catalog-models/workload/service"},next:{title:"postgres",permalink:"/docs/kusion/reference/modules/workspace-configs/database/postgres"}},i={},u=[{value:"Module MySQL",id:"module-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:u};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"mysql"},"mysql"),(0,a.kt)("h2",{id:"module-mysql"},"Module MySQL"),(0,a.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider managed mysql database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the mysql database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud mysql instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the mysql instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud mysql instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL workspace configs for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL workspace configs for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2353ab8e.6804a17b.js b/assets/js/2353ab8e.6804a17b.js deleted file mode 100644 index 5f95acbfee1..00000000000 --- a/assets/js/2353ab8e.6804a17b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4919],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>m});var t=a(67294);function i(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function o(e){for(var n=1;n=0||(i[a]=e[a]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=t.createContext({}),p=function(e){var n=t.useContext(s),a=n;return e&&(a="function"==typeof e?e(n):o(o({},n),e)),a},d=function(e){var n=p(e.components);return t.createElement(s.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(a),m=i,h=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return a?t.createElement(h,o(o({ref:n},d),{},{components:a})):t.createElement(h,o({ref:n},d))}));function m(e,n){var a=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{a.r(n),a.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),i=(a(67294),a(3905));const r={sidebar_position:3},o="PodTransitionRule",l={unversionedId:"operating/manuals/podtransitionrule",id:"version-v0.10/operating/manuals/podtransitionrule",title:"PodTransitionRule",description:"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.",source:"@site/versioned_docs/version-v0.10/operating/manuals/podtransitionrule.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/podtransitionrule",permalink:"/docs/operating/manuals/podtransitionrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/podtransitionrule.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"operating",previous:{title:"ResourceConsist",permalink:"/docs/operating/manuals/resourceconsist"},next:{title:"PodDecoration",permalink:"/docs/operating/manuals/poddecoration"}},s={},p=[{value:"Rule Definition",id:"rule-definition",level:2},{value:"Available Policy",id:"available-policy",level:3},{value:"maxUnavailable",id:"maxunavailable",level:4},{value:"minAvailable",id:"minavailable",level:4},{value:"Label Check",id:"label-check",level:3},{value:"Webhook",id:"webhook",level:3}],d={toc:p};function c(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"podtransitionrule"},"PodTransitionRule"),(0,i.kt)("p",null,"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pending")," phase, moving through ",(0,i.kt)("inlineCode",{parentName:"p"},"Running")," if at least one of its primary containers starts ",(0,i.kt)("inlineCode",{parentName:"p"},"OK"),", and then through either the ",(0,i.kt)("inlineCode",{parentName:"p"},"Succeeded")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"Failed")," phases depending on whether any container in the Pod terminated in failure."),(0,i.kt)("p",null,"These phase definitions can fulfill basic Pod change scenarios, but it are ambiguous.\nActually, before pod upgrade or ready, it is necessary to have some check mechanisms in place to ensure the safety of pod changes. Fortunately, ",(0,i.kt)("a",{parentName:"p",href:"/docs/operating/concepts/podopslifecycle"},"PodOpsLifecycle")," extends and supports some check stages: ",(0,i.kt)("inlineCode",{parentName:"p"},"PreCheck")," before pod upgrade and ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," before pod ready."),(0,i.kt)("p",null,"To ensure a more fine-grained and controlled change process for Pods, we introduce custom rules or perform additional tasks as prerequisites for state transitions before the desired state of a Pod is achieved. Similar to the Pod ",(0,i.kt)("inlineCode",{parentName:"p"},"readinessGates"),", where certain conditions must be met for a Pod to be considered readiness. For example, we consider a Pod ready for the ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," phase only if it has specific labels. For this purpose, we introduce the ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," as a prerequisite for the state transition of a Pod."),(0,i.kt)("h2",{id:"rule-definition"},"Rule Definition"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," to define a set of transition rules for your workload pods.\nEach rule will be executed at the corresponding stage, and it will be blocked if the conditions are not met."),(0,i.kt)("p",null,"Here is an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n name: podtransitionrule-sample\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n - stage: PreCheck # stages are supported by PodOpsLifecycle. Defaults to PreCheck.\n labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n name: labelCheck\n - stage: PostCheck\n webhook:\n clientConfig:\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id # URL parameter key to carry trace ID when fetching result. Defaults to task-id in form 'QueryUrl=URL?rawQueryKey='\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef: \n fieldPath: status.podIP\n name: webhookCheck\n selector: # select pods in effect\n matchLabels:\n app: foo\n")),(0,i.kt)("h3",{id:"available-policy"},"Available Policy"),(0,i.kt)("p",null,"An ",(0,i.kt)("inlineCode",{parentName:"p"},"availablePolicy")," rule defines the availability strategy during the Pod update process."),(0,i.kt)("h4",{id:"maxunavailable"},"maxUnavailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n maxUnavailable: \n value: 50% # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailableValue")," is the maximum number of pods that can be unavailable during the update.\nValue can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).\nAbsolute number is calculated from percentage by rounding down.\nThis can not be 0."),(0,i.kt)("h4",{id:"minavailable"},"minAvailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n minAvailable:\n value: 5 # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"minAvailableValue")," is the minimum number of pods that should be available during the update."),(0,i.kt)("h3",{id:"label-check"},"Label Check"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"labelCheck")," rule is used to check if labels are satisfied.\nYou can define your own labels as change check conditions and modify the labels according to your needs."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n matchExpressions:\n - key: app.custom/forbidden \n operator: DoesNotExist\n")),(0,i.kt)("h3",{id:"webhook"},"Webhook"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"webhook")," is an HTTP callback, based on which a external web application can determine whether a pod can pass this check."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"An HTTP POST occurs first when pods entries the configured stage which defaults PreCheck."),(0,i.kt)("li",{parentName:"ul"},"If ",(0,i.kt)("inlineCode",{parentName:"li"},"poll")," is provided, this rule then keeps calling polling url to fetch a long running job result. This job can be located by ",(0,i.kt)("inlineCode",{parentName:"li"},"task-id")," returned from the response of the first request. ")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"webhook:\n clientConfig: # custom server config\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol without poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": false,\n "message": "msg", \n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating all pods approved or not. If it's ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", the ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," field can be used to approve partial pods."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol with poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "poll": true, // required to indicate polling calls is necessary\n "taskId": , // required to to fetch polling result\n "message": "msg"\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating whether the first request is success or not. If true and field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true")," (or field ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),"), PodTransisionRule will then begin to keep calling poll URL to fetch process result.\nField ",(0,i.kt)("inlineCode",{parentName:"p"},"taskId")," is required for polling. "),(0,i.kt)("p",null,"The request for polling is GET method and in form of ",(0,i.kt)("inlineCode",{parentName:"p"},"QueryUrl=URL?task-id="),". The parameter key in this URL defaults ",(0,i.kt)("inlineCode",{parentName:"p"},"task-id"),", if using ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in above response. It would be ",(0,i.kt)("inlineCode",{parentName:"p"},"trace-id")," if using ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in above response.\nUsers can also indicate the key by field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll.rawQueryKey"),"."),(0,i.kt)("p",null,"The response from polling call is expected like following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "message": "msg",\n "finished": false,\n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"success")," is supposed to be true, if there is no error. If all pods is approved, ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," should be ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),".\nIf ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," can be used to allow partial pods to be approved."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2353ab8e.dcd1b566.js b/assets/js/2353ab8e.dcd1b566.js new file mode 100644 index 00000000000..37286348dd7 --- /dev/null +++ b/assets/js/2353ab8e.dcd1b566.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4919],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>m});var t=a(67294);function i(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function o(e){for(var n=1;n=0||(i[a]=e[a]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=t.createContext({}),p=function(e){var n=t.useContext(s),a=n;return e&&(a="function"==typeof e?e(n):o(o({},n),e)),a},d=function(e){var n=p(e.components);return t.createElement(s.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(a),m=i,h=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return a?t.createElement(h,o(o({ref:n},d),{},{components:a})):t.createElement(h,o({ref:n},d))}));function m(e,n){var a=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{a.r(n),a.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),i=(a(67294),a(3905));const r={sidebar_position:3},o="PodTransitionRule",l={unversionedId:"operating/manuals/podtransitionrule",id:"version-v0.10/operating/manuals/podtransitionrule",title:"PodTransitionRule",description:"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.",source:"@site/versioned_docs/version-v0.10/operating/manuals/podtransitionrule.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/podtransitionrule",permalink:"/docs/operating/manuals/podtransitionrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/podtransitionrule.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"operating",previous:{title:"ResourceConsist",permalink:"/docs/operating/manuals/resourceconsist"},next:{title:"PodDecoration",permalink:"/docs/operating/manuals/poddecoration"}},s={},p=[{value:"Rule Definition",id:"rule-definition",level:2},{value:"Available Policy",id:"available-policy",level:3},{value:"maxUnavailable",id:"maxunavailable",level:4},{value:"minAvailable",id:"minavailable",level:4},{value:"Label Check",id:"label-check",level:3},{value:"Webhook",id:"webhook",level:3}],d={toc:p};function c(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"podtransitionrule"},"PodTransitionRule"),(0,i.kt)("p",null,"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pending")," phase, moving through ",(0,i.kt)("inlineCode",{parentName:"p"},"Running")," if at least one of its primary containers starts ",(0,i.kt)("inlineCode",{parentName:"p"},"OK"),", and then through either the ",(0,i.kt)("inlineCode",{parentName:"p"},"Succeeded")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"Failed")," phases depending on whether any container in the Pod terminated in failure."),(0,i.kt)("p",null,"These phase definitions can fulfill basic Pod change scenarios, but it are ambiguous.\nActually, before pod upgrade or ready, it is necessary to have some check mechanisms in place to ensure the safety of pod changes. Fortunately, ",(0,i.kt)("a",{parentName:"p",href:"/docs/operating/concepts/podopslifecycle"},"PodOpsLifecycle")," extends and supports some check stages: ",(0,i.kt)("inlineCode",{parentName:"p"},"PreCheck")," before pod upgrade and ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," before pod ready."),(0,i.kt)("p",null,"To ensure a more fine-grained and controlled change process for Pods, we introduce custom rules or perform additional tasks as prerequisites for state transitions before the desired state of a Pod is achieved. Similar to the Pod ",(0,i.kt)("inlineCode",{parentName:"p"},"readinessGates"),", where certain conditions must be met for a Pod to be considered readiness. For example, we consider a Pod ready for the ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," phase only if it has specific labels. For this purpose, we introduce the ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," as a prerequisite for the state transition of a Pod."),(0,i.kt)("h2",{id:"rule-definition"},"Rule Definition"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," to define a set of transition rules for your workload pods.\nEach rule will be executed at the corresponding stage, and it will be blocked if the conditions are not met."),(0,i.kt)("p",null,"Here is an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n name: podtransitionrule-sample\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n - stage: PreCheck # stages are supported by PodOpsLifecycle. Defaults to PreCheck.\n labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n name: labelCheck\n - stage: PostCheck\n webhook:\n clientConfig:\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id # URL parameter key to carry trace ID when fetching result. Defaults to task-id in form 'QueryUrl=URL?rawQueryKey='\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef: \n fieldPath: status.podIP\n name: webhookCheck\n selector: # select pods in effect\n matchLabels:\n app: foo\n")),(0,i.kt)("h3",{id:"available-policy"},"Available Policy"),(0,i.kt)("p",null,"An ",(0,i.kt)("inlineCode",{parentName:"p"},"availablePolicy")," rule defines the availability strategy during the Pod update process."),(0,i.kt)("h4",{id:"maxunavailable"},"maxUnavailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n maxUnavailable: \n value: 50% # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailableValue")," is the maximum number of pods that can be unavailable during the update.\nValue can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).\nAbsolute number is calculated from percentage by rounding down.\nThis can not be 0."),(0,i.kt)("h4",{id:"minavailable"},"minAvailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n minAvailable:\n value: 5 # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"minAvailableValue")," is the minimum number of pods that should be available during the update."),(0,i.kt)("h3",{id:"label-check"},"Label Check"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"labelCheck")," rule is used to check if labels are satisfied.\nYou can define your own labels as change check conditions and modify the labels according to your needs."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n matchExpressions:\n - key: app.custom/forbidden \n operator: DoesNotExist\n")),(0,i.kt)("h3",{id:"webhook"},"Webhook"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"webhook")," is an HTTP callback, based on which a external web application can determine whether a pod can pass this check."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"An HTTP POST occurs first when pods entries the configured stage which defaults PreCheck."),(0,i.kt)("li",{parentName:"ul"},"If ",(0,i.kt)("inlineCode",{parentName:"li"},"poll")," is provided, this rule then keeps calling polling url to fetch a long running job result. This job can be located by ",(0,i.kt)("inlineCode",{parentName:"li"},"task-id")," returned from the response of the first request. ")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"webhook:\n clientConfig: # custom server config\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol without poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": false,\n "message": "msg", \n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating all pods approved or not. If it's ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", the ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," field can be used to approve partial pods."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol with poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "poll": true, // required to indicate polling calls is necessary\n "taskId": , // required to to fetch polling result\n "message": "msg"\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating whether the first request is success or not. If true and field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true")," (or field ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),"), PodTransisionRule will then begin to keep calling poll URL to fetch process result.\nField ",(0,i.kt)("inlineCode",{parentName:"p"},"taskId")," is required for polling. "),(0,i.kt)("p",null,"The request for polling is GET method and in form of ",(0,i.kt)("inlineCode",{parentName:"p"},"QueryUrl=URL?task-id="),". The parameter key in this URL defaults ",(0,i.kt)("inlineCode",{parentName:"p"},"task-id"),", if using ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in above response. It would be ",(0,i.kt)("inlineCode",{parentName:"p"},"trace-id")," if using ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in above response.\nUsers can also indicate the key by field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll.rawQueryKey"),"."),(0,i.kt)("p",null,"The response from polling call is expected like following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "message": "msg",\n "finished": false,\n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"success")," is supposed to be true, if there is no error. If all pods is approved, ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," should be ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),".\nIf ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," can be used to allow partial pods to be approved."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/237b575e.15551eb2.js b/assets/js/237b575e.45b6ef1e.js similarity index 59% rename from assets/js/237b575e.15551eb2.js rename to assets/js/237b575e.45b6ef1e.js index 62e8bc6e547..295e804548e 100644 --- a/assets/js/237b575e.15551eb2.js +++ b/assets/js/237b575e.45b6ef1e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4599],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),u=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=u(r),d=a,f=m["".concat(i,".").concat(d)]||m[d]||c[d]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,l[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",s={unversionedId:"kusion/reference/modules/catalog-models/trait/opsrule",id:"kusion/reference/modules/catalog-models/trait/opsrule",title:"opsrule",description:"Schema OpsRule",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/trait",slug:"/kusion/reference/modules/catalog-models/trait/opsrule",permalink:"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"prometheus",permalink:"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus"},next:{title:"job",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/job"}},i={},u=[{value:"Schema OpsRule",id:"schema-opsrule",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("h2",{id:"schema-opsrule"},"Schema OpsRule"),(0,a.kt)("p",null,"OpsRule describes operation rules for various Day-2 Operations. Once declared, these",(0,a.kt)("br",null),"operation rules will be checked before any Day-2 operations."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},'"25%"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.trait as t\n\nopsRule : t.OpsRule {\n maxUnavailable: "30%"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4599],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),u=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=u(r),d=a,f=m["".concat(i,".").concat(d)]||m[d]||c[d]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,l[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",s={unversionedId:"kusion/reference/modules/catalog-models/trait/opsrule",id:"kusion/reference/modules/catalog-models/trait/opsrule",title:"opsrule",description:"Schema OpsRule",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/trait",slug:"/kusion/reference/modules/catalog-models/trait/opsrule",permalink:"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"prometheus",permalink:"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus"},next:{title:"job",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/job"}},i={},u=[{value:"Schema OpsRule",id:"schema-opsrule",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("h2",{id:"schema-opsrule"},"Schema OpsRule"),(0,a.kt)("p",null,"OpsRule describes operation rules for various Day-2 Operations. Once declared, these",(0,a.kt)("br",null),"operation rules will be checked before any Day-2 operations."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},'"25%"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.trait as t\n\nopsRule : t.OpsRule {\n maxUnavailable: "30%"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/23bbb932.52032b41.js b/assets/js/23bbb932.52032b41.js deleted file mode 100644 index 40a68378b6b..00000000000 --- a/assets/js/23bbb932.52032b41.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5856],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),u=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=u(e.components);return n.createElement(l.Provider,{value:r},e.children)},c={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=o,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||s;return t?n.createElement(f,a(a({ref:r},p),{},{components:t})):n.createElement(f,a({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var s=t.length,a=new Array(s);a[0]=d;var i={};for(var l in r)hasOwnProperty.call(r,l)&&(i[l]=r[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,a[1]=i;for(var u=2;u{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var n=t(87462),o=(t(67294),t(3905));const s={},a="Roadmap",i={unversionedId:"kusion/reference/roadmap",id:"version-v0.10/kusion/reference/roadmap",title:"Roadmap",description:"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/3-roadmap.md",sourceDirName:"kusion/6-reference",slug:"/kusion/reference/roadmap",permalink:"/docs/kusion/reference/roadmap",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/3-roadmap.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Resource Naming Conventions",permalink:"/docs/kusion/reference/modules/naming-conventions"},next:{title:"Installation",permalink:"/docs/kusion/faq/install-error"}},l={},u=[{value:"Resource Ecosystem",id:"resource-ecosystem",level:2},{value:"App Progressive Rollout",id:"app-progressive-rollout",level:2},{value:"Custom Pipelines",id:"custom-pipelines",level:2},{value:"Runtime Plugin",id:"runtime-plugin",level:2}],p={toc:u};function c(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"roadmap"},"Roadmap"),(0,o.kt)("p",null,"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"GitHub Issue Tracker")),(0,o.kt)("h2",{id:"resource-ecosystem"},"Resource Ecosystem"),(0,o.kt)("p",null,"We plan to expand the range of resource types that our platform can handle. This includes not only traditional cloud IaaS resources, but also popular cloud-native products such as Prometheus, istio and Argo. By supporting a wider variety of resources, we aim to address the heterogeneous needs of modern applications and allow users to harness the full power of the cloud-native technologies."),(0,o.kt)("h2",{id:"app-progressive-rollout"},"App Progressive Rollout"),(0,o.kt)("p",null,"One of the key challenges in delivering applications at scale is to balance the need for speed with the need for reliability. To help our users achieve this balance, we will introduce progressive rollout strategies, such as canary release, rolling release, and percentage release. These techniques enable users to test new features or versions on a small subset of their users or infrastructure before rolling them out to the entire system. By doing so, users can minimize the risk of downtime or errors caused by untested changes."),(0,o.kt)("h2",{id:"custom-pipelines"},"Custom Pipelines"),(0,o.kt)("p",null,"Thie current workflow of KusionStack is ",(0,o.kt)("inlineCode",{parentName:"p"},"write"),",",(0,o.kt)("inlineCode",{parentName:"p"},"preview")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"apply"),", but to handle more complex deployments we need to empower users to customize the deployment pipelines to fit their specific workflows and requirements. This includes the ability to define custom stages, add or remove steps, and integrate with third-party tools. With customizable pipelines, users can streamline their deployment process, automate repetitive tasks, and satisfy their own needs by themselves."),(0,o.kt)("h2",{id:"runtime-plugin"},"Runtime Plugin"),(0,o.kt)("p",null,"We have already supported IaaS cloud resources and Kubernetes resources, but we need a more flexible mechanism to support a broader range of on-premise infrastructure. By supporting a diverse set of infrastructures, we can help users avoid vendor lock-in, optimize their resource usage, and scale their applications across different regions and geographies."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/23bbb932.726ad797.js b/assets/js/23bbb932.726ad797.js new file mode 100644 index 00000000000..e1887e42a4f --- /dev/null +++ b/assets/js/23bbb932.726ad797.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5856],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),u=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=u(e.components);return n.createElement(l.Provider,{value:r},e.children)},c={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=o,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||s;return t?n.createElement(f,a(a({ref:r},p),{},{components:t})):n.createElement(f,a({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var s=t.length,a=new Array(s);a[0]=d;var i={};for(var l in r)hasOwnProperty.call(r,l)&&(i[l]=r[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,a[1]=i;for(var u=2;u{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var n=t(87462),o=(t(67294),t(3905));const s={},a="Roadmap",i={unversionedId:"kusion/reference/roadmap",id:"version-v0.10/kusion/reference/roadmap",title:"Roadmap",description:"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/3-roadmap.md",sourceDirName:"kusion/6-reference",slug:"/kusion/reference/roadmap",permalink:"/docs/kusion/reference/roadmap",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/3-roadmap.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Resource Naming Conventions",permalink:"/docs/kusion/reference/modules/naming-conventions"},next:{title:"Installation",permalink:"/docs/kusion/faq/install-error"}},l={},u=[{value:"Resource Ecosystem",id:"resource-ecosystem",level:2},{value:"App Progressive Rollout",id:"app-progressive-rollout",level:2},{value:"Custom Pipelines",id:"custom-pipelines",level:2},{value:"Runtime Plugin",id:"runtime-plugin",level:2}],p={toc:u};function c(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"roadmap"},"Roadmap"),(0,o.kt)("p",null,"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"GitHub Issue Tracker")),(0,o.kt)("h2",{id:"resource-ecosystem"},"Resource Ecosystem"),(0,o.kt)("p",null,"We plan to expand the range of resource types that our platform can handle. This includes not only traditional cloud IaaS resources, but also popular cloud-native products such as Prometheus, istio and Argo. By supporting a wider variety of resources, we aim to address the heterogeneous needs of modern applications and allow users to harness the full power of the cloud-native technologies."),(0,o.kt)("h2",{id:"app-progressive-rollout"},"App Progressive Rollout"),(0,o.kt)("p",null,"One of the key challenges in delivering applications at scale is to balance the need for speed with the need for reliability. To help our users achieve this balance, we will introduce progressive rollout strategies, such as canary release, rolling release, and percentage release. These techniques enable users to test new features or versions on a small subset of their users or infrastructure before rolling them out to the entire system. By doing so, users can minimize the risk of downtime or errors caused by untested changes."),(0,o.kt)("h2",{id:"custom-pipelines"},"Custom Pipelines"),(0,o.kt)("p",null,"Thie current workflow of KusionStack is ",(0,o.kt)("inlineCode",{parentName:"p"},"write"),",",(0,o.kt)("inlineCode",{parentName:"p"},"preview")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"apply"),", but to handle more complex deployments we need to empower users to customize the deployment pipelines to fit their specific workflows and requirements. This includes the ability to define custom stages, add or remove steps, and integrate with third-party tools. With customizable pipelines, users can streamline their deployment process, automate repetitive tasks, and satisfy their own needs by themselves."),(0,o.kt)("h2",{id:"runtime-plugin"},"Runtime Plugin"),(0,o.kt)("p",null,"We have already supported IaaS cloud resources and Kubernetes resources, but we need a more flexible mechanism to support a broader range of on-premise infrastructure. By supporting a diverse set of infrastructures, we can help users avoid vendor lock-in, optimize their resource usage, and scale their applications across different regions and geographies."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/26fe9297.96894e7f.js b/assets/js/26fe9297.96894e7f.js new file mode 100644 index 00000000000..f252f276ac9 --- /dev/null +++ b/assets/js/26fe9297.96894e7f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[192],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(h,a(a({ref:t},c),{},{components:n})):i.createElement(h,a({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),r=(n(67294),n(3905));const o={},a="Expose Application Service Deployed on CSP Kubernetes",s={unversionedId:"kusion/guides/cloud-resources/expose-service",id:"version-v0.9/kusion/guides/cloud-resources/expose-service",title:"Expose Application Service Deployed on CSP Kubernetes",description:"Deploying application on the Kuberentes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many individuals and enterprises. Kusion has a good integration with CSP Kuberentes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.",source:"@site/versioned_docs/version-v0.9/kusion/guides/cloud-resources/expose-service.md",sourceDirName:"kusion/guides/cloud-resources",slug:"/kusion/guides/cloud-resources/expose-service",permalink:"/docs/v0.9/kusion/guides/cloud-resources/expose-service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/cloud-resources/expose-service.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/v0.9/kusion/guides/cloud-resources/database"},next:{title:"Kubernetes",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Expose Service Publicly",id:"expose-service-publicly",level:2},{value:"Write Configuration Code",id:"write-configuration-code",level:3},{value:"Preview and Apply",id:"preview-and-apply",level:3},{value:"Verify Accessibility",id:"verify-accessibility",level:3},{value:"Expose Service Inside Cluster",id:"expose-service-inside-cluster",level:2},{value:"Summary",id:"summary",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"expose-application-service-deployed-on-csp-kubernetes"},"Expose Application Service Deployed on CSP Kubernetes"),(0,r.kt)("p",null,"Deploying application on the Kuberentes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many individuals and enterprises. Kusion has a good integration with CSP Kuberentes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way. "),(0,r.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on CSP Kubernetes. In this article, ",(0,r.kt)("em",{parentName:"p"},(0,r.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/blob/main/example/nginx/dev/main.k"},"exposing the service of nginx"),' (referred to "the example" in the below)')," is given as an example."),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Create a Kubernetes cluster, the following CSP Kubernetes services are supported."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/kubernetes"},"Alibaba Cloud Container Service for Kubernetes (ACK)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://aws.amazon.com/eks"},"Amazon Elastic Kubernetes Service (EKS)"),".")),(0,r.kt)("p",null,"After creating the cluster, get the kube-config and export it, so that Kusion can access the cluster."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export KUBE_CONFIG=""\n')),(0,r.kt)("h2",{id:"expose-service-publicly"},"Expose Service Publicly"),(0,r.kt)("p",null,"If you want the application can be accessed from outside the cluster, you should expose the service publicly. Follow the steps below, you will simply hit the goal."),(0,r.kt)("h3",{id:"write-configuration-code"},"Write Configuration Code"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n nginx: c.Container {\n image = "nginx:1.25.2"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n protocol: "TCP"\n public: True\n }\n ]\n }\n}\n')),(0,r.kt)("p",null,"The code shown above describes how to expose service publicly of the example on ACK. Kusion use schema ",(0,r.kt)("inlineCode",{parentName:"p"},"Port")," to describe the network configuration, the primary fields of Port are as follows:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"type: the CSP providing Kubernetes service, support ",(0,r.kt)("inlineCode",{parentName:"li"},"aliyun")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"aws")),(0,r.kt)("li",{parentName:"ul"},"port: port number to expose service"),(0,r.kt)("li",{parentName:"ul"},"protocol: protocol to expose service, support ",(0,r.kt)("inlineCode",{parentName:"li"},"TCP")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"UDP")),(0,r.kt)("li",{parentName:"ul"},"public: whether to public the service")),(0,r.kt)("p",null,"To public the service, you should assign the ",(0,r.kt)("inlineCode",{parentName:"p"},"type")," (aliyun for ACK, aws for EKS), and set ",(0,r.kt)("inlineCode",{parentName:"p"},"public")," as True. Besides, schema ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," should be used to describe the workload configuration."),(0,r.kt)("p",null,"That's all what you need to configure! Next, preview and apply the configuration, the application will get deployed and exposed publicly."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Kusion uses Load Balancer (LB) provided by the CSP to expose service publicly. For more detailed network configuration, please refer to ",(0,r.kt)("a",{parentName:"p",href:"../../config-walkthrough/networking"},"Application Networking"))),(0,r.kt)("h3",{id:"preview-and-apply"},"Preview and Apply"),(0,r.kt)("p",null,"Execute ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion preview")," under the stack path, you will get what will be created in the real infrastructure. The picture below gives the preview result of the example. A Namespace, Service and Deployment will be created, which meets the expectation. The service name has a suffix ",(0,r.kt)("inlineCode",{parentName:"p"},"public"),", which shows it can be accessed publicly."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"preview-public",src:n(85091).Z,width:"1540",height:"262"})),(0,r.kt)("p",null,"Then, execute ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply --yes")," to do the real deploying job. Just a command and a few minutes, you have accomplished deploying application and expose it publicly."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply-public",src:n(97932).Z,width:"1558",height:"480"})),(0,r.kt)("h3",{id:"verify-accessibility"},"Verify Accessibility"),(0,r.kt)("p",null,"In the example, the kubernetes Namespace whose name is nginx, and a Service and Deployment under the Namespace should be created. Use ",(0,r.kt)("inlineCode",{parentName:"p"},"kubectl get")," to check, the Service whose type is ",(0,r.kt)("inlineCode",{parentName:"p"},"LoadBalancer")," and Deployment are created indeed. And the Service has ",(0,r.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," 106.5.190.109, which means it can be accessed from outside the cluster."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"k8s-resource-public",src:n(68162).Z,width:"1662",height:"216"})),(0,r.kt)("p",null,"Visit the ",(0,r.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," via browser, the correct result is returned, which illustrates the servie get publicly exposed successfully."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"result-public",src:n(65377).Z,width:"1494",height:"682"})),(0,r.kt)("h2",{id:"expose-service-inside-cluster"},"Expose Service Inside Cluster"),(0,r.kt)("p",null,"If you only need the application can be accessed inside the cluster, just configure ",(0,r.kt)("inlineCode",{parentName:"p"},"Public")," as False in schema ",(0,r.kt)("inlineCode",{parentName:"p"},"Port"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n ...\n ports: [\n n.Port {\n ...\n public: False\n }\n ]\n }\n}\n")),(0,r.kt)("p",null,"Execute ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply --yes"),", the generated Service has suffix ",(0,r.kt)("inlineCode",{parentName:"p"},"private"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply-private",src:n(96057).Z,width:"1612",height:"494"})),(0,r.kt)("p",null,"And the Service type is ",(0,r.kt)("inlineCode",{parentName:"p"},"ClusterIP"),", only has ",(0,r.kt)("inlineCode",{parentName:"p"},"CLUSTER_IP")," and no ",(0,r.kt)("inlineCode",{parentName:"p"},"EXTERNAL_IP"),", which means it cannot get accessed from outside the cluster. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"k8s-resource-private",src:n(64600).Z,width:"1542",height:"210"})),(0,r.kt)("h2",{id:"summary"},"Summary"),(0,r.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on the CSP Kubernetes. By configuring schema Port, Kusion enables you expose service simply and efficiently."))}u.isMDXComponent=!0},96057:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-private-a1d1f3a1b5afac81cea19f189d08222d.png"},97932:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-public-d89cdb3ba9d96904e1820bfbcf4671d8.png"},64600:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-private-62ab14b1de35205866b64a0d63180450.png"},68162:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-public-66ffcb206b33c5fc6f1a779bc10b3e93.png"},85091:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/preview-public-eea90eec123cd2fc13536be2b645e900.png"},65377:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/result-public-4bf3f757b0a43c78464ec9bcd75a4b2f.png"}}]); \ No newline at end of file diff --git a/assets/js/26fe9297.bbc7d4f8.js b/assets/js/26fe9297.bbc7d4f8.js deleted file mode 100644 index bae86c82d86..00000000000 --- a/assets/js/26fe9297.bbc7d4f8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[192],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(h,a(a({ref:t},c),{},{components:n})):i.createElement(h,a({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),r=(n(67294),n(3905));const o={},a="Expose Application Service Deployed on CSP Kubernetes",s={unversionedId:"kusion/guides/cloud-resources/expose-service",id:"version-v0.9/kusion/guides/cloud-resources/expose-service",title:"Expose Application Service Deployed on CSP Kubernetes",description:"Deploying application on the Kuberentes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many individuals and enterprises. Kusion has a good integration with CSP Kuberentes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.",source:"@site/versioned_docs/version-v0.9/kusion/guides/cloud-resources/expose-service.md",sourceDirName:"kusion/guides/cloud-resources",slug:"/kusion/guides/cloud-resources/expose-service",permalink:"/docs/v0.9/kusion/guides/cloud-resources/expose-service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/cloud-resources/expose-service.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/v0.9/kusion/guides/cloud-resources/database"},next:{title:"Kubernetes",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Expose Service Publicly",id:"expose-service-publicly",level:2},{value:"Write Configuration Code",id:"write-configuration-code",level:3},{value:"Preview and Apply",id:"preview-and-apply",level:3},{value:"Verify Accessibility",id:"verify-accessibility",level:3},{value:"Expose Service Inside Cluster",id:"expose-service-inside-cluster",level:2},{value:"Summary",id:"summary",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"expose-application-service-deployed-on-csp-kubernetes"},"Expose Application Service Deployed on CSP Kubernetes"),(0,r.kt)("p",null,"Deploying application on the Kuberentes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many individuals and enterprises. Kusion has a good integration with CSP Kuberentes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way. "),(0,r.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on CSP Kubernetes. In this article, ",(0,r.kt)("em",{parentName:"p"},(0,r.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/blob/main/example/nginx/dev/main.k"},"exposing the service of nginx"),' (referred to "the example" in the below)')," is given as an example."),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Create a Kubernetes cluster, the following CSP Kubernetes services are supported."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/kubernetes"},"Alibaba Cloud Container Service for Kubernetes (ACK)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://aws.amazon.com/eks"},"Amazon Elastic Kubernetes Service (EKS)"),".")),(0,r.kt)("p",null,"After creating the cluster, get the kube-config and export it, so that Kusion can access the cluster."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export KUBE_CONFIG=""\n')),(0,r.kt)("h2",{id:"expose-service-publicly"},"Expose Service Publicly"),(0,r.kt)("p",null,"If you want the application can be accessed from outside the cluster, you should expose the service publicly. Follow the steps below, you will simply hit the goal."),(0,r.kt)("h3",{id:"write-configuration-code"},"Write Configuration Code"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n nginx: c.Container {\n image = "nginx:1.25.2"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n protocol: "TCP"\n public: True\n }\n ]\n }\n}\n')),(0,r.kt)("p",null,"The code shown above describes how to expose service publicly of the example on ACK. Kusion use schema ",(0,r.kt)("inlineCode",{parentName:"p"},"Port")," to describe the network configuration, the primary fields of Port are as follows:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"type: the CSP providing Kubernetes service, support ",(0,r.kt)("inlineCode",{parentName:"li"},"aliyun")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"aws")),(0,r.kt)("li",{parentName:"ul"},"port: port number to expose service"),(0,r.kt)("li",{parentName:"ul"},"protocol: protocol to expose service, support ",(0,r.kt)("inlineCode",{parentName:"li"},"TCP")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"UDP")),(0,r.kt)("li",{parentName:"ul"},"public: whether to public the service")),(0,r.kt)("p",null,"To public the service, you should assign the ",(0,r.kt)("inlineCode",{parentName:"p"},"type")," (aliyun for ACK, aws for EKS), and set ",(0,r.kt)("inlineCode",{parentName:"p"},"public")," as True. Besides, schema ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," should be used to describe the workload configuration."),(0,r.kt)("p",null,"That's all what you need to configure! Next, preview and apply the configuration, the application will get deployed and exposed publicly."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Kusion uses Load Balancer (LB) provided by the CSP to expose service publicly. For more detailed network configuration, please refer to ",(0,r.kt)("a",{parentName:"p",href:"../../config-walkthrough/networking"},"Application Networking"))),(0,r.kt)("h3",{id:"preview-and-apply"},"Preview and Apply"),(0,r.kt)("p",null,"Execute ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion preview")," under the stack path, you will get what will be created in the real infrastructure. The picture below gives the preview result of the example. A Namespace, Service and Deployment will be created, which meets the expectation. The service name has a suffix ",(0,r.kt)("inlineCode",{parentName:"p"},"public"),", which shows it can be accessed publicly."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"preview-public",src:n(85091).Z,width:"1540",height:"262"})),(0,r.kt)("p",null,"Then, execute ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply --yes")," to do the real deploying job. Just a command and a few minutes, you have accomplished deploying application and expose it publicly."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply-public",src:n(97932).Z,width:"1558",height:"480"})),(0,r.kt)("h3",{id:"verify-accessibility"},"Verify Accessibility"),(0,r.kt)("p",null,"In the example, the kubernetes Namespace whose name is nginx, and a Service and Deployment under the Namespace should be created. Use ",(0,r.kt)("inlineCode",{parentName:"p"},"kubectl get")," to check, the Service whose type is ",(0,r.kt)("inlineCode",{parentName:"p"},"LoadBalancer")," and Deployment are created indeed. And the Service has ",(0,r.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," 106.5.190.109, which means it can be accessed from outside the cluster."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"k8s-resource-public",src:n(68162).Z,width:"1662",height:"216"})),(0,r.kt)("p",null,"Visit the ",(0,r.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," via browser, the correct result is returned, which illustrates the servie get publicly exposed successfully."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"result-public",src:n(65377).Z,width:"1494",height:"682"})),(0,r.kt)("h2",{id:"expose-service-inside-cluster"},"Expose Service Inside Cluster"),(0,r.kt)("p",null,"If you only need the application can be accessed inside the cluster, just configure ",(0,r.kt)("inlineCode",{parentName:"p"},"Public")," as False in schema ",(0,r.kt)("inlineCode",{parentName:"p"},"Port"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n ...\n ports: [\n n.Port {\n ...\n public: False\n }\n ]\n }\n}\n")),(0,r.kt)("p",null,"Execute ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply --yes"),", the generated Service has suffix ",(0,r.kt)("inlineCode",{parentName:"p"},"private"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply-private",src:n(96057).Z,width:"1612",height:"494"})),(0,r.kt)("p",null,"And the Service type is ",(0,r.kt)("inlineCode",{parentName:"p"},"ClusterIP"),", only has ",(0,r.kt)("inlineCode",{parentName:"p"},"CLUSTER_IP")," and no ",(0,r.kt)("inlineCode",{parentName:"p"},"EXTERNAL_IP"),", which means it cannot get accessed from outside the cluster. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"k8s-resource-private",src:n(64600).Z,width:"1542",height:"210"})),(0,r.kt)("h2",{id:"summary"},"Summary"),(0,r.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on the CSP Kubernetes. By configuring schema Port, Kusion enables you expose service simply and efficiently."))}u.isMDXComponent=!0},96057:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-private-a1d1f3a1b5afac81cea19f189d08222d.png"},97932:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-public-d89cdb3ba9d96904e1820bfbcf4671d8.png"},64600:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-private-62ab14b1de35205866b64a0d63180450.png"},68162:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-public-66ffcb206b33c5fc6f1a779bc10b3e93.png"},85091:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/preview-public-eea90eec123cd2fc13536be2b645e900.png"},65377:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/result-public-4bf3f757b0a43c78464ec9bcd75a4b2f.png"}}]); \ No newline at end of file diff --git a/assets/js/28005ec6.5b4c5ee5.js b/assets/js/28005ec6.5b4c5ee5.js deleted file mode 100644 index ef29d5a20e2..00000000000 --- a/assets/js/28005ec6.5b4c5ee5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[858],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(r),m=a,k=p["".concat(i,".").concat(m)]||p[m]||u[m]||l;return r?n.createElement(k,o(o({ref:t},d),{},{components:r})):n.createElement(k,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=p;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={},o="secret",s={unversionedId:"kusion/reference/modules/catalog-models/internal/secret/secret",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/secret/secret",title:"secret",description:"Schema Secret",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/secret",slug:"/kusion/reference/modules/catalog-models/internal/secret/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/secret/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/kusion/reference/modules/catalog-models/internal/network/port"},next:{title:"prometheus",permalink:"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus"}},i={},c=[{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secret"},"secret"),(0,a.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,a.kt)("p",null,"Secrets are used to provide data that is considered sensitive like passwords, API keys,",(0,a.kt)("br",null),"TLS certificates, tokens or other credentials."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "token" ',"|",' "opaque" ',"|",' "certificate" ',"|",' "external"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"params"),(0,a.kt)("br",null),"Collection of parameters used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"data"),(0,a.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"immutable"),(0,a.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/28005ec6.6599965d.js b/assets/js/28005ec6.6599965d.js new file mode 100644 index 00000000000..f8914afa7ef --- /dev/null +++ b/assets/js/28005ec6.6599965d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[858],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(r),m=a,k=p["".concat(s,".").concat(m)]||p[m]||u[m]||l;return r?n.createElement(k,o(o({ref:t},d),{},{components:r})):n.createElement(k,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=p;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>i,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={},o="secret",i={unversionedId:"kusion/reference/modules/catalog-models/internal/secret/secret",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/secret/secret",title:"secret",description:"Schema Secret",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/secret",slug:"/kusion/reference/modules/catalog-models/internal/secret/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/secret/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/kusion/reference/modules/catalog-models/internal/network/port"},next:{title:"prometheus",permalink:"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus"}},s={},c=[{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secret"},"secret"),(0,a.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,a.kt)("p",null,"Secrets are used to provide data that is considered sensitive like passwords, API keys,",(0,a.kt)("br",null),"TLS certificates, tokens or other credentials."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "token" ',"|",' "opaque" ',"|",' "certificate" ',"|",' "external"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"params"),(0,a.kt)("br",null),"Collection of parameters used to facilitate programmatic handling of secret data."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"data"),(0,a.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"immutable"),(0,a.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/281e8991.490faf47.js b/assets/js/281e8991.490faf47.js new file mode 100644 index 00000000000..385c8a29b23 --- /dev/null +++ b/assets/js/281e8991.490faf47.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4960],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(t),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(f,i(i({ref:n},p),{},{components:t})):a.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=t.length,i=new Array(r);i[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var a=t(87462),o=(t(67294),t(3905));const r={},i="Workspace",s={unversionedId:"kusion/concepts/workspace",id:"version-v0.10/kusion/concepts/workspace",title:"Workspace",description:"Definition",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/4-workspace.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/workspace",permalink:"/docs/kusion/concepts/workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/4-workspace.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Module",permalink:"/docs/kusion/concepts/kusion-module"},next:{title:"AppConfiguration",permalink:"/docs/kusion/concepts/app-configuration"}},l={},c=[{value:"Definition",id:"definition",level:2},{value:"Structure",id:"structure",level:2},{value:"Workflow",id:"workflow",level:2}],p={toc:c};function d(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"workspace"},"Workspace"),(0,o.kt)("h2",{id:"definition"},"Definition"),(0,o.kt)("p",null,"A workspace is a logical concept that represents a target environment for deploying a stack. It contains platform configurations, including a set of configurations, Kubeconfig, and provider authentication information, all of which can be reused by multiple stacks. We recommend organizing workspaces by SDLC (Software Development Life Cycle) phases or by cloud vendors. For example, workspaces could be named ",(0,o.kt)("inlineCode",{parentName:"p"},"dev"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"staging"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"prod"),", or according to cloud vendors such as ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Azure"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"Alibaba Cloud"),"."),(0,o.kt)("p",null,"For clarity, workspace data is categorized into two types: configuration and secret. The configuration data is non-sensitive and is stored locally in YAML files, including module inputs, runtime configurations, and backend configurations. The secret data is sensitive and should be stored as workspace variables. For example, when using AWS, users must set the correct workspace variables for ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_ACCESS_KEY_ID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_SECRET_ACCESS_KEY"),"."),(0,o.kt)("p",null,"If a set of data items serves the same target and contains one or more sensitive data items, then the entire set should be managed using environment variables. This approach ensures a consistent and seamless user experience."),(0,o.kt)("p",null,"Each stack must be associated with a single workspace, and ",(0,o.kt)("strong",{parentName:"p"},"the stack's name must be the same as the workspace it will be deployed to"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"workspace-project-stack",src:t(27137).Z,width:"587",height:"362"})),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In product design, Kusion does not support deploying to multiple clouds or multiple regions within a single workspace. While users can technically define a module that provisions resources across multiple clouds or regions, Kusion does not recommend this practice and will not provide technical support for such configurations. If a platform team needs to manage resources across multiple clouds or regions, they should create separate workspaces.")),(0,o.kt)("h2",{id:"structure"},"Structure"),(0,o.kt)("p",null,"The configuration of a workspace is stored in a single YAML file, which consists of three components: ",(0,o.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"backends"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"module")," configuration comprises default configs and several patchers, where the name of each patcher must not be ",(0,o.kt)("strong",{parentName:"p"},"default"),". Configurations in the ",(0,o.kt)("inlineCode",{parentName:"p"},"default")," block will be applied to all applications in this workspace and configurations in the patcher block will only be applied to projects in the ",(0,o.kt)("inlineCode",{parentName:"p"},"projectSelector"),". Values in patchers will override default configs with the same field name.\nFor the default configuration or a specific patcher, field keys must be the same as module input field names defined by the module. Module configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/modules"},"Kusion Modules")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime")," configuration currently supports Kubernetes and Terraform, where the former includes the field ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeConfig")," to specify the path of Kube Config, and the latter contains data for Terraform providers, which vary across different providers. For Terraform providers, sensitive data should be stored in environment variables."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"backend")," configuration currently supports local, oss, s3, database, and http. This defines the backend for state, intent, and other Kusion data that may require storage in the future. This format requires that all Kusion data share the same backend. As with sensitive data in the runtime configuration, these details should also be stored in environment variables. Backend configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"backend-configuration"},"Backend Configuration")),(0,o.kt)("p",null,"An example is shown as below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# Module input, each with the format standard\uff1a\n# # :\n# # default: # default configurations, applied to all projects\n# # : \n# # : \n# # ...\n# # : #patcher configurations, applied to the projects assigned in projectSelector\n# # : \n# # ...\n# # projectSelector:\n# # - \n# # ...\nmodules:\n database:\n default:\n provider: aws\n size: 20\n instanceClass: db.t3.micro\n securityIPs:\n - 10.0.0.0/18\n smallClass:\n size: 50\n instanceClass: db.t3.small\n projectSelector:\n - foo\n - bar\n largeClass:\n instanceClass: db.t3.large\n projectSelector:\n - baz\n \n# A set of runtime configs, each with the format standard:\n# # :\n# # : \n# # : \n# # ...\nruntimes:\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n terraform:\n aws:\n version: 1.0.4\n source: hashicorp/aws\n region: us-east-1\n \n# A set of backend configs, each with the following format standard:\n# # :\n# # : \n# # : \n# # ...\nbackends:\n s3: \n bucket: kusion\n region: us-east-1\n")),(0,o.kt)("h2",{id:"workflow"},"Workflow"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Write the ",(0,o.kt)("inlineCode",{parentName:"li"},"workspace.yaml")," with the format shown above and fulfill all necessary fields."),(0,o.kt)("li",{parentName:"ol"},"Create a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce create -f "),"\nA new workspace configuration file named ",(0,o.kt)("inlineCode",{parentName:"li"},".yaml")," will be created under the path ",(0,o.kt)("inlineCode",{parentName:"li"},"$KUSION_PATH/.workspace"),", and the validation will be done before the creation."),(0,o.kt)("li",{parentName:"ol"},"Update a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce update -f "),"\nThe workspace will be updated with the latest values."),(0,o.kt)("li",{parentName:"ol"},"Delete a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion workspace delete ")," if you don't need it anymore.")),(0,o.kt)("p",null,"More workspace commands can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands/kusion-workspace"},"reference"),"."))}d.isMDXComponent=!0},27137:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/workspace-project-stack-35aa4e25ab80fe4a1a6bbfbbe024e127.png"}}]); \ No newline at end of file diff --git a/assets/js/281e8991.d6d8d49d.js b/assets/js/281e8991.d6d8d49d.js deleted file mode 100644 index 2d42cc904a5..00000000000 --- a/assets/js/281e8991.d6d8d49d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4960],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(t),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(f,i(i({ref:n},p),{},{components:t})):a.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=t.length,i=new Array(r);i[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var a=t(87462),o=(t(67294),t(3905));const r={},i="Workspace",s={unversionedId:"kusion/concepts/workspace",id:"version-v0.10/kusion/concepts/workspace",title:"Workspace",description:"Definition",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/4-workspace.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/workspace",permalink:"/docs/kusion/concepts/workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/4-workspace.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Module",permalink:"/docs/kusion/concepts/kusion-module"},next:{title:"AppConfiguration",permalink:"/docs/kusion/concepts/app-configuration"}},l={},c=[{value:"Definition",id:"definition",level:2},{value:"Structure",id:"structure",level:2},{value:"Workflow",id:"workflow",level:2}],p={toc:c};function d(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"workspace"},"Workspace"),(0,o.kt)("h2",{id:"definition"},"Definition"),(0,o.kt)("p",null,"A workspace is a logical concept that represents a target environment for deploying a stack. It contains platform configurations, including a set of configurations, Kubeconfig, and provider authentication information, all of which can be reused by multiple stacks. We recommend organizing workspaces by SDLC (Software Development Life Cycle) phases or by cloud vendors. For example, workspaces could be named ",(0,o.kt)("inlineCode",{parentName:"p"},"dev"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"staging"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"prod"),", or according to cloud vendors such as ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Azure"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"Alibaba Cloud"),"."),(0,o.kt)("p",null,"For clarity, workspace data is categorized into two types: configuration and secret. The configuration data is non-sensitive and is stored locally in YAML files, including module inputs, runtime configurations, and backend configurations. The secret data is sensitive and should be stored as workspace variables. For example, when using AWS, users must set the correct workspace variables for ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_ACCESS_KEY_ID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_SECRET_ACCESS_KEY"),"."),(0,o.kt)("p",null,"If a set of data items serves the same target and contains one or more sensitive data items, then the entire set should be managed using environment variables. This approach ensures a consistent and seamless user experience."),(0,o.kt)("p",null,"Each stack must be associated with a single workspace, and ",(0,o.kt)("strong",{parentName:"p"},"the stack's name must be the same as the workspace it will be deployed to"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"workspace-project-stack",src:t(27137).Z,width:"587",height:"362"})),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In product design, Kusion does not support deploying to multiple clouds or multiple regions within a single workspace. While users can technically define a module that provisions resources across multiple clouds or regions, Kusion does not recommend this practice and will not provide technical support for such configurations. If a platform team needs to manage resources across multiple clouds or regions, they should create separate workspaces.")),(0,o.kt)("h2",{id:"structure"},"Structure"),(0,o.kt)("p",null,"The configuration of a workspace is stored in a single YAML file, which consists of three components: ",(0,o.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"backends"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"module")," configuration comprises default configs and several patchers, where the name of each patcher must not be ",(0,o.kt)("strong",{parentName:"p"},"default"),". Configurations in the ",(0,o.kt)("inlineCode",{parentName:"p"},"default")," block will be applied to all applications in this workspace and configurations in the patcher block will only be applied to projects in the ",(0,o.kt)("inlineCode",{parentName:"p"},"projectSelector"),". Values in patchers will override default configs with the same field name.\nFor the default configuration or a specific patcher, field keys must be the same as module input field names defined by the module. Module configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/modules"},"Kusion Modules")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime")," configuration currently supports Kubernetes and Terraform, where the former includes the field ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeConfig")," to specify the path of Kube Config, and the latter contains data for Terraform providers, which vary across different providers. For Terraform providers, sensitive data should be stored in environment variables."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"backend")," configuration currently supports local, oss, s3, database, and http. This defines the backend for state, intent, and other Kusion data that may require storage in the future. This format requires that all Kusion data share the same backend. As with sensitive data in the runtime configuration, these details should also be stored in environment variables. Backend configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"backend-configuration"},"Backend Configuration")),(0,o.kt)("p",null,"An example is shown as below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# Module input, each with the format standard\uff1a\n# # :\n# # default: # default configurations, applied to all projects\n# # : \n# # : \n# # ...\n# # : #patcher configurations, applied to the projects assigned in projectSelector\n# # : \n# # ...\n# # projectSelector:\n# # - \n# # ...\nmodules:\n database:\n default:\n provider: aws\n size: 20\n instanceClass: db.t3.micro\n securityIPs:\n - 10.0.0.0/18\n smallClass:\n size: 50\n instanceClass: db.t3.small\n projectSelector:\n - foo\n - bar\n largeClass:\n instanceClass: db.t3.large\n projectSelector:\n - baz\n \n# A set of runtime configs, each with the format standard:\n# # :\n# # : \n# # : \n# # ...\nruntimes:\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n terraform:\n aws:\n version: 1.0.4\n source: hashicorp/aws\n region: us-east-1\n \n# A set of backend configs, each with the following format standard:\n# # :\n# # : \n# # : \n# # ...\nbackends:\n s3: \n bucket: kusion\n region: us-east-1\n")),(0,o.kt)("h2",{id:"workflow"},"Workflow"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Write the ",(0,o.kt)("inlineCode",{parentName:"li"},"workspace.yaml")," with the format shown above and fulfill all necessary fields."),(0,o.kt)("li",{parentName:"ol"},"Create a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce create -f "),"\nA new workspace configuration file named ",(0,o.kt)("inlineCode",{parentName:"li"},".yaml")," will be created under the path ",(0,o.kt)("inlineCode",{parentName:"li"},"$KUSION_PATH/.workspace"),", and the validation will be done before the creation."),(0,o.kt)("li",{parentName:"ol"},"Update a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce update -f "),"\nThe workspace will be updated with the latest values."),(0,o.kt)("li",{parentName:"ol"},"Delete a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion workspace delete ")," if you don't need it anymore.")),(0,o.kt)("p",null,"More workspace commands can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands/kusion-workspace"},"reference"),"."))}d.isMDXComponent=!0},27137:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/workspace-project-stack-35aa4e25ab80fe4a1a6bbfbbe024e127.png"}}]); \ No newline at end of file diff --git a/assets/js/287f5fa1.e7768f6e.js b/assets/js/287f5fa1.75a3faa3.js similarity index 56% rename from assets/js/287f5fa1.e7768f6e.js rename to assets/js/287f5fa1.75a3faa3.js index a9538e1ad75..9cea744b7e3 100644 --- a/assets/js/287f5fa1.e7768f6e.js +++ b/assets/js/287f5fa1.75a3faa3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[159],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>k});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(n),k=o,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function k(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace delete",i={unversionedId:"kusion/reference/commands/kusion-workspace-delete",id:"version-v0.10/kusion/reference/commands/kusion-workspace-delete",title:"kusion workspace delete",description:"Delete a workspace",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-delete.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-delete",permalink:"/docs/kusion/reference/commands/kusion-workspace-delete",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-delete.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace create",permalink:"/docs/kusion/reference/commands/kusion-workspace-create"},next:{title:"kusion workspace list",permalink:"/docs/kusion/reference/commands/kusion-workspace-list"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-delete"},"kusion workspace delete"),(0,o.kt)("p",null,"Delete a workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command deletes a specified workspace."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace delete\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete a workspace\n kusion workspace delete dev\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for delete\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[159],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>k});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(n),k=o,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function k(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace delete",i={unversionedId:"kusion/reference/commands/kusion-workspace-delete",id:"version-v0.10/kusion/reference/commands/kusion-workspace-delete",title:"kusion workspace delete",description:"Delete a workspace",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-delete.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-delete",permalink:"/docs/kusion/reference/commands/kusion-workspace-delete",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-delete.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace create",permalink:"/docs/kusion/reference/commands/kusion-workspace-create"},next:{title:"kusion workspace list",permalink:"/docs/kusion/reference/commands/kusion-workspace-list"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-delete"},"kusion workspace delete"),(0,o.kt)("p",null,"Delete a workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command deletes a specified workspace."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace delete\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete a workspace\n kusion workspace delete dev\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for delete\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/28de08e8.9a8c6761.js b/assets/js/28de08e8.796c1f89.js similarity index 50% rename from assets/js/28de08e8.9a8c6761.js rename to assets/js/28de08e8.796c1f89.js index a99666ce3af..4b5c81013b4 100644 --- a/assets/js/28de08e8.9a8c6761.js +++ b/assets/js/28de08e8.796c1f89.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9533],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(k,l(l({ref:t},s),{},{components:r})):n.createElement(k,l({ref:t},s))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/catalog-models/internal/network/port",id:"kusion/reference/modules/catalog-models/internal/network/port",title:"port",description:"Schema Port",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/network",slug:"/kusion/reference/modules/catalog-models/internal/network/port",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/network/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"probe",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/"},next:{title:"secret",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/"}},p={},c=[{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],s={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("h2",{id:"schema-port"},"Schema Port"),(0,a.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,a.kt)("br",null),"get accessed."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The exposed port of the Service."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"80"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"targetPort"),(0,a.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"protocol"),(0,a.kt)("br",null),"The protocol to access the port."),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"public"),(0,a.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"False"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9533],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(k,l(l({ref:t},s),{},{components:r})):n.createElement(k,l({ref:t},s))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/catalog-models/internal/network/port",id:"kusion/reference/modules/catalog-models/internal/network/port",title:"port",description:"Schema Port",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/network",slug:"/kusion/reference/modules/catalog-models/internal/network/port",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/network/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"probe",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/"},next:{title:"secret",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/"}},p={},c=[{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],s={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("h2",{id:"schema-port"},"Schema Port"),(0,a.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,a.kt)("br",null),"get accessed."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The exposed port of the Service."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"80"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"targetPort"),(0,a.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"protocol"),(0,a.kt)("br",null),"The protocol to access the port."),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"public"),(0,a.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"False"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2b4be8fd.0ebc72ab.js b/assets/js/2b4be8fd.0ebc72ab.js deleted file mode 100644 index 62b6f4b1469..00000000000 --- a/assets/js/2b4be8fd.0ebc72ab.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3449],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(n),p=a,k=u["".concat(s,".").concat(p)]||u[p]||m[p]||o;return n?r.createElement(k,l(l({ref:t},d),{},{components:n})):r.createElement(k,l({ref:t},d))}));function p(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="common",i={unversionedId:"kusion/reference/modules/catalog-models/internal/common",id:"kusion/reference/modules/catalog-models/internal/common",title:"common",description:"Schema WorkloadBase",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal",slug:"/kusion/reference/modules/catalog-models/internal/common",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/common",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/postgres"},next:{title:"container",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/"}},s={},c=[{value:"Schema WorkloadBase",id:"schema-workloadbase",level:2},{value:"Attributes",id:"attributes",level:3}],d={toc:c};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"common"},"common"),(0,a.kt)("h2",{id:"schema-workloadbase"},"Schema WorkloadBase"),(0,a.kt)("p",null,"WorkloadBase defines set of attributes shared by different workload profile, e.g Service",(0,a.kt)("br",null),"and Job. You can inherit this Schema to reuse these common attributes."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"containers"),(0,a.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/#schema-container"},"container.Container"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"secrets")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/#schema-secret"},"secret.Secret"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2b4be8fd.ec338e27.js b/assets/js/2b4be8fd.ec338e27.js new file mode 100644 index 00000000000..e800a9a4e92 --- /dev/null +++ b/assets/js/2b4be8fd.ec338e27.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3449],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(n),p=a,k=u["".concat(s,".").concat(p)]||u[p]||m[p]||o;return n?r.createElement(k,l(l({ref:t},d),{},{components:n})):r.createElement(k,l({ref:t},d))}));function p(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="common",i={unversionedId:"kusion/reference/modules/catalog-models/internal/common",id:"kusion/reference/modules/catalog-models/internal/common",title:"common",description:"Schema WorkloadBase",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal",slug:"/kusion/reference/modules/catalog-models/internal/common",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/common",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/postgres"},next:{title:"container",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/"}},s={},c=[{value:"Schema WorkloadBase",id:"schema-workloadbase",level:2},{value:"Attributes",id:"attributes",level:3}],d={toc:c};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"common"},"common"),(0,a.kt)("h2",{id:"schema-workloadbase"},"Schema WorkloadBase"),(0,a.kt)("p",null,"WorkloadBase defines set of attributes shared by different workload profile, e.g Service",(0,a.kt)("br",null),"and Job. You can inherit this Schema to reuse these common attributes."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"containers"),(0,a.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/#schema-container"},"container.Container"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"secrets")),(0,a.kt)("td",{parentName:"tr",align:null},"{str: ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/#schema-secret"},"secret.Secret"),"}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2e98070f.462da715.js b/assets/js/2e98070f.462da715.js deleted file mode 100644 index 8de57d5c0c4..00000000000 --- a/assets/js/2e98070f.462da715.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1164],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),m=l(n),h=r,d=m["".concat(s,".").concat(h)]||m[h]||c[h]||i;return n?o.createElement(d,a(a({ref:t},u),{},{components:n})):o.createElement(d,a({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p.mdxType="string"==typeof e?e:r,a[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>p,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:8},a="Application Monitoring",p={unversionedId:"kusion/config-walkthrough/monitoring",id:"version-v0.9/kusion/config-walkthrough/monitoring",title:"Application Monitoring",description:"The monitoring attribute in the AppConfiguration instance is used to describe the specification for the collection of monitoring requirements for the application.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/monitoring.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/monitoring",permalink:"/docs/v0.9/kusion/config-walkthrough/monitoring",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/monitoring.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"kusion",previous:{title:"Secret Management",permalink:"/docs/v0.9/kusion/config-walkthrough/secret"},next:{title:"Operational Rules",permalink:"/docs/v0.9/kusion/config-walkthrough/operational_rules"}},s={},l=[{value:"Import",id:"import",level:2},{value:"Project-level configurations",id:"project-level-configurations",level:2},{value:"Operator mode",id:"operator-mode",level:3},{value:"Monitor types",id:"monitor-types",level:3},{value:"Managing Scraping Configuration",id:"managing-scraping-configuration",level:2}],u={toc:l};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-monitoring"},"Application Monitoring"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of monitoring requirements for the application."),(0,r.kt)("p",null,"As of version 0.9.0, Kusion supports integration with Prometheus by managing scraping behaviors in the configuration file."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute requires the target cluster to have installed Prometheus correctly, either as a Kubernetes operator or a server/agent."),(0,r.kt)("p",{parentName:"admonition"},"More about how to set up Prometheus can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../guides/observability/prometheus"},"Prometheus User Guide for Kusion"))),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.monitoring as m\n")),(0,r.kt)("h2",{id:"project-level-configurations"},"Project-level configurations"),(0,r.kt)("p",null,"In addition to the KCL configuration file, there are also project-level configurations that can be set in the ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," in hte project root directory."),(0,r.kt)("p",null,"By separating configurations that the developers are interested in and those that platform owners are interested in, we can reduce the cognitive complexity of the application configuration and achieve separation of concern."),(0,r.kt)("p",null,"In the context of ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring"),", there are two flags you can set in ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," that will alter the behavior of Kusion."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you have initialized the projects with ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init"),", the ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," should be automatically created for you.")),(0,r.kt)("h3",{id:"operator-mode"},"Operator mode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," flag indicates to Kusion whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,r.kt)("p",null,"To see more about different ways to run Prometheus in the Kubernetes cluster, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md#prometheus-installation"},"design documentation"),"."),(0,r.kt)("p",null,"Most cloud vendors provide an out-of-the-box monitoring solutions for workloads running in a managed-Kubernetes cluster (EKS, AKS, etc), such as AWS CloudWatch, Azure Monitor, etc. These solutions mostly involve installing an agent (CloudWatch Agent, OMS Agent, etc) in the cluster and collecting the metrics to a centralized monitoring server. In those cases, you don't need to set ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". It only needs to be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when you have an installation of the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator")," running inside the Kubernetes cluster."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For differences between ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/kube-prometheus"},"kube-prometheus")," and the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack"},"community kube-prometheus-stack helm chart"),", the details are documented ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator#prometheus-operator-vs-kube-prometheus-vs-community-helm-chart"},"here"),".")),(0,r.kt)("h3",{id:"monitor-types"},"Monitor types"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitorType")," flag indicates the kind of monitor Kusion will create. It only applies when ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". As of version 0.9.0, Kusion provides options to scrape metrics from either the application pods or its corresponding Kubernetes services. This determines the different kinds of resources Kusion manages when Prometheus runs as an operator in the target cluster."),(0,r.kt)("p",null,"A sample ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," with Prometheus settings:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# The project basic info\nname: multi-stack-project\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,r.kt)("p",null,"To instruct Prometheus to scrape from pod targets instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# The project basic info\nname: multi-stack-project\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Pod\n")),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus")," section is missing from the ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml"),", Kusion defaults ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to false."),(0,r.kt)("h2",{id:"managing-scraping-configuration"},"Managing Scraping Configuration"),(0,r.kt)("p",null,"To create scrape configuration for the application:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')),(0,r.kt)("p",null,"The example above will instruct the Prometheus job to scrape metrics from the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint of the application every 30 seconds."),(0,r.kt)("p",null,"To instruct Prometheus to scrape from ",(0,r.kt)("inlineCode",{parentName:"p"},"actuator/metrics")," on port ",(0,r.kt)("inlineCode",{parentName:"p"},"9099")," instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n interval: "10s"\n timeout: "5s"\n path: "/actuator/metrics"\n port: "9099"\n scheme: "http"\n }\n}\n')),(0,r.kt)("p",null,"More details about how the Prometheus integration works can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus"},"design documentation"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2e98070f.ba257614.js b/assets/js/2e98070f.ba257614.js new file mode 100644 index 00000000000..900bb62da84 --- /dev/null +++ b/assets/js/2e98070f.ba257614.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1164],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),m=l(n),h=r,d=m["".concat(s,".").concat(h)]||m[h]||c[h]||i;return n?o.createElement(d,a(a({ref:t},u),{},{components:n})):o.createElement(d,a({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p.mdxType="string"==typeof e?e:r,a[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>p,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:8},a="Application Monitoring",p={unversionedId:"kusion/config-walkthrough/monitoring",id:"version-v0.9/kusion/config-walkthrough/monitoring",title:"Application Monitoring",description:"The monitoring attribute in the AppConfiguration instance is used to describe the specification for the collection of monitoring requirements for the application.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/monitoring.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/monitoring",permalink:"/docs/v0.9/kusion/config-walkthrough/monitoring",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/monitoring.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"kusion",previous:{title:"Secret Management",permalink:"/docs/v0.9/kusion/config-walkthrough/secret"},next:{title:"Operational Rules",permalink:"/docs/v0.9/kusion/config-walkthrough/operational_rules"}},s={},l=[{value:"Import",id:"import",level:2},{value:"Project-level configurations",id:"project-level-configurations",level:2},{value:"Operator mode",id:"operator-mode",level:3},{value:"Monitor types",id:"monitor-types",level:3},{value:"Managing Scraping Configuration",id:"managing-scraping-configuration",level:2}],u={toc:l};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-monitoring"},"Application Monitoring"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of monitoring requirements for the application."),(0,r.kt)("p",null,"As of version 0.9.0, Kusion supports integration with Prometheus by managing scraping behaviors in the configuration file."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute requires the target cluster to have installed Prometheus correctly, either as a Kubernetes operator or a server/agent."),(0,r.kt)("p",{parentName:"admonition"},"More about how to set up Prometheus can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../guides/observability/prometheus"},"Prometheus User Guide for Kusion"))),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.monitoring as m\n")),(0,r.kt)("h2",{id:"project-level-configurations"},"Project-level configurations"),(0,r.kt)("p",null,"In addition to the KCL configuration file, there are also project-level configurations that can be set in the ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," in hte project root directory."),(0,r.kt)("p",null,"By separating configurations that the developers are interested in and those that platform owners are interested in, we can reduce the cognitive complexity of the application configuration and achieve separation of concern."),(0,r.kt)("p",null,"In the context of ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring"),", there are two flags you can set in ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," that will alter the behavior of Kusion."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you have initialized the projects with ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init"),", the ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," should be automatically created for you.")),(0,r.kt)("h3",{id:"operator-mode"},"Operator mode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," flag indicates to Kusion whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,r.kt)("p",null,"To see more about different ways to run Prometheus in the Kubernetes cluster, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md#prometheus-installation"},"design documentation"),"."),(0,r.kt)("p",null,"Most cloud vendors provide an out-of-the-box monitoring solutions for workloads running in a managed-Kubernetes cluster (EKS, AKS, etc), such as AWS CloudWatch, Azure Monitor, etc. These solutions mostly involve installing an agent (CloudWatch Agent, OMS Agent, etc) in the cluster and collecting the metrics to a centralized monitoring server. In those cases, you don't need to set ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". It only needs to be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when you have an installation of the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator")," running inside the Kubernetes cluster."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For differences between ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/kube-prometheus"},"kube-prometheus")," and the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack"},"community kube-prometheus-stack helm chart"),", the details are documented ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator#prometheus-operator-vs-kube-prometheus-vs-community-helm-chart"},"here"),".")),(0,r.kt)("h3",{id:"monitor-types"},"Monitor types"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitorType")," flag indicates the kind of monitor Kusion will create. It only applies when ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". As of version 0.9.0, Kusion provides options to scrape metrics from either the application pods or its corresponding Kubernetes services. This determines the different kinds of resources Kusion manages when Prometheus runs as an operator in the target cluster."),(0,r.kt)("p",null,"A sample ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml")," with Prometheus settings:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# The project basic info\nname: multi-stack-project\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,r.kt)("p",null,"To instruct Prometheus to scrape from pod targets instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# The project basic info\nname: multi-stack-project\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Pod\n")),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus")," section is missing from the ",(0,r.kt)("inlineCode",{parentName:"p"},"project.yaml"),", Kusion defaults ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to false."),(0,r.kt)("h2",{id:"managing-scraping-configuration"},"Managing Scraping Configuration"),(0,r.kt)("p",null,"To create scrape configuration for the application:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')),(0,r.kt)("p",null,"The example above will instruct the Prometheus job to scrape metrics from the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint of the application every 30 seconds."),(0,r.kt)("p",null,"To instruct Prometheus to scrape from ",(0,r.kt)("inlineCode",{parentName:"p"},"actuator/metrics")," on port ",(0,r.kt)("inlineCode",{parentName:"p"},"9099")," instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n interval: "10s"\n timeout: "5s"\n path: "/actuator/metrics"\n port: "9099"\n scheme: "http"\n }\n}\n')),(0,r.kt)("p",null,"More details about how the Prometheus integration works can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus"},"design documentation"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2e999f74.101389b3.js b/assets/js/2e999f74.101389b3.js new file mode 100644 index 00000000000..b3ec9074e71 --- /dev/null +++ b/assets/js/2e999f74.101389b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9470],{3905:(e,n,a)=>{a.d(n,{Zo:()=>c,kt:()=>k});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function s(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var i=t.createContext({}),p=function(e){var n=t.useContext(i),a=n;return e&&(a="function"==typeof e?e(n):s(s({},n),e)),a},c=function(e){var n=p(e.components);return t.createElement(i.Provider,{value:n},e.children)},m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(a),k=o,d=u["".concat(i,".").concat(k)]||u[k]||m[k]||r;return a?t.createElement(d,s(s({ref:n},c),{},{components:a})):t.createElement(d,s({ref:n},c))}));function k(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=a.length,s=new Array(r);s[0]=u;var l={};for(var i in n)hasOwnProperty.call(n,i)&&(l[i]=n[i]);l.originalType=e,l.mdxType="string"==typeof e?e:o,s[1]=l;for(var p=2;p{a.r(n),a.d(n,{Highlight:()=>c,assets:()=>i,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),o=(a(67294),a(3905));const r={sidebar_position:4},s="Try a Sample",l={unversionedId:"ctrlmesh/started/try",id:"ctrlmesh/started/try",title:"Try a Sample",description:"This guide lets you quickly evaluate KusionStack Controller Mesh.",source:"@site/docs/ctrlmesh/started/try.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/try",permalink:"/docs/next/ctrlmesh/started/try",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/started/try.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"ctrlmesh",previous:{title:"Installation",permalink:"/docs/next/ctrlmesh/started/install"},next:{title:"FAQ",permalink:"/docs/next/ctrlmesh/faq/"}},i={},p=[{value:"Install Controller Mesh Manager",id:"install-controller-mesh-manager",level:2},{value:"Try with sample-operator",id:"try-with-sample-operator",level:2},{value:"Get and deploy sample-operator v0",id:"get-and-deploy-sample-operator-v0",level:3},{value:"Play with ShardingConfig",id:"play-with-shardingconfig",level:3},{value:"Clear sample resources",id:"clear-sample-resources",level:3},{value:"Try with Operating",id:"try-with-operating",level:2}],c=e=>{let{children:n,color:a}=e;return(0,o.kt)("span",{style:{backgroundColor:a,borderRadius:"5px",color:"#fff",padding:"0.1rem"}},n)},m={toc:p,Highlight:c};function u(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},m,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"try-a-sample"},"Try a Sample"),(0,o.kt)("p",null,"This guide lets you quickly evaluate KusionStack Controller Mesh. "),(0,o.kt)("h2",{id:"install-controller-mesh-manager"},"Install Controller Mesh Manager"),(0,o.kt)("p",null,"Controller Mesh requires ",(0,o.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Install with helm")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Firstly add KusionStack charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Wait manager ready\n$ kubectl -n ctrlmesh get po\nNAME READY STATUS RESTARTS AGE\nctrlmesh-57d6b4df57-mdslc 1/1 Running 0 40s\nctrlmesh-57d6b4df57-mtv2s 1/1 Running 0 40s\n")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"/docs/next/ctrlmesh/started/install"},"Install manager with more options")),(0,o.kt)("h2",{id:"try-with-sample-operator"},"Try with sample-operator"),(0,o.kt)("p",null,"Here is an example of a ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," enabling sharding."),(0,o.kt)("h3",{id:"get-and-deploy-sample-operator-v0"},"Get and deploy sample-operator v0"),(0,o.kt)("p",null,"\ud83d\udc49 ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/tree/sample-operator"},"sample-operator repo")," "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Clone and checkout branch sample-operator.\n$ git clone -b sample-operator https://github.com/KusionStack/controller-mesh.git\n$ cd sample\n\n# Make sure you have kind or test cluster, and kubectl is available.\n\n# Deploy default sample-operator v0.\n$ IMAGE_TAG=v0.1.0 make deploy\n\nnamespace/kusionstack-sample created\nserviceaccount/kusionstack-controller-manager created\nrole.rbac.authorization.k8s.io/kusionstack-leader-election-role created\nclusterrole.rbac.authorization.k8s.io/kusionstack-manager-role created\nrolebinding.rbac.authorization.k8s.io/kusionstack-leader-election-rolebinding created\nclusterrolebinding.rbac.authorization.k8s.io/kusionstack-sample-manager-rolebinding created\ndeployment.apps/kusionstack-sample-operator-v0 created\n\n# kusionstack-sample-operator-v0 is created.\n$ kubectl get deploy -n kusionstack-sample \nNAME READY UP-TO-DATE AVAILABLE AGE\nkusionstack-sample-operator-v0 2/2 2 2 14s\n\n$ kubectl get po -n kusionstack-sample \nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-66f7595c7b-n4c47 1/1 Running 0 50s\nkusionstack-sample-operator-v0-66f7595c7b-wxwtv 1/1 Running 0 50s\n\n# sample-operator uses leader-election. Only one leader pod reconciling.\n$ kubectl -n kusionstack-sample get lease \nNAME HOLDER AGE\nsample-operator-leader kusionstack-sample-operator-v0-66f7595c7b-wxwtv_c0ed684d-f332-47f6-890c-dd7e489486f2 53\n")),(0,o.kt)("h3",{id:"play-with-shardingconfig"},"Play with ShardingConfig"),(0,o.kt)("p",null,"By configuring ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig")," appropriately, you can achieve canary and sharding deploy."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Isolate canary namespaces")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Create some test namespaces([foo-01, foo-02, ..., foo-31]).\n$ chmod +x ./scripts/create-ns-foo.sh && ./scripts/create-ns-foo.sh\n\n# All namespaces are controlled by sample-operator v0.\n$ kubectl get ns -l sample.kusionstack.io/control-by=kusionstack-sample-operator-v0-66f7595c7b-wxwtv \nNAME STATUS AGE\ndefault Active 12d\nfoo-01 Active 78s\nfoo-02 Active 78s\nfoo-03 Active 78s\n... ... ...\nfoo-32 Active 78s\n\n# There are more details in leader pod log.\n$ kubectl logs kusionstack-sample-operator-v0-66f7595c7b-wxwtv -n kusionstack-sample | grep "hold namespaces"\nI0110 09:32:50.950535 1 runner.go:101] hold namespaces [ctrlmesh default foo-01 foo-02 foo-03 foo-04 foo-05 foo-06 foo-07 foo-08 foo-09 foo-10 foo-11 foo-12 foo-13 foo-14 foo-15 foo-16 foo-17 foo-18 foo-19 foo-20 foo-21 foo-22 foo-23 foo-24 foo-25 foo-26 foo-27 foo-28 foo-29 foo-30 foo-31 foo-32 kusionstack-sample kusionstack-system local-path-storage]\n\n# Apply sample ShardingConfigs\n$ ./bin/kustomize build config/shardingconfig/canary | kubectl apply -f -\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-0-canary created\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-1-normal created\n')),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-canary.yaml"},"kusionstack-sample-operator-0-canary")," has restricted the scope of namespaces ",(0,o.kt)(c,{color:"#A3B1A8",mdxType:"Highlight"},"[foo-01, foo-02, foo-03]")," reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v1"),".\nAnd ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-normal.yaml"},"kusionstack-sample-operator-1-normal")," decided that other namespaces will be reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Patch labels to pod template to inject sidecar and ShardingConfig\n$ kubectl -n kusionstack-sample patch deployment kusionstack-sample-operator-v0 --type=strategic --patch \\\n \'spec:\n template:\n metadata:\n labels:\n ctrlmesh.kusionstack.io/enable-proxy: "true"\n ctrlmesh.kusionstack.io/watching: "true"\'\n\n# Mesh proxy container was injected\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 30s\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 41s\n\n# Find current leader\n# sharding lease format: ${leader-election-name}---${shardingconfig-name}\n$ kubectl get lease -n kusionstack-sample\nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 32s\n\n# Namespaces [foo-1, foo-2, foo-3] are no longer under v0 control.\n$ kubectl logs kusionstack-sample-operator-v0-6944bb4bf5-lfwdb -c manager -n kusionstack-sample | grep "namespaces"\n ... hold namespaces [default foo-04 foo-05 ... foo-32]\n\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Deploy canary sample-operator v1")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Apply sample operator v1 which deployment already labeled\n$ ./bin/kustomize build config/manager-v1 | kubectl apply -f - \ndeployment.apps/kusionstack-sample-operator-v1 created\n\n# Two pods created\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 4m\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 4m\nkusionstack-sample-operator-v1-7b6bbb49c8-kbgww 0/2 ContainerCreating 0 3s\nkusionstack-sample-operator-v1-7b6bbb49c8-qbzjj 0/2 ContainerCreating 0 3s\n\n# The canary shard uses a separate lease\n$ kubectl get lease -n kusionstack-sample \nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-0-canary kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj_64272983-c59a-4574-933d-7d5fea7a1e35 15s\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 4m\n\n# Only foo-01, foo-02, foo-03 controlled by v1\n$ kubectl get ns -l sample.kusionstack.io/control-by=v1 -n kusionstack-sample\nNAME STATUS AGE\nfoo-01 Active 4m\nfoo-02 Active 4m\nfoo-03 Active 4m\n\n$ kubectl logs kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj -c manager -c kusionstack-sample| grep namespaces\n ... hold namespaces [foo-01 foo-02 foo-03]\n")),(0,o.kt)("p",null,"Similarly, if you want to have more shards, you need to do the following steps: "),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Extract a portion of the namespace from the existing ShardingConfigs."),(0,o.kt)("li",{parentName:"ol"},"Configure a new ShardingConfig and apply it."),(0,o.kt)("li",{parentName:"ol"},"Recreate or restart the existing pods to make the new ShardingConfig take effect."),(0,o.kt)("li",{parentName:"ol"},"Scale out the Pods for the new ShardingConfig.")),(0,o.kt)("h3",{id:"clear-sample-resources"},"Clear sample resources"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ chmod +x ./scripts/clear.sh && ./scripts/clear.sh\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("strong",{parentName:"p"},"Beta"),": ",(0,o.kt)("em",{parentName:"p"},"We try to support automatic sharding strategy. With automatic sharding configuration, there is no need to manually configure each shard's configuration. It manages multiple sub-shardingconfigs automatically through a root configuration."))),(0,o.kt)("h2",{id:"try-with-operating"},"Try with Operating"),(0,o.kt)("p",null,"For ",(0,o.kt)("inlineCode",{parentName:"p"},"StatefulSet")," case, you can use the ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("a",{parentName:"strong",href:"https://kusionstack.io/docs/operating/introduction/"},"Operating v0.1.1"))," available here."),(0,o.kt)("p",null,"Deploy the sample operator with ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm repo update\n$ helm install sample-operating kusionstack/operating \\\n --version v0.2.0 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true\n\n$ kubectl -n kusionstack-system get sts\nNAME READY AGE\nkusionstack-operating 5/5 1m45s\n\n# The proxy container will be automatically injected into the pod\n$ kubectl -n kusionstack-system get po\nNAME READY STATUS RESTARTS AGE\nkusionstack-operating-0 2/2 Running 0 42s\nkusionstack-operating-1 2/2 Running 0 32s\nkusionstack-operating-2 2/2 Running 0 21s\nkusionstack-operating-3 2/2 Running 0 12s\nkusionstack-operating-4 0/2 ContainerCreating 0 1s\n\n# Now we have three shards with three lease.\n# operating-0-canary -> [kusionstack-operating-0]\n# operating-1-normal -> [kusionstack-operating-1, kusionstack-operating-2]\n# operating-2-normal -> [kusionstack-operating-3, kusionstack-operating-4]\n$ kubectl -n kusionstack-system get lease\nNAME HOLDER AGE\nkusionstack-controller-manager---operating-0-canary kusionstack-operating-0_81b5bbae-be63-45ed-a939-e67e0c3d6326 12m\nkusionstack-controller-manager---operating-1-normal kusionstack-operating-1_e4bbad49-e6ec-42fa-8ffd-caae82156a3e 12m\nkusionstack-controller-manager---operating-2-normal kusionstack-operating-3_94f7f81a-f9e6-47d6-b72b-e16da479e9be 12m\n")),(0,o.kt)("p",null," Show the sample ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm template sample-operating kusionstack/operating \\\n --version v0.1.1 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true \\\n --show-only templates/shardingconfig.yaml\n")),(0,o.kt)("p",null,"Here is a sample ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="operating/templates/shardingconfig.yaml"',title:'"operating/templates/shardingconfig.yaml"'},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-root\n namespace: kusionstack-system\nspec:\n # Auto sharding config\n root:\n prefix: operating\n targetStatefulSet: kusionstack-operating\n canary:\n replicas: 1\n inNamespaces:\n - kusionstack-system\n auto:\n everyShardReplicas: 2\n shardingSize: 2\n resourceSelector:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - configmaps\n - pods\n - endpoints\n - services\n - replicasets\n - apiGroups:\n - apps.kusionstack.io\n resources:\n - '*'\n controller:\n leaderElectionName: kusionstack-controller-manager\n")),(0,o.kt)("p",null,"You can configure the ShardingConfig according to your requirements."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In order to enable the ShardingConfig, you also need to add the following label to the pod template.",(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/watching: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/enable-proxy: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n","We plan to deprecate it in future versions.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2e999f74.a2353f97.js b/assets/js/2e999f74.a2353f97.js deleted file mode 100644 index 2cc945a858e..00000000000 --- a/assets/js/2e999f74.a2353f97.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9470],{3905:(e,n,a)=>{a.d(n,{Zo:()=>c,kt:()=>k});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function s(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var i=t.createContext({}),p=function(e){var n=t.useContext(i),a=n;return e&&(a="function"==typeof e?e(n):s(s({},n),e)),a},c=function(e){var n=p(e.components);return t.createElement(i.Provider,{value:n},e.children)},m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(a),k=o,d=u["".concat(i,".").concat(k)]||u[k]||m[k]||r;return a?t.createElement(d,s(s({ref:n},c),{},{components:a})):t.createElement(d,s({ref:n},c))}));function k(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=a.length,s=new Array(r);s[0]=u;var l={};for(var i in n)hasOwnProperty.call(n,i)&&(l[i]=n[i]);l.originalType=e,l.mdxType="string"==typeof e?e:o,s[1]=l;for(var p=2;p{a.r(n),a.d(n,{Highlight:()=>c,assets:()=>i,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),o=(a(67294),a(3905));const r={sidebar_position:4},s="Try a Sample",l={unversionedId:"ctrlmesh/started/try",id:"ctrlmesh/started/try",title:"Try a Sample",description:"This guide lets you quickly evaluate KusionStack Controller Mesh.",source:"@site/docs/ctrlmesh/started/try.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/try",permalink:"/docs/next/ctrlmesh/started/try",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/started/try.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"ctrlmesh",previous:{title:"Installation",permalink:"/docs/next/ctrlmesh/started/install"},next:{title:"FAQ",permalink:"/docs/next/ctrlmesh/faq/"}},i={},p=[{value:"Install Controller Mesh Manager",id:"install-controller-mesh-manager",level:2},{value:"Try with sample-operator",id:"try-with-sample-operator",level:2},{value:"Get and deploy sample-operator v0",id:"get-and-deploy-sample-operator-v0",level:3},{value:"Play with ShardingConfig",id:"play-with-shardingconfig",level:3},{value:"Clear sample resources",id:"clear-sample-resources",level:3},{value:"Try with Operating",id:"try-with-operating",level:2}],c=e=>{let{children:n,color:a}=e;return(0,o.kt)("span",{style:{backgroundColor:a,borderRadius:"5px",color:"#fff",padding:"0.1rem"}},n)},m={toc:p,Highlight:c};function u(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},m,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"try-a-sample"},"Try a Sample"),(0,o.kt)("p",null,"This guide lets you quickly evaluate KusionStack Controller Mesh. "),(0,o.kt)("h2",{id:"install-controller-mesh-manager"},"Install Controller Mesh Manager"),(0,o.kt)("p",null,"Controller Mesh requires ",(0,o.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Install with helm")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Firstly add KusionStack charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Wait manager ready\n$ kubectl -n ctrlmesh get po\nNAME READY STATUS RESTARTS AGE\nctrlmesh-57d6b4df57-mdslc 1/1 Running 0 40s\nctrlmesh-57d6b4df57-mtv2s 1/1 Running 0 40s\n")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"/docs/next/ctrlmesh/started/install"},"Install manager with more options")),(0,o.kt)("h2",{id:"try-with-sample-operator"},"Try with sample-operator"),(0,o.kt)("p",null,"Here is an example of a ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," enabling sharding."),(0,o.kt)("h3",{id:"get-and-deploy-sample-operator-v0"},"Get and deploy sample-operator v0"),(0,o.kt)("p",null,"\ud83d\udc49 ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/tree/sample-operator"},"sample-operator repo")," "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Clone and checkout branch sample-operator.\n$ git clone -b sample-operator https://github.com/KusionStack/controller-mesh.git\n$ cd sample\n\n# Make sure you have kind or test cluster, and kubectl is available.\n\n# Deploy default sample-operator v0.\n$ IMAGE_TAG=v0.1.0 make deploy\n\nnamespace/kusionstack-sample created\nserviceaccount/kusionstack-controller-manager created\nrole.rbac.authorization.k8s.io/kusionstack-leader-election-role created\nclusterrole.rbac.authorization.k8s.io/kusionstack-manager-role created\nrolebinding.rbac.authorization.k8s.io/kusionstack-leader-election-rolebinding created\nclusterrolebinding.rbac.authorization.k8s.io/kusionstack-sample-manager-rolebinding created\ndeployment.apps/kusionstack-sample-operator-v0 created\n\n# kusionstack-sample-operator-v0 is created.\n$ kubectl get deploy -n kusionstack-sample \nNAME READY UP-TO-DATE AVAILABLE AGE\nkusionstack-sample-operator-v0 2/2 2 2 14s\n\n$ kubectl get po -n kusionstack-sample \nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-66f7595c7b-n4c47 1/1 Running 0 50s\nkusionstack-sample-operator-v0-66f7595c7b-wxwtv 1/1 Running 0 50s\n\n# sample-operator uses leader-election. Only one leader pod reconciling.\n$ kubectl -n kusionstack-sample get lease \nNAME HOLDER AGE\nsample-operator-leader kusionstack-sample-operator-v0-66f7595c7b-wxwtv_c0ed684d-f332-47f6-890c-dd7e489486f2 53\n")),(0,o.kt)("h3",{id:"play-with-shardingconfig"},"Play with ShardingConfig"),(0,o.kt)("p",null,"By configuring ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig")," appropriately, you can achieve canary and sharding deploy."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Isolate canary namespaces")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Create some test namespaces([foo-01, foo-02, ..., foo-31]).\n$ chmod +x ./scripts/create-ns-foo.sh && ./scripts/create-ns-foo.sh\n\n# All namespaces are controlled by sample-operator v0.\n$ kubectl get ns -l sample.kusionstack.io/control-by=kusionstack-sample-operator-v0-66f7595c7b-wxwtv \nNAME STATUS AGE\ndefault Active 12d\nfoo-01 Active 78s\nfoo-02 Active 78s\nfoo-03 Active 78s\n... ... ...\nfoo-32 Active 78s\n\n# There are more details in leader pod log.\n$ kubectl logs kusionstack-sample-operator-v0-66f7595c7b-wxwtv -n kusionstack-sample | grep "hold namespaces"\nI0110 09:32:50.950535 1 runner.go:101] hold namespaces [ctrlmesh default foo-01 foo-02 foo-03 foo-04 foo-05 foo-06 foo-07 foo-08 foo-09 foo-10 foo-11 foo-12 foo-13 foo-14 foo-15 foo-16 foo-17 foo-18 foo-19 foo-20 foo-21 foo-22 foo-23 foo-24 foo-25 foo-26 foo-27 foo-28 foo-29 foo-30 foo-31 foo-32 kusionstack-sample kusionstack-system local-path-storage]\n\n# Apply sample ShardingConfigs\n$ ./bin/kustomize build config/shardingconfig/canary | kubectl apply -f -\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-0-canary created\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-1-normal created\n')),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-canary.yaml"},"kusionstack-sample-operator-0-canary")," has restricted the scope of namespaces ",(0,o.kt)(c,{color:"#A3B1A8",mdxType:"Highlight"},"[foo-01, foo-02, foo-03]")," reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v1"),".\nAnd ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-normal.yaml"},"kusionstack-sample-operator-1-normal")," decided that other namespaces will be reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Patch labels to pod template to inject sidecar and ShardingConfig\n$ kubectl -n kusionstack-sample patch deployment kusionstack-sample-operator-v0 --type=strategic --patch \\\n \'spec:\n template:\n metadata:\n labels:\n ctrlmesh.kusionstack.io/enable-proxy: "true"\n ctrlmesh.kusionstack.io/watching: "true"\'\n\n# Mesh proxy container was injected\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 30s\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 41s\n\n# Find current leader\n# sharding lease format: ${leader-election-name}---${shardingconfig-name}\n$ kubectl get lease -n kusionstack-sample\nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 32s\n\n# Namespaces [foo-1, foo-2, foo-3] are no longer under v0 control.\n$ kubectl logs kusionstack-sample-operator-v0-6944bb4bf5-lfwdb -c manager -n kusionstack-sample | grep "namespaces"\n ... hold namespaces [default foo-04 foo-05 ... foo-32]\n\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Deploy canary sample-operator v1")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Apply sample operator v1 which deployment already labeled\n$ ./bin/kustomize build config/manager-v1 | kubectl apply -f - \ndeployment.apps/kusionstack-sample-operator-v1 created\n\n# Two pods created\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 4m\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 4m\nkusionstack-sample-operator-v1-7b6bbb49c8-kbgww 0/2 ContainerCreating 0 3s\nkusionstack-sample-operator-v1-7b6bbb49c8-qbzjj 0/2 ContainerCreating 0 3s\n\n# The canary shard uses a separate lease\n$ kubectl get lease -n kusionstack-sample \nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-0-canary kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj_64272983-c59a-4574-933d-7d5fea7a1e35 15s\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 4m\n\n# Only foo-01, foo-02, foo-03 controlled by v1\n$ kubectl get ns -l sample.kusionstack.io/control-by=v1 -n kusionstack-sample\nNAME STATUS AGE\nfoo-01 Active 4m\nfoo-02 Active 4m\nfoo-03 Active 4m\n\n$ kubectl logs kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj -c manager -c kusionstack-sample| grep namespaces\n ... hold namespaces [foo-01 foo-02 foo-03]\n")),(0,o.kt)("p",null,"Similarly, if you want to have more shards, you need to do the following steps: "),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Extract a portion of the namespace from the existing ShardingConfigs."),(0,o.kt)("li",{parentName:"ol"},"Configure a new ShardingConfig and apply it."),(0,o.kt)("li",{parentName:"ol"},"Recreate or restart the existing pods to make the new ShardingConfig take effect."),(0,o.kt)("li",{parentName:"ol"},"Scale out the Pods for the new ShardingConfig.")),(0,o.kt)("h3",{id:"clear-sample-resources"},"Clear sample resources"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ chmod +x ./scripts/clear.sh && ./scripts/clear.sh\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("strong",{parentName:"p"},"Beta"),": ",(0,o.kt)("em",{parentName:"p"},"We try to support automatic sharding strategy. With automatic sharding configuration, there is no need to manually configure each shard's configuration. It manages multiple sub-shardingconfigs automatically through a root configuration."))),(0,o.kt)("h2",{id:"try-with-operating"},"Try with Operating"),(0,o.kt)("p",null,"For ",(0,o.kt)("inlineCode",{parentName:"p"},"StatefulSet")," case, you can use the ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("a",{parentName:"strong",href:"https://kusionstack.io/docs/operating/introduction/"},"Operating v0.1.1"))," available here."),(0,o.kt)("p",null,"Deploy the sample operator with ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm repo update\n$ helm install sample-operating kusionstack/operating \\\n --version v0.2.0 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true\n\n$ kubectl -n kusionstack-system get sts\nNAME READY AGE\nkusionstack-operating 5/5 1m45s\n\n# The proxy container will be automatically injected into the pod\n$ kubectl -n kusionstack-system get po\nNAME READY STATUS RESTARTS AGE\nkusionstack-operating-0 2/2 Running 0 42s\nkusionstack-operating-1 2/2 Running 0 32s\nkusionstack-operating-2 2/2 Running 0 21s\nkusionstack-operating-3 2/2 Running 0 12s\nkusionstack-operating-4 0/2 ContainerCreating 0 1s\n\n# Now we have three shards with three lease.\n# operating-0-canary -> [kusionstack-operating-0]\n# operating-1-normal -> [kusionstack-operating-1, kusionstack-operating-2]\n# operating-2-normal -> [kusionstack-operating-3, kusionstack-operating-4]\n$ kubectl -n kusionstack-system get lease\nNAME HOLDER AGE\nkusionstack-controller-manager---operating-0-canary kusionstack-operating-0_81b5bbae-be63-45ed-a939-e67e0c3d6326 12m\nkusionstack-controller-manager---operating-1-normal kusionstack-operating-1_e4bbad49-e6ec-42fa-8ffd-caae82156a3e 12m\nkusionstack-controller-manager---operating-2-normal kusionstack-operating-3_94f7f81a-f9e6-47d6-b72b-e16da479e9be 12m\n")),(0,o.kt)("p",null," Show the sample ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm template sample-operating kusionstack/operating \\\n --version v0.1.1 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true \\\n --show-only templates/shardingconfig.yaml\n")),(0,o.kt)("p",null,"Here is a sample ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="operating/templates/shardingconfig.yaml"',title:'"operating/templates/shardingconfig.yaml"'},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-root\n namespace: kusionstack-system\nspec:\n # Auto sharding config\n root:\n prefix: operating\n targetStatefulSet: kusionstack-operating\n canary:\n replicas: 1\n inNamespaces:\n - kusionstack-system\n auto:\n everyShardReplicas: 2\n shardingSize: 2\n resourceSelector:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - configmaps\n - pods\n - endpoints\n - services\n - replicasets\n - apiGroups:\n - apps.kusionstack.io\n resources:\n - '*'\n controller:\n leaderElectionName: kusionstack-controller-manager\n")),(0,o.kt)("p",null,"You can configure the ShardingConfig according to your requirements."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In order to enable the ShardingConfig, you also need to add the following label to the pod template.",(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/watching: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/enable-proxy: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n","We plan to deprecate it in future versions.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/30546e72.9178b7fb.js b/assets/js/30546e72.9178b7fb.js new file mode 100644 index 00000000000..420b47d6847 --- /dev/null +++ b/assets/js/30546e72.9178b7fb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9809],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var m=a.createContext({}),p=function(t){var e=a.useContext(m),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},s=function(t){var e=p(t.components);return a.createElement(m.Provider,{value:e},t.children)},d={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(n),c=r,k=u["".concat(m,".").concat(c)]||u[c]||d[c]||l;return n?a.createElement(k,i(i({ref:e},s),{},{components:n})):a.createElement(k,i({ref:e},s))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var p=2;p{n.r(e),n.d(e,{assets:()=>m,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:1},i="Installation",o={unversionedId:"ctrlmesh/started/install",id:"version-v0.9/ctrlmesh/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.9/ctrlmesh/started/install.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/install",permalink:"/docs/v0.9/ctrlmesh/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/started/install.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Concepts",permalink:"/docs/v0.9/ctrlmesh/concepts/"},next:{title:"Try a Sample",permalink:"/docs/v0.9/ctrlmesh/started/try"}},m={},p=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3}],s={toc:p};function d(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Upgrade to the latest version \n$ helm upgrade ctrlmesh kusionstack/ctrlmesh \n\n# Uninstall\n$ helm uninstall ctrlmesh\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for controller mesh installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"ctrlmesh"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.replicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of ctrlmesh-manager deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"2"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-manager"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"512Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-proxy image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-proxy"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-init image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-init"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-init"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"shardingGroupVersionKinds")),(0,r.kt)("td",{parentName:"tr",align:null},"Sharding resource lists\uff08yaml\uff09"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("p",null,"config ",(0,r.kt)("inlineCode",{parentName:"p"},"groupVersionKinds")," in file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"ctrlmesh.kusionstack.io/v1alpha1:\n- '*'\nv1:\n- Pod\n- PersistentVolumeClaim\n- Service\n- ConfigMap\n- Endpoint\napps/v1:\n- StatefulSet\n- ReplicaSet\n- ControllerRevision\n")),(0,r.kt)("p",null,"Specify each parameter using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--set key=value")," argument to ",(0,r.kt)("inlineCode",{parentName:"p"},"helm install")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/30546e72.e9bbd5b0.js b/assets/js/30546e72.e9bbd5b0.js deleted file mode 100644 index 1c3677baca5..00000000000 --- a/assets/js/30546e72.e9bbd5b0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9809],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var m=a.createContext({}),p=function(t){var e=a.useContext(m),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},s=function(t){var e=p(t.components);return a.createElement(m.Provider,{value:e},t.children)},d={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(n),c=r,k=u["".concat(m,".").concat(c)]||u[c]||d[c]||l;return n?a.createElement(k,i(i({ref:e},s),{},{components:n})):a.createElement(k,i({ref:e},s))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var p=2;p{n.r(e),n.d(e,{assets:()=>m,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:1},i="Installation",o={unversionedId:"ctrlmesh/started/install",id:"version-v0.9/ctrlmesh/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.9/ctrlmesh/started/install.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/install",permalink:"/docs/v0.9/ctrlmesh/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/started/install.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Concepts",permalink:"/docs/v0.9/ctrlmesh/concepts/"},next:{title:"Try a Sample",permalink:"/docs/v0.9/ctrlmesh/started/try"}},m={},p=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3}],s={toc:p};function d(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Upgrade to the latest version \n$ helm upgrade ctrlmesh kusionstack/ctrlmesh \n\n# Uninstall\n$ helm uninstall ctrlmesh\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for controller mesh installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"ctrlmesh"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.replicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of ctrlmesh-manager deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"2"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-manager"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"512Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-proxy image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-proxy"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-init image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-init"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-init"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"shardingGroupVersionKinds")),(0,r.kt)("td",{parentName:"tr",align:null},"Sharding resource lists\uff08yaml\uff09"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("p",null,"config ",(0,r.kt)("inlineCode",{parentName:"p"},"groupVersionKinds")," in file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"ctrlmesh.kusionstack.io/v1alpha1:\n- '*'\nv1:\n- Pod\n- PersistentVolumeClaim\n- Service\n- ConfigMap\n- Endpoint\napps/v1:\n- StatefulSet\n- ReplicaSet\n- ControllerRevision\n")),(0,r.kt)("p",null,"Specify each parameter using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--set key=value")," argument to ",(0,r.kt)("inlineCode",{parentName:"p"},"helm install")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/305bace7.541a67ad.js b/assets/js/305bace7.a69aabe8.js similarity index 70% rename from assets/js/305bace7.541a67ad.js rename to assets/js/305bace7.a69aabe8.js index 9483ecc5d1a..a23c6719fc5 100644 --- a/assets/js/305bace7.541a67ad.js +++ b/assets/js/305bace7.a69aabe8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3241],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>v});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),v=r,f=u["".concat(c,".").concat(v)]||u[v]||d[v]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function v(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_label:"Overview",id:"overview"},a="Overview",s={unversionedId:"kusion/concepts/stack/overview",id:"version-v0.10/kusion/concepts/stack/overview",title:"Overview",description:"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/1-overview.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/overview",permalink:"/docs/kusion/concepts/stack/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Project Configuration",permalink:"/docs/kusion/concepts/project/configuration"},next:{title:"Stack Configuration",permalink:"/docs/kusion/concepts/stack/configuration"}},c={},l=[{value:"High Level Schema",id:"high-level-schema",level:2}],p={toc:l};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"overview"},"Overview"),(0,r.kt)("p",null,"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production."),(0,r.kt)("h2",{id:"high-level-schema"},"High Level Schema"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"High_Level_Schema",src:n(4994).Z,width:"2390",height:"1487"})))}d.isMDXComponent=!0},4994:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/high-level-schema-ba34668ea6879003a582f15496c3ab6e.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3241],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>v});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),v=r,f=u["".concat(c,".").concat(v)]||u[v]||d[v]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function v(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_label:"Overview",id:"overview"},a="Overview",s={unversionedId:"kusion/concepts/stack/overview",id:"version-v0.10/kusion/concepts/stack/overview",title:"Overview",description:"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/1-overview.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/overview",permalink:"/docs/kusion/concepts/stack/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Project Configuration",permalink:"/docs/kusion/concepts/project/configuration"},next:{title:"Stack Configuration",permalink:"/docs/kusion/concepts/stack/configuration"}},c={},l=[{value:"High Level Schema",id:"high-level-schema",level:2}],p={toc:l};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"overview"},"Overview"),(0,r.kt)("p",null,"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production."),(0,r.kt)("h2",{id:"high-level-schema"},"High Level Schema"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"High_Level_Schema",src:n(4994).Z,width:"2390",height:"1487"})))}d.isMDXComponent=!0},4994:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/high-level-schema-ba34668ea6879003a582f15496c3ab6e.png"}}]); \ No newline at end of file diff --git a/assets/js/32000204.2c8aa695.js b/assets/js/32000204.2c8aa695.js deleted file mode 100644 index 0e0c66a9579..00000000000 --- a/assets/js/32000204.2c8aa695.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6138],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,l=e.mdxType,o=e.originalType,p=e.parentName,c=r(e,["components","mdxType","originalType","parentName"]),d=s(n),m=l,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(k,i(i({ref:t},c),{},{components:n})):a.createElement(k,i({ref:t},c))}));function m(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var o=n.length,i=new Array(o);i[0]=d;var r={};for(var p in t)hasOwnProperty.call(t,p)&&(r[p]=t[p]);r.originalType=e,r.mdxType="string"==typeof e?e:l,i[1]=r;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>s});var a=n(87462),l=(n(67294),n(3905));const o={},i="Deploy Application",r={unversionedId:"kusion/guides/working-with-k8s/deploy-application",id:"version-v0.9/kusion/guides/working-with-k8s/deploy-application",title:"Deploy Application",description:"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/1-deploy-application.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/deploy-application",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/1-deploy-application.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Kubernetes",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/"},next:{title:"Configure Containers",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/container"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initializing",id:"initializing",level:2},{value:"kcl.mod",id:"kclmod",level:3},{value:"Compiling",id:"compiling",level:2},{value:"Applying",id:"applying",level:2}],c={toc:s};function u(e){let{components:t,...o}=e;return(0,l.kt)("wrapper",(0,a.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"deploy-application"},"Deploy Application"),(0,l.kt)("p",null,"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.\nWe call the abstraction of application operation and maintenance configuration as ",(0,l.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", and its instance as ",(0,l.kt)("inlineCode",{parentName:"p"},"Application"),".\nIt is essentially an configuration model that describes an application. The complete definition can be seen ",(0,l.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/doc_app_configuration"},"here"),"."),(0,l.kt)("p",null,"In production, the application generally includes minimally several k8s resources:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Namespace"),(0,l.kt)("li",{parentName:"ul"},"Deployment"),(0,l.kt)("li",{parentName:"ul"},"Service")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,l.kt)("ul",{parentName:"admonition"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/"},"Namespace")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/services-networking/service/"},"Service")))),(0,l.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,l.kt)("p",null,"Before we start, we need to complete the following steps:"),(0,l.kt)("p",null,"1\u3001Install Kusion"),(0,l.kt)("p",null,"We recommend using HomeBrew(Mac), Scoop(Windows), or an installation shell script to download and install Kusion.\nSee ",(0,l.kt)("a",{parentName:"p",href:"../../getting-started/install-kusion"},"Download and Install")," for more details."),(0,l.kt)("p",null,"2\u3001Running Kubernetes cluster"),(0,l.kt)("p",null,"There must be a running Kubernetes cluster and a ",(0,l.kt)("a",{parentName:"p",href:"https://Kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," command line tool.\nIf you don't have a cluster yet, you can use ",(0,l.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")," to start one of your own."),(0,l.kt)("h2",{id:"initializing"},"Initializing"),(0,l.kt)("p",null,"This guide is to deploy an app using Kusion, relying on the Kusion CLI and a Kubernetes cluster."),(0,l.kt)("p",null,"To initialize the application configuration:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kusion init\n")),(0,l.kt)("p",null,"The ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion init")," command will prompt you to enter required parameters, such as project name, project description, image address, etc.\nYou can keep pressing ",(0,l.kt)("em",{parentName:"p"},"Enter")," all the way to use the default values."),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"\u2714 single-stack-sample A minimal kusion project of single stack\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n\u2714 Project Name: helloworld\n\u2714 AppName: helloworld\n\u2714 ProjectName: helloworld\nStack Config: dev\n\u2714 Image: gcr.io/google-samples/gb-frontend:v4\n\nCreated project 'helloworld'\n")),(0,l.kt)("p",null,"Now, we have successfully initialized a project ",(0,l.kt)("inlineCode",{parentName:"p"},"helloworld")," using the ",(0,l.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," template, which contains a ",(0,l.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"AppName")," represents the name of the sample application, which is recorded in the generated ",(0,l.kt)("inlineCode",{parentName:"li"},"main.k")," as the name of the ",(0,l.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," instance."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ProjectName")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"Project Name")," represent the name of the sample project, which is used as the generated folder name and then recorded in the generated ",(0,l.kt)("inlineCode",{parentName:"li"},"project.yaml"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Image")," represents the image address of the application container.")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"See ",(0,l.kt)("a",{parentName:"p",href:"../../concepts/glossary"},"Project&Stack")," for more details about Project and Stack.")),(0,l.kt)("p",null,"The directory structure is as follows:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"helloworld\n \u251c\u2500\u2500 README.md\n \u251c\u2500\u2500 dev\n \u2502 \u251c\u2500\u2500 main.k\n \u2502 \u251c\u2500\u2500 kcl.mod\n \u2502 \u251c\u2500\u2500 kcl.mod.lock\n \u2502 \u2514\u2500\u2500 stack.yaml\n \u2514\u2500\u2500 project.yaml\n\n1 directory, 6 files\n")),(0,l.kt)("p",null,"The project directory has the following files that are automatically generated:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"README.md")," contains the generated README from a template."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"project.yaml")," represents project-level configurations."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev")," directory stores the customized stack configuration:",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/main.k")," stores configurations in the ",(0,l.kt)("inlineCode",{parentName:"li"},"dev")," stack."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/stack.yaml")," stores stack-level configurations."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod")," stores stack-level dependencies."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod.lock")," stores version-sensitive dependencies.")))),(0,l.kt)("p",null,"In general, the ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," files are the KCL source code that represents the application configuration, and the ",(0,l.kt)("inlineCode",{parentName:"p"},".yaml")," is the static configuration file that describes behavior at the project or stack level."),(0,l.kt)("h3",{id:"kclmod"},"kcl.mod"),(0,l.kt)("p",null,"There should be a ",(0,l.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file generated automatically under the project directory. The ",(0,l.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file describes the dependency for the current project or stack. By default, it should contain a reference to the official ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},(0,l.kt)("inlineCode",{parentName:"a"},"catalog")," repository")," which holds some common model definitions that fits best practices. You can also create your own models library and reference that."),(0,l.kt)("h2",{id:"compiling"},"Compiling"),(0,l.kt)("p",null,"At this point, the project has been initialized with the Kusion built-in template.\nThe configuration is written in KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output."),(0,l.kt)("p",null,"Enter stack dir ",(0,l.kt)("inlineCode",{parentName:"p"},"helloworld/dev")," and compile:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cd helloworld/dev && kusion compile\n")),(0,l.kt)("p",null,"The output is printed to ",(0,l.kt)("inlineCode",{parentName:"p"},"stdout")," by default. You can save it to a file using the ",(0,l.kt)("inlineCode",{parentName:"p"},"-o/--output")," flag when running ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion compile"),"."),(0,l.kt)("p",null,"The output of ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion compile")," is the spec format."),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"For instructions on the kusion command line tool, execute ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion -h"),", or refer to the tool's online ",(0,l.kt)("a",{parentName:"p",href:"../../reference/cli/kusion"},"documentation"),".")),(0,l.kt)("h2",{id:"applying"},"Applying"),(0,l.kt)("p",null,"Compilation is now completed. We can apply the configuration as the next step. In the output from ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion compile"),", you can see 3 resources:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"a Namespace named ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld")),(0,l.kt)("li",{parentName:"ul"},"a Deployment named ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld-dev-helloworld")," in the ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld")," namespace"),(0,l.kt)("li",{parentName:"ul"},"a Service named ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld-dev-helloworld-private")," in the ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld")," namespace")),(0,l.kt)("p",null,"Execute command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kusion apply\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"}," \u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld Create\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private Create\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:helloworld success \n SUCCESS Create v1:Service:helloworld:helloworld-dev-helloworld-private success \n SUCCESS Create apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nCreate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 3 created, 0 updated, 0 deleted.\n")),(0,l.kt)("p",null,"After the configuration applying successfully, you can use the ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl")," to check the actual status of these resources."),(0,l.kt)("p",null,"1\u3001 Check Namespace"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get ns\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"NAME STATUS AGE\ndefault Active 117d\nhelloworld Active 63s\nkube-system Active 117d\n...\n")),(0,l.kt)("p",null,"2\u3001Check Deployment"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get deploy -n helloworld\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"NAME READY UP-TO-DATE AVAILABLE AGE\nhelloworld-dev-helloworld 2/2 2 2 111s\n")),(0,l.kt)("p",null,"3\u3001Check Service"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get svc -n helloworld\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nhelloworld-dev-helloworld-private ClusterIP 10.111.183.0 80/TCP 2m6s\n")),(0,l.kt)("p",null,"4\u3001Validate app"),(0,l.kt)("p",null,"Using the ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl")," tool, forward native port ",(0,l.kt)("inlineCode",{parentName:"p"},"30000")," to the service port ",(0,l.kt)("inlineCode",{parentName:"p"},"80"),"."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl port-forward svc/helloworld-dev-helloworld-private -n helloworld 30000:80\n")),(0,l.kt)("p",null,"Open browser and visit ",(0,l.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),"\uff1a"),(0,l.kt)("p",null,(0,l.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}u.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/32000204.61d2178b.js b/assets/js/32000204.61d2178b.js new file mode 100644 index 00000000000..37dd67b156e --- /dev/null +++ b/assets/js/32000204.61d2178b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6138],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,l=e.mdxType,o=e.originalType,p=e.parentName,c=r(e,["components","mdxType","originalType","parentName"]),d=s(n),m=l,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(k,i(i({ref:t},c),{},{components:n})):a.createElement(k,i({ref:t},c))}));function m(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var o=n.length,i=new Array(o);i[0]=d;var r={};for(var p in t)hasOwnProperty.call(t,p)&&(r[p]=t[p]);r.originalType=e,r.mdxType="string"==typeof e?e:l,i[1]=r;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>s});var a=n(87462),l=(n(67294),n(3905));const o={},i="Deploy Application",r={unversionedId:"kusion/guides/working-with-k8s/deploy-application",id:"version-v0.9/kusion/guides/working-with-k8s/deploy-application",title:"Deploy Application",description:"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/1-deploy-application.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/deploy-application",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/1-deploy-application.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Kubernetes",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/"},next:{title:"Configure Containers",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/container"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initializing",id:"initializing",level:2},{value:"kcl.mod",id:"kclmod",level:3},{value:"Compiling",id:"compiling",level:2},{value:"Applying",id:"applying",level:2}],c={toc:s};function u(e){let{components:t,...o}=e;return(0,l.kt)("wrapper",(0,a.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"deploy-application"},"Deploy Application"),(0,l.kt)("p",null,"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.\nWe call the abstraction of application operation and maintenance configuration as ",(0,l.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", and its instance as ",(0,l.kt)("inlineCode",{parentName:"p"},"Application"),".\nIt is essentially an configuration model that describes an application. The complete definition can be seen ",(0,l.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/doc_app_configuration"},"here"),"."),(0,l.kt)("p",null,"In production, the application generally includes minimally several k8s resources:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Namespace"),(0,l.kt)("li",{parentName:"ul"},"Deployment"),(0,l.kt)("li",{parentName:"ul"},"Service")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,l.kt)("ul",{parentName:"admonition"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/"},"Namespace")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/services-networking/service/"},"Service")))),(0,l.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,l.kt)("p",null,"Before we start, we need to complete the following steps:"),(0,l.kt)("p",null,"1\u3001Install Kusion"),(0,l.kt)("p",null,"We recommend using HomeBrew(Mac), Scoop(Windows), or an installation shell script to download and install Kusion.\nSee ",(0,l.kt)("a",{parentName:"p",href:"../../getting-started/install-kusion"},"Download and Install")," for more details."),(0,l.kt)("p",null,"2\u3001Running Kubernetes cluster"),(0,l.kt)("p",null,"There must be a running Kubernetes cluster and a ",(0,l.kt)("a",{parentName:"p",href:"https://Kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," command line tool.\nIf you don't have a cluster yet, you can use ",(0,l.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")," to start one of your own."),(0,l.kt)("h2",{id:"initializing"},"Initializing"),(0,l.kt)("p",null,"This guide is to deploy an app using Kusion, relying on the Kusion CLI and a Kubernetes cluster."),(0,l.kt)("p",null,"To initialize the application configuration:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kusion init\n")),(0,l.kt)("p",null,"The ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion init")," command will prompt you to enter required parameters, such as project name, project description, image address, etc.\nYou can keep pressing ",(0,l.kt)("em",{parentName:"p"},"Enter")," all the way to use the default values."),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"\u2714 single-stack-sample A minimal kusion project of single stack\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n\u2714 Project Name: helloworld\n\u2714 AppName: helloworld\n\u2714 ProjectName: helloworld\nStack Config: dev\n\u2714 Image: gcr.io/google-samples/gb-frontend:v4\n\nCreated project 'helloworld'\n")),(0,l.kt)("p",null,"Now, we have successfully initialized a project ",(0,l.kt)("inlineCode",{parentName:"p"},"helloworld")," using the ",(0,l.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," template, which contains a ",(0,l.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"AppName")," represents the name of the sample application, which is recorded in the generated ",(0,l.kt)("inlineCode",{parentName:"li"},"main.k")," as the name of the ",(0,l.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," instance."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ProjectName")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"Project Name")," represent the name of the sample project, which is used as the generated folder name and then recorded in the generated ",(0,l.kt)("inlineCode",{parentName:"li"},"project.yaml"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"Image")," represents the image address of the application container.")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"See ",(0,l.kt)("a",{parentName:"p",href:"../../concepts/glossary"},"Project&Stack")," for more details about Project and Stack.")),(0,l.kt)("p",null,"The directory structure is as follows:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"helloworld\n \u251c\u2500\u2500 README.md\n \u251c\u2500\u2500 dev\n \u2502 \u251c\u2500\u2500 main.k\n \u2502 \u251c\u2500\u2500 kcl.mod\n \u2502 \u251c\u2500\u2500 kcl.mod.lock\n \u2502 \u2514\u2500\u2500 stack.yaml\n \u2514\u2500\u2500 project.yaml\n\n1 directory, 6 files\n")),(0,l.kt)("p",null,"The project directory has the following files that are automatically generated:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"README.md")," contains the generated README from a template."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"project.yaml")," represents project-level configurations."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev")," directory stores the customized stack configuration:",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/main.k")," stores configurations in the ",(0,l.kt)("inlineCode",{parentName:"li"},"dev")," stack."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/stack.yaml")," stores stack-level configurations."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod")," stores stack-level dependencies."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"dev/kcl.mod.lock")," stores version-sensitive dependencies.")))),(0,l.kt)("p",null,"In general, the ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," files are the KCL source code that represents the application configuration, and the ",(0,l.kt)("inlineCode",{parentName:"p"},".yaml")," is the static configuration file that describes behavior at the project or stack level."),(0,l.kt)("h3",{id:"kclmod"},"kcl.mod"),(0,l.kt)("p",null,"There should be a ",(0,l.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file generated automatically under the project directory. The ",(0,l.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file describes the dependency for the current project or stack. By default, it should contain a reference to the official ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},(0,l.kt)("inlineCode",{parentName:"a"},"catalog")," repository")," which holds some common model definitions that fits best practices. You can also create your own models library and reference that."),(0,l.kt)("h2",{id:"compiling"},"Compiling"),(0,l.kt)("p",null,"At this point, the project has been initialized with the Kusion built-in template.\nThe configuration is written in KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output."),(0,l.kt)("p",null,"Enter stack dir ",(0,l.kt)("inlineCode",{parentName:"p"},"helloworld/dev")," and compile:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"cd helloworld/dev && kusion compile\n")),(0,l.kt)("p",null,"The output is printed to ",(0,l.kt)("inlineCode",{parentName:"p"},"stdout")," by default. You can save it to a file using the ",(0,l.kt)("inlineCode",{parentName:"p"},"-o/--output")," flag when running ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion compile"),"."),(0,l.kt)("p",null,"The output of ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion compile")," is the spec format."),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"For instructions on the kusion command line tool, execute ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion -h"),", or refer to the tool's online ",(0,l.kt)("a",{parentName:"p",href:"../../reference/cli/kusion"},"documentation"),".")),(0,l.kt)("h2",{id:"applying"},"Applying"),(0,l.kt)("p",null,"Compilation is now completed. We can apply the configuration as the next step. In the output from ",(0,l.kt)("inlineCode",{parentName:"p"},"kusion compile"),", you can see 3 resources:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"a Namespace named ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld")),(0,l.kt)("li",{parentName:"ul"},"a Deployment named ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld-dev-helloworld")," in the ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld")," namespace"),(0,l.kt)("li",{parentName:"ul"},"a Service named ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld-dev-helloworld-private")," in the ",(0,l.kt)("inlineCode",{parentName:"li"},"helloworld")," namespace")),(0,l.kt)("p",null,"Execute command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kusion apply\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"}," \u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld Create\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private Create\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:helloworld success \n SUCCESS Create v1:Service:helloworld:helloworld-dev-helloworld-private success \n SUCCESS Create apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nCreate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 3 created, 0 updated, 0 deleted.\n")),(0,l.kt)("p",null,"After the configuration applying successfully, you can use the ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl")," to check the actual status of these resources."),(0,l.kt)("p",null,"1\u3001 Check Namespace"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get ns\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"NAME STATUS AGE\ndefault Active 117d\nhelloworld Active 63s\nkube-system Active 117d\n...\n")),(0,l.kt)("p",null,"2\u3001Check Deployment"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get deploy -n helloworld\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"NAME READY UP-TO-DATE AVAILABLE AGE\nhelloworld-dev-helloworld 2/2 2 2 111s\n")),(0,l.kt)("p",null,"3\u3001Check Service"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get svc -n helloworld\n")),(0,l.kt)("p",null,"The output is similar to:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nhelloworld-dev-helloworld-private ClusterIP 10.111.183.0 80/TCP 2m6s\n")),(0,l.kt)("p",null,"4\u3001Validate app"),(0,l.kt)("p",null,"Using the ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl")," tool, forward native port ",(0,l.kt)("inlineCode",{parentName:"p"},"30000")," to the service port ",(0,l.kt)("inlineCode",{parentName:"p"},"80"),"."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl port-forward svc/helloworld-dev-helloworld-private -n helloworld 30000:80\n")),(0,l.kt)("p",null,"Open browser and visit ",(0,l.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),"\uff1a"),(0,l.kt)("p",null,(0,l.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}u.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/32956a74.522512e9.js b/assets/js/32956a74.522512e9.js deleted file mode 100644 index 539af367b48..00000000000 --- a/assets/js/32956a74.522512e9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2842],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=u(n),m=a,k=p["".concat(i,".").concat(m)]||p[m]||c[m]||l;return n?r.createElement(k,o(o({ref:t},d),{},{components:n})):r.createElement(k,o({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=p;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>s,toc:()=>u});var r=n(87462),a=(n(67294),n(3905));const l={},o="mysql",s={unversionedId:"kusion/reference/modules/workspace-configs/database/mysql",id:"kusion/reference/modules/workspace-configs/database/mysql",title:"mysql",description:"Module MySQL",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/mysql",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"service",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/service"},next:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/postgres"}},i={},u=[{value:"Module MySQL",id:"module-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:u};function c(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"mysql"},"mysql"),(0,a.kt)("h2",{id:"module-mysql"},"Module MySQL"),(0,a.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider managed mysql database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the mysql database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud mysql instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the mysql instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud mysql instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL workspace configs for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL workspace configs for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/32956a74.6ee24615.js b/assets/js/32956a74.6ee24615.js new file mode 100644 index 00000000000..2d357dddd03 --- /dev/null +++ b/assets/js/32956a74.6ee24615.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2842],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=u(n),m=a,k=p["".concat(i,".").concat(m)]||p[m]||c[m]||l;return n?r.createElement(k,o(o({ref:t},d),{},{components:n})):r.createElement(k,o({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=p;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>s,toc:()=>u});var r=n(87462),a=(n(67294),n(3905));const l={},o="mysql",s={unversionedId:"kusion/reference/modules/workspace-configs/database/mysql",id:"kusion/reference/modules/workspace-configs/database/mysql",title:"mysql",description:"Module MySQL",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/mysql",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"service",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/service"},next:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/postgres"}},i={},u=[{value:"Module MySQL",id:"module-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:u};function c(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"mysql"},"mysql"),(0,a.kt)("h2",{id:"module-mysql"},"Module MySQL"),(0,a.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider managed mysql database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the mysql database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the mysql instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud mysql instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the mysql instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud mysql instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# MySQL workspace configs for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud: \n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# MySQL workspace configs for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n suffix: "-mysql"\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/33c8bfc8.175f08eb.js b/assets/js/33c8bfc8.26688612.js similarity index 63% rename from assets/js/33c8bfc8.175f08eb.js rename to assets/js/33c8bfc8.26688612.js index 766f6a5d859..061113de811 100644 --- a/assets/js/33c8bfc8.175f08eb.js +++ b/assets/js/33c8bfc8.26688612.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3232],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",i={unversionedId:"kusion/reference/modules/workspace-configs/trait/opsrule",id:"version-v0.10/kusion/reference/modules/workspace-configs/trait/opsrule",title:"opsrule",description:"opsrule can be used to define workspace-level operational rule configurations.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/trait",slug:"/kusion/reference/modules/workspace-configs/trait/opsrule",permalink:"/docs/kusion/reference/modules/workspace-configs/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/kusion/reference/modules/workspace-configs/networking/port"},next:{title:"job",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/job"}},s={},u=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"opsrule")," can be used to define workspace-level operational rule configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3232],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",i={unversionedId:"kusion/reference/modules/workspace-configs/trait/opsrule",id:"version-v0.10/kusion/reference/modules/workspace-configs/trait/opsrule",title:"opsrule",description:"opsrule can be used to define workspace-level operational rule configurations.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/trait",slug:"/kusion/reference/modules/workspace-configs/trait/opsrule",permalink:"/docs/kusion/reference/modules/workspace-configs/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/kusion/reference/modules/workspace-configs/networking/port"},next:{title:"job",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/job"}},s={},u=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"opsrule")," can be used to define workspace-level operational rule configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/34bf352d.1c76b491.js b/assets/js/34bf352d.7c19c4b2.js similarity index 58% rename from assets/js/34bf352d.1c76b491.js rename to assets/js/34bf352d.7c19c4b2.js index 78d99448005..0c170f09db9 100644 --- a/assets/js/34bf352d.1c76b491.js +++ b/assets/js/34bf352d.7c19c4b2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5391],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||a;return n?o.createElement(f,s(s({ref:t},u),{},{components:n})):o.createElement(f,s({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,s=new Array(a);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const a={},s="Kusion Module",i={unversionedId:"kusion/concepts/kusion-module",id:"kusion/concepts/kusion-module",title:"Kusion Module",description:"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:",source:"@site/docs/kusion/3-concepts/3-kusion-module.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/kusion-module",permalink:"/docs/next/kusion/concepts/kusion-module",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/3-kusion-module.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Stack Configuration",permalink:"/docs/next/kusion/concepts/stack/configuration"},next:{title:"Workspace",permalink:"/docs/next/kusion/concepts/workspace"}},c={},l=[],u={toc:l};function p(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,o.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-module"},"Kusion Module"),(0,r.kt)("p",null,"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"App developer-oriented schema: It is a ",(0,r.kt)("a",{parentName:"li",href:"https://kcl-lang.io/docs/user_docs/guides/schema-definition/"},"KCL schema"),". Fields in this schema are recommended to be understandable to application developers and workspace-agnostic. For example, a database Kusion module schema only contains fields like database engine type and database version."),(0,r.kt)("li",{parentName:"ul"},"Kusion module generator: It is a piece of logic that generates the Intent with an instantiated schema mentioned above, along with platform configurations (",(0,r.kt)("a",{parentName:"li",href:"workspace"},"workspace"),"). As a building block, Kusion module hides the complexity of infrastructures. A database Kusion module not only represents a cloud RDS, but it also contains logic to configure other resources such as security groups and IAM policies. Additionally, it seamlessly injects the database host address, username, and password into the workload's environment variables. The generator logic can be very complex in some situations so we recommend implementing it in a GPL like ",(0,r.kt)("a",{parentName:"li",href:"https://go.dev/"},"go"),".")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion-module",src:n(63623).Z,width:"707",height:"215"})))}p.isMDXComponent=!0},63623:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/kusion-module-1b5dfa0856e8c5416468be9719b8e216.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5391],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||a;return n?o.createElement(f,s(s({ref:t},u),{},{components:n})):o.createElement(f,s({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,s=new Array(a);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const a={},s="Kusion Module",i={unversionedId:"kusion/concepts/kusion-module",id:"kusion/concepts/kusion-module",title:"Kusion Module",description:"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:",source:"@site/docs/kusion/3-concepts/3-kusion-module.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/kusion-module",permalink:"/docs/next/kusion/concepts/kusion-module",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/3-kusion-module.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Stack Configuration",permalink:"/docs/next/kusion/concepts/stack/configuration"},next:{title:"Workspace",permalink:"/docs/next/kusion/concepts/workspace"}},c={},l=[],u={toc:l};function p(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,o.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-module"},"Kusion Module"),(0,r.kt)("p",null,"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"App developer-oriented schema: It is a ",(0,r.kt)("a",{parentName:"li",href:"https://kcl-lang.io/docs/user_docs/guides/schema-definition/"},"KCL schema"),". Fields in this schema are recommended to be understandable to application developers and workspace-agnostic. For example, a database Kusion module schema only contains fields like database engine type and database version."),(0,r.kt)("li",{parentName:"ul"},"Kusion module generator: It is a piece of logic that generates the Intent with an instantiated schema mentioned above, along with platform configurations (",(0,r.kt)("a",{parentName:"li",href:"workspace"},"workspace"),"). As a building block, Kusion module hides the complexity of infrastructures. A database Kusion module not only represents a cloud RDS, but it also contains logic to configure other resources such as security groups and IAM policies. Additionally, it seamlessly injects the database host address, username, and password into the workload's environment variables. The generator logic can be very complex in some situations so we recommend implementing it in a GPL like ",(0,r.kt)("a",{parentName:"li",href:"https://go.dev/"},"go"),".")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion-module",src:n(63623).Z,width:"707",height:"215"})))}p.isMDXComponent=!0},63623:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/kusion-module-1b5dfa0856e8c5416468be9719b8e216.png"}}]); \ No newline at end of file diff --git a/assets/js/3536e8ef.af8d45ec.js b/assets/js/3536e8ef.af8d45ec.js deleted file mode 100644 index 1626a60af7c..00000000000 --- a/assets/js/3536e8ef.af8d45ec.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5690],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(s,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,o(o({ref:t},p),{},{components:n})):a.createElement(k,o({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="mysql",i={unversionedId:"kusion/reference/modules/catalog-models/database/mysql",id:"version-v0.10/kusion/reference/modules/catalog-models/database/mysql",title:"mysql",description:"Schema MySQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/mysql",permalink:"/docs/kusion/reference/modules/catalog-models/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"appconfiguration",permalink:"/docs/kusion/reference/modules/catalog-models/app-configuration"},next:{title:"postgres",permalink:"/docs/kusion/reference/modules/catalog-models/database/postgres"}},s={},d=[{value:"Schema MySQL",id:"schema-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"mysql"},"mysql"),(0,r.kt)("h2",{id:"schema-mysql"},"Schema MySQL"),(0,r.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed mysql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the mysql database is deployed locally or provided by ",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local mysql database with version of 5.7. \n\nimport catalog.models.schema.v1.accessories.mysql\n\nmysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3536e8ef.cc81c73d.js b/assets/js/3536e8ef.cc81c73d.js new file mode 100644 index 00000000000..69abe38f006 --- /dev/null +++ b/assets/js/3536e8ef.cc81c73d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5690],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(s,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,o(o({ref:t},p),{},{components:n})):a.createElement(k,o({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="mysql",i={unversionedId:"kusion/reference/modules/catalog-models/database/mysql",id:"version-v0.10/kusion/reference/modules/catalog-models/database/mysql",title:"mysql",description:"Schema MySQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/mysql",permalink:"/docs/kusion/reference/modules/catalog-models/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"appconfiguration",permalink:"/docs/kusion/reference/modules/catalog-models/app-configuration"},next:{title:"postgres",permalink:"/docs/kusion/reference/modules/catalog-models/database/postgres"}},s={},d=[{value:"Schema MySQL",id:"schema-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"mysql"},"mysql"),(0,r.kt)("h2",{id:"schema-mysql"},"Schema MySQL"),(0,r.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed mysql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the mysql database is deployed locally or provided by ",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local mysql database with version of 5.7. \n\nimport catalog.models.schema.v1.accessories.mysql\n\nmysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3712c5a4.2bb652b5.js b/assets/js/3712c5a4.2bb652b5.js deleted file mode 100644 index e8d6f49f6a6..00000000000 --- a/assets/js/3712c5a4.2bb652b5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6817],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),s=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(i.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(n),u=a,f=m["".concat(i,".").concat(u)]||m[u]||d[u]||o;return n?r.createElement(f,l(l({ref:t},p),{},{components:n})):r.createElement(f,l({ref:t},p))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="lifecycle",c={unversionedId:"kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",id:"version-v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",title:"lifecycle",description:"Schema Lifecycle",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle.md",sourceDirName:"kusion/reference/model/catalog_models/internal/container/lifecycle",slug:"/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"container",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container"},next:{title:"probe",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe"}},i={},s=[{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"lifecycle"},"lifecycle"),(0,a.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,a.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,a.kt)("br",null),"to container lifecycle events."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"preStop"),(0,a.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,a.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"postStart"),(0,a.kt)("br",null),"The action to be taken after a container is created.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3712c5a4.cfbc991f.js b/assets/js/3712c5a4.cfbc991f.js new file mode 100644 index 00000000000..41f19a10575 --- /dev/null +++ b/assets/js/3712c5a4.cfbc991f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6817],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),s=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(i.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(n),u=a,f=m["".concat(i,".").concat(u)]||m[u]||d[u]||o;return n?r.createElement(f,l(l({ref:t},p),{},{components:n})):r.createElement(f,l({ref:t},p))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="lifecycle",c={unversionedId:"kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",id:"version-v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",title:"lifecycle",description:"Schema Lifecycle",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle.md",sourceDirName:"kusion/reference/model/catalog_models/internal/container/lifecycle",slug:"/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"container",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container"},next:{title:"probe",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe"}},i={},s=[{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"lifecycle"},"lifecycle"),(0,a.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,a.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,a.kt)("br",null),"to container lifecycle events."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"preStop"),(0,a.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,a.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"postStart"),(0,a.kt)("br",null),"The action to be taken after a container is created.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"../probe/doc_probe#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3715f14e.6cadf77f.js b/assets/js/3715f14e.ab9bba0e.js similarity index 62% rename from assets/js/3715f14e.6cadf77f.js rename to assets/js/3715f14e.ab9bba0e.js index a9f951f9f40..b53744fe06c 100644 --- a/assets/js/3715f14e.6cadf77f.js +++ b/assets/js/3715f14e.ab9bba0e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8742],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",i={unversionedId:"kusion/reference/modules/workspace-configs/trait/opsrule",id:"kusion/reference/modules/workspace-configs/trait/opsrule",title:"opsrule",description:"opsrule can be used to define workspace-level operational rule configurations.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/trait",slug:"/kusion/reference/modules/workspace-configs/trait/opsrule",permalink:"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/next/kusion/reference/modules/workspace-configs/networking/port"},next:{title:"job",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/job"}},s={},u=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"opsrule")," can be used to define workspace-level operational rule configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8742],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",i={unversionedId:"kusion/reference/modules/workspace-configs/trait/opsrule",id:"kusion/reference/modules/workspace-configs/trait/opsrule",title:"opsrule",description:"opsrule can be used to define workspace-level operational rule configurations.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/trait",slug:"/kusion/reference/modules/workspace-configs/trait/opsrule",permalink:"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/next/kusion/reference/modules/workspace-configs/networking/port"},next:{title:"job",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/job"}},s={},u=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"opsrule")," can be used to define workspace-level operational rule configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/376ee327.6f6e1672.js b/assets/js/376ee327.c6e6e730.js similarity index 79% rename from assets/js/376ee327.6f6e1672.js rename to assets/js/376ee327.c6e6e730.js index 6eb82f71e0d..60b7f450c11 100644 --- a/assets/js/376ee327.6f6e1672.js +++ b/assets/js/376ee327.c6e6e730.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4652],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),i=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=i(e.components);return r.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=i(n),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||l;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=d;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var i=2;i{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const l="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(l,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>O});var r=n(87462),a=n(67294),l=n(86010),o=n(12466),s=n(76775),u=n(91980),i=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,s.k6)(),l=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(l),(0,a.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(r.location.search);t.set(l,e),r.replace({...r.location,search:t.toString()})}),[l,r])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,l=d(e),[o,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:l}))),[u,i]=f({queryString:n,groupId:r}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,l]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&l.set(e)}),[n,l])]}({groupId:r}),g=(()=>{const e=u??p;return m({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);s(e),i(e),b(e)}),[i,b,l]),tabValues:l}}var g=n(72389);const h="tabList__CuJ",k="tabItem_LNqP";function v(e){let{className:t,block:n,selectedValue:s,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=i[n].value;r!==s&&(p(t),u(r))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":n},t)},i.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,l.Z)("tabs__item",k,null==o?void 0:o.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const l=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=l.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},l.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function w(e){const t=b(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",h)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function O(e){const t=(0,g.Z)();return a.createElement(w,(0,r.Z)({key:String(t)},e))}},50655:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905)),l=n(74866),o=n(85162);const s={sidebar_position:1,sidebar_label:"Install Kusion",id:"install-kusion"},u="Install Kusion",i={unversionedId:"kusion/getting-started/install-kusion",id:"version-v0.9/kusion/getting-started/install-kusion",title:"Install Kusion",description:"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.",source:"@site/versioned_docs/version-v0.9/kusion/getting-started/install-kusion.md",sourceDirName:"kusion/getting-started",slug:"/kusion/getting-started/install-kusion",permalink:"/docs/v0.9/kusion/getting-started/install-kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/getting-started/install-kusion.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1,sidebar_label:"Install Kusion",id:"install-kusion"},sidebar:"kusion",previous:{title:"Get Started",permalink:"/docs/v0.9/kusion/getting-started/"},next:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/v0.9/kusion/getting-started/deliver-wordpress"}},c={},p=[],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"install-kusion"},"Install Kusion"),(0,a.kt)("p",null,"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Homebrew",mdxType:"TabItem"},(0,a.kt)("p",null,"The recommended method for installing on MacOS and Linux is to use the brew package manager."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"brew install KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Update Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"brew upgrade KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"brew uninstall KusionStack/tap/kusion\n"))),(0,a.kt)(o.Z,{value:"curl | sh",mdxType:"TabItem"},(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"curl https://www.kusionstack.io/scripts/install.sh | sh\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"curl https://www.kusionstack.io/scripts/uninstall.sh | sh\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4652],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),i=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=i(e.components);return r.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=i(n),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||l;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=d;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var i=2;i{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const l="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(l,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>O});var r=n(87462),a=n(67294),l=n(86010),o=n(12466),s=n(76775),u=n(91980),i=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,s.k6)(),l=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(l),(0,a.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(r.location.search);t.set(l,e),r.replace({...r.location,search:t.toString()})}),[l,r])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,l=d(e),[o,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:l}))),[u,i]=f({queryString:n,groupId:r}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,l]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&l.set(e)}),[n,l])]}({groupId:r}),g=(()=>{const e=u??p;return m({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);s(e),i(e),b(e)}),[i,b,l]),tabValues:l}}var g=n(72389);const h="tabList__CuJ",k="tabItem_LNqP";function v(e){let{className:t,block:n,selectedValue:s,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=i[n].value;r!==s&&(p(t),u(r))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":n},t)},i.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,l.Z)("tabs__item",k,null==o?void 0:o.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const l=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=l.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},l.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function w(e){const t=b(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",h)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function O(e){const t=(0,g.Z)();return a.createElement(w,(0,r.Z)({key:String(t)},e))}},50655:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905)),l=n(74866),o=n(85162);const s={sidebar_position:1,sidebar_label:"Install Kusion",id:"install-kusion"},u="Install Kusion",i={unversionedId:"kusion/getting-started/install-kusion",id:"version-v0.9/kusion/getting-started/install-kusion",title:"Install Kusion",description:"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.",source:"@site/versioned_docs/version-v0.9/kusion/getting-started/install-kusion.md",sourceDirName:"kusion/getting-started",slug:"/kusion/getting-started/install-kusion",permalink:"/docs/v0.9/kusion/getting-started/install-kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/getting-started/install-kusion.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1,sidebar_label:"Install Kusion",id:"install-kusion"},sidebar:"kusion",previous:{title:"Get Started",permalink:"/docs/v0.9/kusion/getting-started/"},next:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/v0.9/kusion/getting-started/deliver-wordpress"}},c={},p=[],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"install-kusion"},"Install Kusion"),(0,a.kt)("p",null,"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Homebrew",mdxType:"TabItem"},(0,a.kt)("p",null,"The recommended method for installing on MacOS and Linux is to use the brew package manager."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"brew install KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Update Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"brew upgrade KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"brew uninstall KusionStack/tap/kusion\n"))),(0,a.kt)(o.Z,{value:"curl | sh",mdxType:"TabItem"},(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"curl https://www.kusionstack.io/scripts/install.sh | sh\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"curl https://www.kusionstack.io/scripts/uninstall.sh | sh\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/37badd01.452e0e5c.js b/assets/js/37badd01.452e0e5c.js deleted file mode 100644 index 7f46a0c0c08..00000000000 --- a/assets/js/37badd01.452e0e5c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[884],{3905:(e,a,n)=>{n.d(a,{Zo:()=>r,kt:()=>m});var t=n(67294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function i(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=t.createContext({}),d=function(e){var a=t.useContext(p),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},r=function(e){var a=d(e.components);return t.createElement(p.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},u=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,i=e.originalType,p=e.parentName,r=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=l,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return n?t.createElement(g,o(o({ref:a},r),{},{components:n})):t.createElement(g,o({ref:a},r))}));function m(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var i=n.length,o=new Array(i);o[0]=u;var s={};for(var p in a)hasOwnProperty.call(a,p)&&(s[p]=a[p]);s.originalType=e,s.mdxType="string"==typeof e?e:l,o[1]=s;for(var d=2;d{n.r(a),n.d(a,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var t=n(87462),l=(n(67294),n(3905));const i={sidebar_position:1},o="CollaSet",s={unversionedId:"operating/manuals/collaset",id:"version-v0.10/operating/manuals/collaset",title:"CollaSet",description:"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.",source:"@site/versioned_docs/version-v0.10/operating/manuals/collaset.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/collaset",permalink:"/docs/operating/manuals/collaset",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/collaset.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"operating",previous:{title:"PodOpsLifecycle",permalink:"/docs/operating/concepts/podopslifecycle"},next:{title:"ResourceConsist",permalink:"/docs/operating/manuals/resourceconsist"}},p={},d=[{value:"Basic Features",id:"basic-features",level:2},{value:"Scaling Pods",id:"scaling-pods",level:3},{value:"Updating Pods",id:"updating-pods",level:3},{value:"Partition",id:"partition",level:4},{value:"Update by Label",id:"update-by-label",level:4},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Scaling Pods",id:"scaling-pods-1",level:3},{value:"Pod Instance ID",id:"pod-instance-id",level:4},{value:"Revision Consistency",id:"revision-consistency",level:4},{value:"Updating Pods",id:"updating-pods-1",level:3},{value:"Update Policy",id:"update-policy",level:4}],r={toc:d};function c(e){let{components:a,...n}=e;return(0,l.kt)("wrapper",(0,t.Z)({},r,n,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"collaset"},"CollaSet"),(0,l.kt)("p",null,"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods."),(0,l.kt)("p",null,"A basic CollaSet configuration is represented in the following YAML format:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Let's explore the features of CollaSet."),(0,l.kt)("h2",{id:"basic-features"},"Basic Features"),(0,l.kt)("h3",{id:"scaling-pods"},"Scaling Pods"),(0,l.kt)("p",null,"CollaSet utilizes the field spec.replicas to indicate the number of Pods under management."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 3 # indicate the number of Pods to manage\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n...\n")),(0,l.kt)("p",null,"Pods can be provisioned by CollaSet."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-85q7g 1/1 Running 0 57s\ncollaset-sample-vx5ws 1/1 Running 0 57s\ncollaset-sample-hr7pv 1/1 Running 0 57s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("p",null,"By default, CollaSet always creates new Pods using the latest template specified in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". CollaSet establishes ownership over a set of Pods through the label selector defined in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector"),". Thus, it's important to ensure that the labels provided in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector")," match those in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template.metadata.labels"),"."),(0,l.kt)("p",null,"CollaSet status provides general information about this CollaSet and all Pods under it."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get cls collaset-sample -o yaml\n......\nstatus:\n availableReplicas: 3\n collisionCount: 0\n conditions:\n - lastTransitionTime: "2023-09-01T03:56:09Z"\n reason: Updated\n status: "True"\n type: Update\n currentRevision: collaset-sample-6d7b7c58f\n observedGeneration: 1\n operatingReplicas: 0\n readyReplicas: 3\n replicas: 3\n scheduledReplicas: 3\n updatedAvailableReplicas: 3\n updatedReadyReplicas: 3\n updatedReplicas: 3\n updatedRevision: collaset-sample-6d7b7c58f\n')),(0,l.kt)("p",null,"Some fields in CollaSet status are explained here:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedRevision")," indicates the latest revision that CollaSet uses to create or update Pods."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"currentRevision")," indicates the last updated revision. It will be set to updatedRevision after all Pods are updated, and their PodReady conditions become True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"replicas")," indicates the count of Pods under this CollaSet."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"scheduledReplicas")," indicates the count of Pods under this CollaSet that successfully got scheduled."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"availableReplicas")," indicates the count of Pods under this CollaSet that have all expected finalizers attached."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," indicates the count of Pods under this CollaSet that have the updated revision."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," indicates the count of Pods under this CollaSet that are counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," and have their PodReady conditions set to True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedAvailableReplicas")," indicates the count of Pods under this CollaSet that is counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," and have all expected finalizers attached."),(0,l.kt)("h3",{id:"updating-pods"},"Updating Pods"),(0,l.kt)("p",null,"CollaSet generates Pods according to the pod template described in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". This template can be updated to signal CollaSet to update each owned Pod:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n......\nspec:\n......\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n......\n")),(0,l.kt)("p",null,"CollaSet immediately updates all Pods it owns with the new Pod template by default."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("p",null,"The update progress can be controlled using partition."),(0,l.kt)("h4",{id:"partition"},"Partition"),(0,l.kt)("p",null,"Similar to StatefulSet, ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," is used to control the upgrade progress."),(0,l.kt)("p",null,"By default, if not indicated, all Pods will be updated when spec.template changes. The ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," can be adjusted from 0 to ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.replicas")," to specify how many Pods CollaSet should update. ",(0,l.kt)("strong",{parentName:"p"},"Unlike StatefulSet, the partition in CollaSet represents the number of Pods to update.")),(0,l.kt)("p",null,"Let's update the image back to nginx:1.25.2:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.25.2 # changed from nginx:1.24.0 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # use partition to control upgrade progress\n")),(0,l.kt)("p",null,"In this case, CollaSet only updates 1 Pod to the updated revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.25.2 # only 1 Pod updated\n - image: nginx:1.24.0\n')),(0,l.kt)("h4",{id:"update-by-label"},"Update by Label"),(0,l.kt)("p",null,"By configuring the ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," rolling update policy, users can precisely specify which Pods they want to update by using labels."),(0,l.kt)("p",null,"If you go back to the sample in the ",(0,l.kt)("a",{parentName:"p",href:"#Partition"},"section Partition")," and change ",(0,l.kt)("inlineCode",{parentName:"p"},"byPartition")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," like the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n- byPartition:\n- partition: 1\n+ byLabel: {}\n")),(0,l.kt)("p",null,"Subsequently, each Pod will only be updated if it's marked with the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/update-included"),"."),(0,l.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,l.kt)("h3",{id:"scaling-pods-1"},"Scaling Pods"),(0,l.kt)("h4",{id:"pod-instance-id"},"Pod Instance ID"),(0,l.kt)("p",null,"Each Pod created by CollaSet has a unique ID held by the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/instance-id"),", which can be used to identify each individual Pod."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: Pod\nmetadata:\n labels:\n collaset.kusionstack.io/instance-id: "0" # Pod instance ID\n...\n')),(0,l.kt)("p",null,"CollaSet provides a context to specify an ID pool, which defaults to the same name as the CollaSet and is immutable."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"...\nspec:\n scaleStrategy:\n context: \n")),(0,l.kt)("p",null,"The same ID pool name can be indicated for multiple CollaSets, allowing them to share a single ID pool. Consequently, each Pod created by these CollaSets will be assigned a unique ID."),(0,l.kt)("p",null,"For example, these are two CollaSets with the same context:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ cat ~/sample.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-a\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n---\n\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-b\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Then create these CollaSets with the sample file:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default apply -f ~/sample.yaml\ncollaset.apps.kusionstack.io/collaset-sample-a created\ncollaset.apps.kusionstack.io/collaset-sample-b created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-a-g4sjj 1/1 Running 0 42s\ncollaset-sample-a-ph9vc 1/1 Running 0 42s\ncollaset-sample-b-fqkq4 1/1 Running 0 42s\ncollaset-sample-b-lqg8f 1/1 Running 0 42s\n\n$ kubectl -n default get pod -o yaml | grep collaset.kusionstack.io/instance-id\n collaset.kusionstack.io/instance-id: "0"\n collaset.kusionstack.io/instance-id: "1"\n collaset.kusionstack.io/instance-id: "3"\n collaset.kusionstack.io/instance-id: "2"\n')),(0,l.kt)("p",null,"Now, the 4 Pods created by these 2 CollaSets will have a unique instance ID."),(0,l.kt)("h4",{id:"revision-consistency"},"Revision Consistency"),(0,l.kt)("p",null,"Pods within a CollaSet can utilize more than two different Pod templates simultaneously, including both the current and updated revisions. This can result from partial updates. To ensure the stability of Pod revisions over time, CollaSet records this information. When a Pod is deleted, CollaSet recreates it using its previous revision."),(0,l.kt)("p",null,"It can be reproduced by following steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Provision a new CollaSet with replicas 3.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 4s\ncollaset-sample-glgnb 1/1 Running 0 4s\ncollaset-sample-qs46r 1/1 Running 0 4s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.24.0 and set the partition to 2. Then there will be 2 Pods with image nginx:1.24.0 and 1 Pod with image nginx:1.25.2.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 2 # update 2 Pods\n\n# Wait until these 2 Pods are updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("ol",{start:3},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.23.4 and set the partition to 1.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.23.4 # changed from nginx:1.24.0\n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # update 1 Pod\n\n# Wait until the Pod is updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # Pod collaset-sample-qs46r\n - image: nginx:1.23.4\n')),(0,l.kt)("p",null,"Now, there are 3 Pods, each of which has an individual image. If we then delete the Pod with the image nginx:1.24.0, the new Pod replacing it will be created with the same image nginx:1.24.0 in order for the Pod to inherit the revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl delete -n default delete pod collaset-sample-qs46r\npod "collaset-sample-qs46r" deleted\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 3h\ncollaset-sample-ht9x6 1/1 Running 0 2m27s # Pod recreated\ncollaset-sample-qs46r 1/1 Running 1 (3h ago) 3h\n\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # image has not been changed\n - image: nginx:1.23.4\n')),(0,l.kt)("h3",{id:"updating-pods-1"},"Updating Pods"),(0,l.kt)("h4",{id:"update-policy"},"Update Policy"),(0,l.kt)("p",null,"In addition to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," update policy, which is identical to Deployment and StatefulSet, CollaSet offers the ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," update policy."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # Options: InPlaceIfPossible, ReCreate\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," is the default value, which instructs CollaSets to try to update Pods in place when only container images, labels, and annotations have changed. If some other fields have changed too, the policy will back off to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," policy."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," indicates CollaSets always delete the old Pod and create a new one with an updated revision."),(0,l.kt)("p",null,"If update pod template with ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," policy as following example, the Pod will not be recreated."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # use InPlaceIfPossible policy\n\n$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5wvlh 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-ldvrg 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-pbz75 1/1 Running 1 (6s ago) 2m10s\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/37badd01.6e9d76a9.js b/assets/js/37badd01.6e9d76a9.js new file mode 100644 index 00000000000..646f4911f8e --- /dev/null +++ b/assets/js/37badd01.6e9d76a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[884],{3905:(e,a,n)=>{n.d(a,{Zo:()=>r,kt:()=>m});var t=n(67294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function i(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=t.createContext({}),d=function(e){var a=t.useContext(p),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},r=function(e){var a=d(e.components);return t.createElement(p.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},u=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,i=e.originalType,p=e.parentName,r=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=l,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return n?t.createElement(g,o(o({ref:a},r),{},{components:n})):t.createElement(g,o({ref:a},r))}));function m(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var i=n.length,o=new Array(i);o[0]=u;var s={};for(var p in a)hasOwnProperty.call(a,p)&&(s[p]=a[p]);s.originalType=e,s.mdxType="string"==typeof e?e:l,o[1]=s;for(var d=2;d{n.r(a),n.d(a,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var t=n(87462),l=(n(67294),n(3905));const i={sidebar_position:1},o="CollaSet",s={unversionedId:"operating/manuals/collaset",id:"version-v0.10/operating/manuals/collaset",title:"CollaSet",description:"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.",source:"@site/versioned_docs/version-v0.10/operating/manuals/collaset.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/collaset",permalink:"/docs/operating/manuals/collaset",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/collaset.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"operating",previous:{title:"PodOpsLifecycle",permalink:"/docs/operating/concepts/podopslifecycle"},next:{title:"ResourceConsist",permalink:"/docs/operating/manuals/resourceconsist"}},p={},d=[{value:"Basic Features",id:"basic-features",level:2},{value:"Scaling Pods",id:"scaling-pods",level:3},{value:"Updating Pods",id:"updating-pods",level:3},{value:"Partition",id:"partition",level:4},{value:"Update by Label",id:"update-by-label",level:4},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Scaling Pods",id:"scaling-pods-1",level:3},{value:"Pod Instance ID",id:"pod-instance-id",level:4},{value:"Revision Consistency",id:"revision-consistency",level:4},{value:"Updating Pods",id:"updating-pods-1",level:3},{value:"Update Policy",id:"update-policy",level:4}],r={toc:d};function c(e){let{components:a,...n}=e;return(0,l.kt)("wrapper",(0,t.Z)({},r,n,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"collaset"},"CollaSet"),(0,l.kt)("p",null,"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods."),(0,l.kt)("p",null,"A basic CollaSet configuration is represented in the following YAML format:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Let's explore the features of CollaSet."),(0,l.kt)("h2",{id:"basic-features"},"Basic Features"),(0,l.kt)("h3",{id:"scaling-pods"},"Scaling Pods"),(0,l.kt)("p",null,"CollaSet utilizes the field spec.replicas to indicate the number of Pods under management."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 3 # indicate the number of Pods to manage\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n...\n")),(0,l.kt)("p",null,"Pods can be provisioned by CollaSet."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-85q7g 1/1 Running 0 57s\ncollaset-sample-vx5ws 1/1 Running 0 57s\ncollaset-sample-hr7pv 1/1 Running 0 57s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("p",null,"By default, CollaSet always creates new Pods using the latest template specified in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". CollaSet establishes ownership over a set of Pods through the label selector defined in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector"),". Thus, it's important to ensure that the labels provided in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector")," match those in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template.metadata.labels"),"."),(0,l.kt)("p",null,"CollaSet status provides general information about this CollaSet and all Pods under it."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get cls collaset-sample -o yaml\n......\nstatus:\n availableReplicas: 3\n collisionCount: 0\n conditions:\n - lastTransitionTime: "2023-09-01T03:56:09Z"\n reason: Updated\n status: "True"\n type: Update\n currentRevision: collaset-sample-6d7b7c58f\n observedGeneration: 1\n operatingReplicas: 0\n readyReplicas: 3\n replicas: 3\n scheduledReplicas: 3\n updatedAvailableReplicas: 3\n updatedReadyReplicas: 3\n updatedReplicas: 3\n updatedRevision: collaset-sample-6d7b7c58f\n')),(0,l.kt)("p",null,"Some fields in CollaSet status are explained here:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedRevision")," indicates the latest revision that CollaSet uses to create or update Pods."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"currentRevision")," indicates the last updated revision. It will be set to updatedRevision after all Pods are updated, and their PodReady conditions become True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"replicas")," indicates the count of Pods under this CollaSet."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"scheduledReplicas")," indicates the count of Pods under this CollaSet that successfully got scheduled."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"availableReplicas")," indicates the count of Pods under this CollaSet that have all expected finalizers attached."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," indicates the count of Pods under this CollaSet that have the updated revision."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," indicates the count of Pods under this CollaSet that are counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," and have their PodReady conditions set to True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedAvailableReplicas")," indicates the count of Pods under this CollaSet that is counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," and have all expected finalizers attached."),(0,l.kt)("h3",{id:"updating-pods"},"Updating Pods"),(0,l.kt)("p",null,"CollaSet generates Pods according to the pod template described in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". This template can be updated to signal CollaSet to update each owned Pod:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n......\nspec:\n......\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n......\n")),(0,l.kt)("p",null,"CollaSet immediately updates all Pods it owns with the new Pod template by default."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("p",null,"The update progress can be controlled using partition."),(0,l.kt)("h4",{id:"partition"},"Partition"),(0,l.kt)("p",null,"Similar to StatefulSet, ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," is used to control the upgrade progress."),(0,l.kt)("p",null,"By default, if not indicated, all Pods will be updated when spec.template changes. The ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," can be adjusted from 0 to ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.replicas")," to specify how many Pods CollaSet should update. ",(0,l.kt)("strong",{parentName:"p"},"Unlike StatefulSet, the partition in CollaSet represents the number of Pods to update.")),(0,l.kt)("p",null,"Let's update the image back to nginx:1.25.2:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.25.2 # changed from nginx:1.24.0 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # use partition to control upgrade progress\n")),(0,l.kt)("p",null,"In this case, CollaSet only updates 1 Pod to the updated revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.25.2 # only 1 Pod updated\n - image: nginx:1.24.0\n')),(0,l.kt)("h4",{id:"update-by-label"},"Update by Label"),(0,l.kt)("p",null,"By configuring the ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," rolling update policy, users can precisely specify which Pods they want to update by using labels."),(0,l.kt)("p",null,"If you go back to the sample in the ",(0,l.kt)("a",{parentName:"p",href:"#Partition"},"section Partition")," and change ",(0,l.kt)("inlineCode",{parentName:"p"},"byPartition")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," like the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n- byPartition:\n- partition: 1\n+ byLabel: {}\n")),(0,l.kt)("p",null,"Subsequently, each Pod will only be updated if it's marked with the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/update-included"),"."),(0,l.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,l.kt)("h3",{id:"scaling-pods-1"},"Scaling Pods"),(0,l.kt)("h4",{id:"pod-instance-id"},"Pod Instance ID"),(0,l.kt)("p",null,"Each Pod created by CollaSet has a unique ID held by the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/instance-id"),", which can be used to identify each individual Pod."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: Pod\nmetadata:\n labels:\n collaset.kusionstack.io/instance-id: "0" # Pod instance ID\n...\n')),(0,l.kt)("p",null,"CollaSet provides a context to specify an ID pool, which defaults to the same name as the CollaSet and is immutable."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"...\nspec:\n scaleStrategy:\n context: \n")),(0,l.kt)("p",null,"The same ID pool name can be indicated for multiple CollaSets, allowing them to share a single ID pool. Consequently, each Pod created by these CollaSets will be assigned a unique ID."),(0,l.kt)("p",null,"For example, these are two CollaSets with the same context:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ cat ~/sample.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-a\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n---\n\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-b\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Then create these CollaSets with the sample file:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default apply -f ~/sample.yaml\ncollaset.apps.kusionstack.io/collaset-sample-a created\ncollaset.apps.kusionstack.io/collaset-sample-b created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-a-g4sjj 1/1 Running 0 42s\ncollaset-sample-a-ph9vc 1/1 Running 0 42s\ncollaset-sample-b-fqkq4 1/1 Running 0 42s\ncollaset-sample-b-lqg8f 1/1 Running 0 42s\n\n$ kubectl -n default get pod -o yaml | grep collaset.kusionstack.io/instance-id\n collaset.kusionstack.io/instance-id: "0"\n collaset.kusionstack.io/instance-id: "1"\n collaset.kusionstack.io/instance-id: "3"\n collaset.kusionstack.io/instance-id: "2"\n')),(0,l.kt)("p",null,"Now, the 4 Pods created by these 2 CollaSets will have a unique instance ID."),(0,l.kt)("h4",{id:"revision-consistency"},"Revision Consistency"),(0,l.kt)("p",null,"Pods within a CollaSet can utilize more than two different Pod templates simultaneously, including both the current and updated revisions. This can result from partial updates. To ensure the stability of Pod revisions over time, CollaSet records this information. When a Pod is deleted, CollaSet recreates it using its previous revision."),(0,l.kt)("p",null,"It can be reproduced by following steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Provision a new CollaSet with replicas 3.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 4s\ncollaset-sample-glgnb 1/1 Running 0 4s\ncollaset-sample-qs46r 1/1 Running 0 4s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.24.0 and set the partition to 2. Then there will be 2 Pods with image nginx:1.24.0 and 1 Pod with image nginx:1.25.2.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 2 # update 2 Pods\n\n# Wait until these 2 Pods are updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("ol",{start:3},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.23.4 and set the partition to 1.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.23.4 # changed from nginx:1.24.0\n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # update 1 Pod\n\n# Wait until the Pod is updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # Pod collaset-sample-qs46r\n - image: nginx:1.23.4\n')),(0,l.kt)("p",null,"Now, there are 3 Pods, each of which has an individual image. If we then delete the Pod with the image nginx:1.24.0, the new Pod replacing it will be created with the same image nginx:1.24.0 in order for the Pod to inherit the revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl delete -n default delete pod collaset-sample-qs46r\npod "collaset-sample-qs46r" deleted\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 3h\ncollaset-sample-ht9x6 1/1 Running 0 2m27s # Pod recreated\ncollaset-sample-qs46r 1/1 Running 1 (3h ago) 3h\n\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # image has not been changed\n - image: nginx:1.23.4\n')),(0,l.kt)("h3",{id:"updating-pods-1"},"Updating Pods"),(0,l.kt)("h4",{id:"update-policy"},"Update Policy"),(0,l.kt)("p",null,"In addition to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," update policy, which is identical to Deployment and StatefulSet, CollaSet offers the ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," update policy."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # Options: InPlaceIfPossible, ReCreate\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," is the default value, which instructs CollaSets to try to update Pods in place when only container images, labels, and annotations have changed. If some other fields have changed too, the policy will back off to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," policy."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," indicates CollaSets always delete the old Pod and create a new one with an updated revision."),(0,l.kt)("p",null,"If update pod template with ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," policy as following example, the Pod will not be recreated."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # use InPlaceIfPossible policy\n\n$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5wvlh 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-ldvrg 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-pbz75 1/1 Running 1 (6s ago) 2m10s\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/39a759e2.003052fb.js b/assets/js/39a759e2.4f82439b.js similarity index 73% rename from assets/js/39a759e2.003052fb.js rename to assets/js/39a759e2.4f82439b.js index c9ba7ba39f6..abc875fcf56 100644 --- a/assets/js/39a759e2.003052fb.js +++ b/assets/js/39a759e2.4f82439b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6478],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),i=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=i(e.components);return r.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,u=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=i(n),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const s="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>N});var r=n(87462),a=n(67294),s=n(86010),o=n(12466),l=n(76775),u=n(91980),i=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.k6)(),s=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=d(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[u,i]=f({queryString:n,groupId:r}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),h=(()=>{const e=u??p;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{h&&l(h)}),[h]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),b(e)}),[i,b,s]),tabValues:s}}var h=n(72389);const k="tabList__CuJ",g="tabItem_LNqP";function v(e){let{className:t,block:n,selectedValue:l,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=i[n].value;r!==l&&(p(t),u(r))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},i.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,s.Z)("tabs__item",g,null==o?void 0:o.className,{"tabs__item--active":l===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},s.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function w(e){const t=b(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",k)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function N(e){const t=(0,h.Z)();return a.createElement(w,(0,r.Z)({key:String(t)},e))}},48514:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905)),s=n(74866),o=n(85162);const l={},u="Install Kusion",i={unversionedId:"kusion/getting-started/install-kusion",id:"version-v0.10/kusion/getting-started/install-kusion",title:"Install Kusion",description:"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.",source:"@site/versioned_docs/version-v0.10/kusion/2-getting-started/1-install-kusion.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/install-kusion",permalink:"/docs/kusion/getting-started/install-kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/2-getting-started/1-install-kusion.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion vs Other Software",permalink:"/docs/kusion/what-is-kusion/kusion-vs-x"},next:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/kusion/getting-started/deliver-wordpress"}},c={},p=[],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"install-kusion"},"Install Kusion"),(0,a.kt)("p",null,"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below."),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Homebrew",mdxType:"TabItem"},(0,a.kt)("p",null,"The recommended method for installing on MacOS and Linux is to use the brew package manager."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# tap formula repository Kusionstack/tap\nbrew tap KusionStack/tap\n\n# install Kusion \nbrew install KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Update Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# update formulae from remote\nbrew update\n\n# update Kusion\nbrew upgrade KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\nbrew uninstall KusionStack/tap/kusion\n"))),(0,a.kt)(o.Z,{value:"curl | sh",mdxType:"TabItem"},(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion, default latest version\ncurl https://www.kusionstack.io/scripts/install.sh | sh\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install the Specified Version of Kusion")),(0,a.kt)("p",null,"You can also install the specified version of Kusion by appointing the version as shell script parameter, where the version is the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/tags"},"available tag"),' trimming prefix "v", such as 0.10.0, 0.9.0, etc. In general, you don\'t need to specify Kusion version, just use the command above to install the latest version.'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion of specified version 0.10.0\ncurl https://www.kusionstack.io/scripts/install.sh | sh -s 0.10.0\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\ncurl https://www.kusionstack.io/scripts/uninstall.sh | sh\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6478],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),i=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=i(e.components);return r.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,u=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=i(n),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const s="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>N});var r=n(87462),a=n(67294),s=n(86010),o=n(12466),l=n(76775),u=n(91980),i=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.k6)(),s=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=d(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[u,i]=f({queryString:n,groupId:r}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),h=(()=>{const e=u??p;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{h&&l(h)}),[h]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),b(e)}),[i,b,s]),tabValues:s}}var h=n(72389);const k="tabList__CuJ",g="tabItem_LNqP";function v(e){let{className:t,block:n,selectedValue:l,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=i[n].value;r!==l&&(p(t),u(r))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},i.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,s.Z)("tabs__item",g,null==o?void 0:o.className,{"tabs__item--active":l===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},s.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function w(e){const t=b(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",k)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function N(e){const t=(0,h.Z)();return a.createElement(w,(0,r.Z)({key:String(t)},e))}},48514:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905)),s=n(74866),o=n(85162);const l={},u="Install Kusion",i={unversionedId:"kusion/getting-started/install-kusion",id:"version-v0.10/kusion/getting-started/install-kusion",title:"Install Kusion",description:"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.",source:"@site/versioned_docs/version-v0.10/kusion/2-getting-started/1-install-kusion.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/install-kusion",permalink:"/docs/kusion/getting-started/install-kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/2-getting-started/1-install-kusion.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion vs Other Software",permalink:"/docs/kusion/what-is-kusion/kusion-vs-x"},next:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/kusion/getting-started/deliver-wordpress"}},c={},p=[],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"install-kusion"},"Install Kusion"),(0,a.kt)("p",null,"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below."),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Homebrew",mdxType:"TabItem"},(0,a.kt)("p",null,"The recommended method for installing on MacOS and Linux is to use the brew package manager."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# tap formula repository Kusionstack/tap\nbrew tap KusionStack/tap\n\n# install Kusion \nbrew install KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Update Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# update formulae from remote\nbrew update\n\n# update Kusion\nbrew upgrade KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\nbrew uninstall KusionStack/tap/kusion\n"))),(0,a.kt)(o.Z,{value:"curl | sh",mdxType:"TabItem"},(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion, default latest version\ncurl https://www.kusionstack.io/scripts/install.sh | sh\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install the Specified Version of Kusion")),(0,a.kt)("p",null,"You can also install the specified version of Kusion by appointing the version as shell script parameter, where the version is the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/tags"},"available tag"),' trimming prefix "v", such as 0.10.0, 0.9.0, etc. In general, you don\'t need to specify Kusion version, just use the command above to install the latest version.'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion of specified version 0.10.0\ncurl https://www.kusionstack.io/scripts/install.sh | sh -s 0.10.0\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\ncurl https://www.kusionstack.io/scripts/uninstall.sh | sh\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3a980746.018d6b6c.js b/assets/js/3a980746.018d6b6c.js deleted file mode 100644 index ab2a5d97b75..00000000000 --- a/assets/js/3a980746.018d6b6c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4371],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(s,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,o(o({ref:t},p),{},{components:n})):a.createElement(k,o({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="mysql",i={unversionedId:"kusion/reference/modules/catalog-models/database/mysql",id:"kusion/reference/modules/catalog-models/database/mysql",title:"mysql",description:"Schema MySQL",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/mysql",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"appconfiguration",permalink:"/docs/next/kusion/reference/modules/catalog-models/app-configuration"},next:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/postgres"}},s={},d=[{value:"Schema MySQL",id:"schema-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"mysql"},"mysql"),(0,r.kt)("h2",{id:"schema-mysql"},"Schema MySQL"),(0,r.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed mysql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the mysql database is deployed locally or provided by ",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local mysql database with version of 5.7. \n\nimport catalog.models.schema.v1.accessories.mysql\n\nmysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3a980746.cfba503b.js b/assets/js/3a980746.cfba503b.js new file mode 100644 index 00000000000..1075940dc9d --- /dev/null +++ b/assets/js/3a980746.cfba503b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4371],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(s,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,o(o({ref:t},p),{},{components:n})):a.createElement(k,o({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="mysql",i={unversionedId:"kusion/reference/modules/catalog-models/database/mysql",id:"kusion/reference/modules/catalog-models/database/mysql",title:"mysql",description:"Schema MySQL",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/mysql",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/mysql",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"appconfiguration",permalink:"/docs/next/kusion/reference/modules/catalog-models/app-configuration"},next:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/catalog-models/database/postgres"}},s={},d=[{value:"Schema MySQL",id:"schema-mysql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"mysql"},"mysql"),(0,r.kt)("h2",{id:"schema-mysql"},"Schema MySQL"),(0,r.kt)("p",null,"MySQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed mysql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the mysql database is deployed locally or provided by ",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local mysql database with version of 5.7. \n\nimport catalog.models.schema.v1.accessories.mysql\n\nmysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3b1f5c9a.4a74a1a0.js b/assets/js/3b1f5c9a.15db957d.js similarity index 54% rename from assets/js/3b1f5c9a.4a74a1a0.js rename to assets/js/3b1f5c9a.15db957d.js index b5f1d1d9ef7..1d5b501166d 100644 --- a/assets/js/3b1f5c9a.4a74a1a0.js +++ b/assets/js/3b1f5c9a.15db957d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9328],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||p[m]||o;return n?r.createElement(k,l(l({ref:t},u),{},{components:n})):r.createElement(k,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="job",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/job",id:"version-v0.10/kusion/reference/modules/workspace-configs/workload/job",title:"job",description:"job can be used to define workspace-level job configuration.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/job",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/kusion/reference/modules/workspace-configs/trait/opsrule"},next:{title:"service",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/service"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"job"},"job"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"job")," can be used to define workspace-level job configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9328],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||p[m]||o;return n?r.createElement(k,l(l({ref:t},u),{},{components:n})):r.createElement(k,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="job",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/job",id:"version-v0.10/kusion/reference/modules/workspace-configs/workload/job",title:"job",description:"job can be used to define workspace-level job configuration.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/job",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/kusion/reference/modules/workspace-configs/trait/opsrule"},next:{title:"service",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/service"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"job"},"job"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"job")," can be used to define workspace-level job configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3ba9be36.02f87a61.js b/assets/js/3ba9be36.02f87a61.js deleted file mode 100644 index 1f8a21f7d18..00000000000 --- a/assets/js/3ba9be36.02f87a61.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3407],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var o=t(67294);function n(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var r=1;r=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var l=o.createContext({}),u=function(e){var r=o.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=u(e.components);return o.createElement(l.Provider,{value:r},e.children)},c={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},d=o.forwardRef((function(e,r){var t=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=n,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||s;return t?o.createElement(f,a(a({ref:r},p),{},{components:t})):o.createElement(f,a({ref:r},p))}));function m(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var s=t.length,a=new Array(s);a[0]=d;var i={};for(var l in r)hasOwnProperty.call(r,l)&&(i[l]=r[l]);i.originalType=e,i.mdxType="string"==typeof e?e:n,a[1]=i;for(var u=2;u{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var o=t(87462),n=(t(67294),t(3905));const s={},a="Roadmap",i={unversionedId:"kusion/reference/roadmap",id:"version-v0.9/kusion/reference/roadmap",title:"Roadmap",description:"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker",source:"@site/versioned_docs/version-v0.9/kusion/reference/roadmap.md",sourceDirName:"kusion/reference",slug:"/kusion/reference/roadmap",permalink:"/docs/v0.9/kusion/reference/roadmap",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/roadmap.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Project & Stack Config Items",permalink:"/docs/v0.9/kusion/reference/model/project-stack-config-items"},next:{title:"FAQ",permalink:"/docs/v0.9/kusion/support/"}},l={},u=[{value:"Resource Ecosystem",id:"resource-ecosystem",level:2},{value:"App Progressive Rollout",id:"app-progressive-rollout",level:2},{value:"Custom Pipelines",id:"custom-pipelines",level:2},{value:"Runtime Plugin",id:"runtime-plugin",level:2}],p={toc:u};function c(e){let{components:r,...t}=e;return(0,n.kt)("wrapper",(0,o.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"roadmap"},"Roadmap"),(0,n.kt)("p",null,"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"GitHub Issue Tracker")),(0,n.kt)("h2",{id:"resource-ecosystem"},"Resource Ecosystem"),(0,n.kt)("p",null,"We plan to expand the range of resource types that our platform can handle. This includes not only traditional cloud IaaS resources, but also popular cloud-native products such as Prometheus, istio and Argo. By supporting a wider variety of resources, we aim to address the heterogeneous needs of modern applications and allow users to harness the full power of the cloud-native technologies."),(0,n.kt)("h2",{id:"app-progressive-rollout"},"App Progressive Rollout"),(0,n.kt)("p",null,"One of the key challenges in delivering applications at scale is to balance the need for speed with the need for reliability. To help our users achieve this balance, we will introduce progressive rollout strategies, such as canary release, rolling release, and percentage release. These techniques enable users to test new features or versions on a small subset of their users or infrastructure before rolling them out to the entire system. By doing so, users can minimize the risk of downtime or errors caused by untested changes."),(0,n.kt)("h2",{id:"custom-pipelines"},"Custom Pipelines"),(0,n.kt)("p",null,"Thie current workflow of KusionStack is ",(0,n.kt)("inlineCode",{parentName:"p"},"write"),",",(0,n.kt)("inlineCode",{parentName:"p"},"preview")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"apply"),", but to handle more complex deployments we need to empower users to customize the deployment pipelines to fit their specific workflows and requirements. This includes the ability to define custom stages, add or remove steps, and integrate with third-party tools. With customizable pipelines, users can streamline their deployment process, automate repetitive tasks, and satisfy their own needs by themself."),(0,n.kt)("h2",{id:"runtime-plugin"},"Runtime Plugin"),(0,n.kt)("p",null,"We have already supported IaaS cloud resources and Kubernetes resources, but we need a more flexible mechanism to support a broader range of on-premise infrastructure. By supporting a diverse set of infrastructures, we can help users avoid vendor lock-in, optimize their resource usage, and scale their applications across different regions and geographies."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3ba9be36.2230bb4e.js b/assets/js/3ba9be36.2230bb4e.js new file mode 100644 index 00000000000..e7c1a202606 --- /dev/null +++ b/assets/js/3ba9be36.2230bb4e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3407],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var o=t(67294);function n(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var r=1;r=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var l=o.createContext({}),u=function(e){var r=o.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=u(e.components);return o.createElement(l.Provider,{value:r},e.children)},c={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},d=o.forwardRef((function(e,r){var t=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=n,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||s;return t?o.createElement(f,a(a({ref:r},p),{},{components:t})):o.createElement(f,a({ref:r},p))}));function m(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var s=t.length,a=new Array(s);a[0]=d;var i={};for(var l in r)hasOwnProperty.call(r,l)&&(i[l]=r[l]);i.originalType=e,i.mdxType="string"==typeof e?e:n,a[1]=i;for(var u=2;u{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var o=t(87462),n=(t(67294),t(3905));const s={},a="Roadmap",i={unversionedId:"kusion/reference/roadmap",id:"version-v0.9/kusion/reference/roadmap",title:"Roadmap",description:"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker",source:"@site/versioned_docs/version-v0.9/kusion/reference/roadmap.md",sourceDirName:"kusion/reference",slug:"/kusion/reference/roadmap",permalink:"/docs/v0.9/kusion/reference/roadmap",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/roadmap.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Project & Stack Config Items",permalink:"/docs/v0.9/kusion/reference/model/project-stack-config-items"},next:{title:"FAQ",permalink:"/docs/v0.9/kusion/support/"}},l={},u=[{value:"Resource Ecosystem",id:"resource-ecosystem",level:2},{value:"App Progressive Rollout",id:"app-progressive-rollout",level:2},{value:"Custom Pipelines",id:"custom-pipelines",level:2},{value:"Runtime Plugin",id:"runtime-plugin",level:2}],p={toc:u};function c(e){let{components:r,...t}=e;return(0,n.kt)("wrapper",(0,o.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"roadmap"},"Roadmap"),(0,n.kt)("p",null,"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"GitHub Issue Tracker")),(0,n.kt)("h2",{id:"resource-ecosystem"},"Resource Ecosystem"),(0,n.kt)("p",null,"We plan to expand the range of resource types that our platform can handle. This includes not only traditional cloud IaaS resources, but also popular cloud-native products such as Prometheus, istio and Argo. By supporting a wider variety of resources, we aim to address the heterogeneous needs of modern applications and allow users to harness the full power of the cloud-native technologies."),(0,n.kt)("h2",{id:"app-progressive-rollout"},"App Progressive Rollout"),(0,n.kt)("p",null,"One of the key challenges in delivering applications at scale is to balance the need for speed with the need for reliability. To help our users achieve this balance, we will introduce progressive rollout strategies, such as canary release, rolling release, and percentage release. These techniques enable users to test new features or versions on a small subset of their users or infrastructure before rolling them out to the entire system. By doing so, users can minimize the risk of downtime or errors caused by untested changes."),(0,n.kt)("h2",{id:"custom-pipelines"},"Custom Pipelines"),(0,n.kt)("p",null,"Thie current workflow of KusionStack is ",(0,n.kt)("inlineCode",{parentName:"p"},"write"),",",(0,n.kt)("inlineCode",{parentName:"p"},"preview")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"apply"),", but to handle more complex deployments we need to empower users to customize the deployment pipelines to fit their specific workflows and requirements. This includes the ability to define custom stages, add or remove steps, and integrate with third-party tools. With customizable pipelines, users can streamline their deployment process, automate repetitive tasks, and satisfy their own needs by themself."),(0,n.kt)("h2",{id:"runtime-plugin"},"Runtime Plugin"),(0,n.kt)("p",null,"We have already supported IaaS cloud resources and Kubernetes resources, but we need a more flexible mechanism to support a broader range of on-premise infrastructure. By supporting a diverse set of infrastructures, we can help users avoid vendor lock-in, optimize their resource usage, and scale their applications across different regions and geographies."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3bda864c.983d1487.js b/assets/js/3bda864c.983d1487.js deleted file mode 100644 index 0744632735a..00000000000 --- a/assets/js/3bda864c.983d1487.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[93],{3905:(t,e,n)=>{n.d(e,{Zo:()=>d,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var p=a.createContext({}),s=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},d=function(t){var e=s(t.components);return a.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(n),c=r,g=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return n?a.createElement(g,i(i({ref:e},d),{},{components:n})):a.createElement(g,i({ref:e},d))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{n.r(e),n.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:2},i="Installation",o={unversionedId:"operating/started/install",id:"version-v0.10/operating/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.10/operating/started/install.md",sourceDirName:"operating/started",slug:"/operating/started/install",permalink:"/docs/operating/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/started/install.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"What is KusionStack Operating?",permalink:"/docs/operating/introduction/"},next:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/operating/started/demo-graceful-operation"}},p={},s=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Uninstall",id:"uninstall",level:3}],d={toc:s};function m(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"KusionStack Operating requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install operating kusionstack/operating \n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for Operating installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack-system"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"managerReplicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of Operating deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"3"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for operating image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/operating"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for operating-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"128Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))))),(0,r.kt)("h3",{id:"upgrade"},"Upgrade"),(0,r.kt)("p",null,"Run following command to upgrade KusionStack Operating to the latest version."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Upgrade to the latest version \n$ helm upgrade operating kusionstack/operating \n")),(0,r.kt)("h3",{id:"uninstall"},"Uninstall"),(0,r.kt)("p",null,"Run following command to uninstall KusionStack Operating."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Uninstall\n$ helm uninstall operating\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3bda864c.fb59e54b.js b/assets/js/3bda864c.fb59e54b.js new file mode 100644 index 00000000000..2a13a726cd9 --- /dev/null +++ b/assets/js/3bda864c.fb59e54b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[93],{3905:(t,e,n)=>{n.d(e,{Zo:()=>d,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var p=a.createContext({}),s=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},d=function(t){var e=s(t.components);return a.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(n),c=r,g=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return n?a.createElement(g,i(i({ref:e},d),{},{components:n})):a.createElement(g,i({ref:e},d))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{n.r(e),n.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:2},i="Installation",o={unversionedId:"operating/started/install",id:"version-v0.10/operating/started/install",title:"Installation",description:"Install with helm",source:"@site/versioned_docs/version-v0.10/operating/started/install.md",sourceDirName:"operating/started",slug:"/operating/started/install",permalink:"/docs/operating/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/started/install.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"What is KusionStack Operating?",permalink:"/docs/operating/introduction/"},next:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/operating/started/demo-graceful-operation"}},p={},s=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Uninstall",id:"uninstall",level:3}],d={toc:s};function m(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"KusionStack Operating requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install operating kusionstack/operating \n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for Operating installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack-system"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"managerReplicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of Operating deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"3"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for operating image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/operating"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for operating-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"128Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))))),(0,r.kt)("h3",{id:"upgrade"},"Upgrade"),(0,r.kt)("p",null,"Run following command to upgrade KusionStack Operating to the latest version."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Upgrade to the latest version \n$ helm upgrade operating kusionstack/operating \n")),(0,r.kt)("h3",{id:"uninstall"},"Uninstall"),(0,r.kt)("p",null,"Run following command to uninstall KusionStack Operating."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Uninstall\n$ helm uninstall operating\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3c3bc024.329f8bb0.js b/assets/js/3c3bc024.329f8bb0.js new file mode 100644 index 00000000000..1f39930326c --- /dev/null +++ b/assets/js/3c3bc024.329f8bb0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[617],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="service",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/service",id:"kusion/reference/modules/workspace-configs/workload/service",title:"service",description:"service can be used to define workspace-level service configuration.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/service",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/job"},next:{title:"Resource Naming Conventions",permalink:"/docs/next/kusion/reference/modules/naming-conventions"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"service"},"service"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"service")," can be used to define workspace-level service configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,a.kt)("br",null),"types, including Deployment and CollaSet."),(0,a.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3c3bc024.dab5524f.js b/assets/js/3c3bc024.dab5524f.js deleted file mode 100644 index ddd5c972a6a..00000000000 --- a/assets/js/3c3bc024.dab5524f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[617],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="service",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/service",id:"kusion/reference/modules/workspace-configs/workload/service",title:"service",description:"service can be used to define workspace-level service configuration.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/service",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/job"},next:{title:"Resource Naming Conventions",permalink:"/docs/next/kusion/reference/modules/naming-conventions"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"service"},"service"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"service")," can be used to define workspace-level service configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,a.kt)("br",null),"types, including Deployment and CollaSet."),(0,a.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3d3b6af8.83e8c78f.js b/assets/js/3d3b6af8.83e8c78f.js new file mode 100644 index 00000000000..f7b7260b8d5 --- /dev/null +++ b/assets/js/3d3b6af8.83e8c78f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9691],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>f});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=o.createContext({}),p=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(t),f=i,h=u["".concat(l,".").concat(f)]||u[f]||d[f]||a;return t?o.createElement(h,r(r({ref:n},c),{},{components:t})):o.createElement(h,r({ref:n},c))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,r=new Array(a);r[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var o=t(87462),i=(t(67294),t(3905));const a={id:"app-configuration",sidebar_label:"AppConfiguration"},r="AppConfiguration",s={unversionedId:"kusion/concepts/app-configuration",id:"version-v0.10/kusion/concepts/app-configuration",title:"AppConfiguration",description:"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and AppConfiguration model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/5-appconfiguration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/app-configuration",permalink:"/docs/kusion/concepts/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/5-appconfiguration.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"app-configuration",sidebar_label:"AppConfiguration"},sidebar:"kusion",previous:{title:"Workspace",permalink:"/docs/kusion/concepts/workspace"},next:{title:"Intent",permalink:"/docs/kusion/concepts/intent"}},l={},p=[{value:"Component",id:"component",level:4},{value:"Pipeline",id:"pipeline",level:4},{value:"Topologies",id:"topologies",level:4},{value:"PolicySets",id:"policysets",level:4},{value:"Dependency",id:"dependency",level:4}],c={toc:p};function d(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"appconfiguration"},"AppConfiguration"),(0,i.kt)("p",null,"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model consolidates all the necessary components and their dependent accessories for the application deployment, along with any workflow, policy and operational requirements into one standardized, infrastructure-independent declarative specification. This declarative specification represents the intuitive user intent for the application, which drives a standardized and efficient application delivery and operation process in a hybrid environment."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"appconfig.png",src:t(57091).Z,width:"2486",height:"1767"})),(0,i.kt)("p",null,"AppConfiguration consists of five core concepts, namely ",(0,i.kt)("inlineCode",{parentName:"p"},"Components"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency"),". We will walk through these concepts one by one."),(0,i.kt)("h4",{id:"component"},"Component"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components")," defines the foundation of any application configuration. Generally speaking, we believe that a comprehensive application description should at least consist of a core deployable workload that is frequently iterated and a collection of any other core services that the workload depends on, such as databases, caches or any other cloud services."),(0,i.kt)("p",null,"Components are conceptually split into two categories, ",(0,i.kt)("inlineCode",{parentName:"p"},"Workload")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories"),". The former revolves around the configuration for the computing resource. The latter represents any third-party runtime capabilities and operational requirements that the application needs. Each AppConfiguration consists of exactly one workload and any number of accessories."),(0,i.kt)("p",null,"Simply put, we can define ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," with the following expression:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components = Workload + Accessories")),(0,i.kt)("p",null,"The concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories")," itself is implicit when ",(0,i.kt)("a",{parentName:"p",href:"../configuration-walkthrough/overview"},"authoring the configuration files"),". You can define the workload and any type of accessories (such as database or monitoring) directly under the AppConfiguration model."),(0,i.kt)("p",null,"From a collaboration perspective, platform developers and SREs are responsible for continuously adding any new schema (as abstractions for the underlying infrastructure) and implementations that can be used out-of-the-box. Application developers SREs should be able to leverage the corresponding schemas to cover the evolving application needs. This helps software organizations achieve separation of concern, so that different roles can focus on the subject matter they are an expert of."),(0,i.kt)("h4",{id:"pipeline"},"Pipeline"),(0,i.kt)("p",null,"In most of the cases, the platform is capable of providing a consistent application delivery process that can meet most application needs. In the case that an application warrants any customization in the delivery workflow, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline")," section in AppConfiguration provides an approach to extend the workflow as needed. "),(0,i.kt)("p",null,"A typical delivery workflow is made of several stages, each corresponds to some logic that needs to be executed, such as manual approval, data transfer, coordinated multi-cluster release, notification, etc. Implementation-wise, the execution of each stage should be carried out with a plugin, developed and managed by the platform owners."),(0,i.kt)("h4",{id:"topologies"},"Topologies"),(0,i.kt)("p",null,"In reality, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets including different clouds, regions, availability zones or runtimes for availability/cost/regulation/performance or disaster recovery related reasons. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies")," section in AppConfiguration highlights the different deployment targets in the application delivery and provides a single pane of glass that overlooks the entire deployment topology."),(0,i.kt)("h4",{id:"policysets"},"PolicySets"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets")," section is responsible for defining the set of rules and procedures that should be followed in the application delivery process. They generally represent the guidelines with the purpose of minimizing any technical, security or compliance risks. Some examples include release strategies, risk management policies, and self-healing strategies. The collections of policies are expected to be managed as a joint effort from all the stakeholders, including platform owners, infrastructure owners, and security and compliance stakeholders. Some policy sets (usually security and compliance related) are expected to be mandatory. Some can be switched on and off by the application owner (self-healing strategy for instance) depending on their specific needs."),(0,i.kt)("h4",{id:"dependency"},"Dependency"),(0,i.kt)("p",null,"In a production-scale environment, there are usually intricate dependencies between multiple applications. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency")," section is responsible for describing the dependencies between multiple applications."))}d.isMDXComponent=!0},57091:(e,n,t)=>{t.d(n,{Z:()=>o});const o=t.p+"assets/images/appconfig-6dd90bd8ff9307dc4e5f9b1553a52b29.png"}}]); \ No newline at end of file diff --git a/assets/js/3d3b6af8.840d42ce.js b/assets/js/3d3b6af8.840d42ce.js deleted file mode 100644 index f54232c2a8e..00000000000 --- a/assets/js/3d3b6af8.840d42ce.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9691],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>f});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=o.createContext({}),p=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(t),f=i,h=u["".concat(l,".").concat(f)]||u[f]||d[f]||a;return t?o.createElement(h,r(r({ref:n},c),{},{components:t})):o.createElement(h,r({ref:n},c))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,r=new Array(a);r[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var o=t(87462),i=(t(67294),t(3905));const a={id:"app-configuration",sidebar_label:"AppConfiguration"},r="AppConfiguration",s={unversionedId:"kusion/concepts/app-configuration",id:"version-v0.10/kusion/concepts/app-configuration",title:"AppConfiguration",description:"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and AppConfiguration model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/5-appconfiguration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/app-configuration",permalink:"/docs/kusion/concepts/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/5-appconfiguration.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"app-configuration",sidebar_label:"AppConfiguration"},sidebar:"kusion",previous:{title:"Workspace",permalink:"/docs/kusion/concepts/workspace"},next:{title:"Intent",permalink:"/docs/kusion/concepts/intent"}},l={},p=[{value:"Component",id:"component",level:4},{value:"Pipeline",id:"pipeline",level:4},{value:"Topologies",id:"topologies",level:4},{value:"PolicySets",id:"policysets",level:4},{value:"Dependency",id:"dependency",level:4}],c={toc:p};function d(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"appconfiguration"},"AppConfiguration"),(0,i.kt)("p",null,"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model consolidates all the necessary components and their dependent accessories for the application deployment, along with any workflow, policy and operational requirements into one standardized, infrastructure-independent declarative specification. This declarative specification represents the intuitive user intent for the application, which drives a standardized and efficient application delivery and operation process in a hybrid environment."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"appconfig.png",src:t(57091).Z,width:"2486",height:"1767"})),(0,i.kt)("p",null,"AppConfiguration consists of five core concepts, namely ",(0,i.kt)("inlineCode",{parentName:"p"},"Components"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency"),". We will walk through these concepts one by one."),(0,i.kt)("h4",{id:"component"},"Component"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components")," defines the foundation of any application configuration. Generally speaking, we believe that a comprehensive application description should at least consist of a core deployable workload that is frequently iterated and a collection of any other core services that the workload depends on, such as databases, caches or any other cloud services."),(0,i.kt)("p",null,"Components are conceptually split into two categories, ",(0,i.kt)("inlineCode",{parentName:"p"},"Workload")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories"),". The former revolves around the configuration for the computing resource. The latter represents any third-party runtime capabilities and operational requirements that the application needs. Each AppConfiguration consists of exactly one workload and any number of accessories."),(0,i.kt)("p",null,"Simply put, we can define ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," with the following expression:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components = Workload + Accessories")),(0,i.kt)("p",null,"The concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories")," itself is implicit when ",(0,i.kt)("a",{parentName:"p",href:"../configuration-walkthrough/overview"},"authoring the configuration files"),". You can define the workload and any type of accessories (such as database or monitoring) directly under the AppConfiguration model."),(0,i.kt)("p",null,"From a collaboration perspective, platform developers and SREs are responsible for continuously adding any new schema (as abstractions for the underlying infrastructure) and implementations that can be used out-of-the-box. Application developers SREs should be able to leverage the corresponding schemas to cover the evolving application needs. This helps software organizations achieve separation of concern, so that different roles can focus on the subject matter they are an expert of."),(0,i.kt)("h4",{id:"pipeline"},"Pipeline"),(0,i.kt)("p",null,"In most of the cases, the platform is capable of providing a consistent application delivery process that can meet most application needs. In the case that an application warrants any customization in the delivery workflow, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline")," section in AppConfiguration provides an approach to extend the workflow as needed. "),(0,i.kt)("p",null,"A typical delivery workflow is made of several stages, each corresponds to some logic that needs to be executed, such as manual approval, data transfer, coordinated multi-cluster release, notification, etc. Implementation-wise, the execution of each stage should be carried out with a plugin, developed and managed by the platform owners."),(0,i.kt)("h4",{id:"topologies"},"Topologies"),(0,i.kt)("p",null,"In reality, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets including different clouds, regions, availability zones or runtimes for availability/cost/regulation/performance or disaster recovery related reasons. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies")," section in AppConfiguration highlights the different deployment targets in the application delivery and provides a single pane of glass that overlooks the entire deployment topology."),(0,i.kt)("h4",{id:"policysets"},"PolicySets"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets")," section is responsible for defining the set of rules and procedures that should be followed in the application delivery process. They generally represent the guidelines with the purpose of minimizing any technical, security or compliance risks. Some examples include release strategies, risk management policies, and self-healing strategies. The collections of policies are expected to be managed as a joint effort from all the stakeholders, including platform owners, infrastructure owners, and security and compliance stakeholders. Some policy sets (usually security and compliance related) are expected to be mandatory. Some can be switched on and off by the application owner (self-healing strategy for instance) depending on their specific needs."),(0,i.kt)("h4",{id:"dependency"},"Dependency"),(0,i.kt)("p",null,"In a production-scale environment, there are usually intricate dependencies between multiple applications. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency")," section is responsible for describing the dependencies between multiple applications."))}d.isMDXComponent=!0},57091:(e,n,t)=>{t.d(n,{Z:()=>o});const o=t.p+"assets/images/appconfig-6dd90bd8ff9307dc4e5f9b1553a52b29.png"}}]); \ No newline at end of file diff --git a/assets/js/3de240dc.97be4a01.js b/assets/js/3de240dc.fbdcaaa2.js similarity index 59% rename from assets/js/3de240dc.97be4a01.js rename to assets/js/3de240dc.fbdcaaa2.js index 2c7b892fb2a..680f0d38d5d 100644 --- a/assets/js/3de240dc.97be4a01.js +++ b/assets/js/3de240dc.fbdcaaa2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6791],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={},i="Controller Mesh",l={unversionedId:"ctrlmesh/intro/intro",id:"ctrlmesh/intro/intro",title:"Controller Mesh",description:"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.",source:"@site/docs/ctrlmesh/intro/intro.md",sourceDirName:"ctrlmesh/intro",slug:"/ctrlmesh/intro/",permalink:"/docs/next/ctrlmesh/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/intro/intro.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",next:{title:"Concepts",permalink:"/docs/next/ctrlmesh/concepts/"}},s={},c=[{value:"Key Features",id:"key-features",level:2},{value:"Architecture",id:"architecture",level:2}],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"controller-mesh"},"Controller Mesh"),(0,o.kt)("p",null,"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better."),(0,o.kt)("h2",{id:"key-features"},"Key Features"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Sharding"),": Through relevant configurations, Kubernetes single-point deployed operator applications can be flexibly shard deployed."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Canary upgrade"),": Depends on sharding, the controller instances can be updated in canary progress instead of updated in one time."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Circuit breaker and rate limiter"),": Not only Kubernetes operation requests, but also other external operation requests."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Multicluster routing and sharding")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"And more"),": Fault injection and Observability (Todo).")),(0,o.kt)("h2",{id:"architecture"},"Architecture"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"800",src:r(59569).Z})),(0,o.kt)("p",null,"Visit ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/ctrlmesh/started/install"},"Installation")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/ctrlmesh/started/try"},"Quick Start"),"."))}u.isMDXComponent=!0},59569:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/mesh-arch-2-d82d2166bfeff6b5e56364fda483e9c2.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6791],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={},i="Controller Mesh",l={unversionedId:"ctrlmesh/intro/intro",id:"ctrlmesh/intro/intro",title:"Controller Mesh",description:"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.",source:"@site/docs/ctrlmesh/intro/intro.md",sourceDirName:"ctrlmesh/intro",slug:"/ctrlmesh/intro/",permalink:"/docs/next/ctrlmesh/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/intro/intro.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",next:{title:"Concepts",permalink:"/docs/next/ctrlmesh/concepts/"}},s={},c=[{value:"Key Features",id:"key-features",level:2},{value:"Architecture",id:"architecture",level:2}],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"controller-mesh"},"Controller Mesh"),(0,o.kt)("p",null,"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better."),(0,o.kt)("h2",{id:"key-features"},"Key Features"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Sharding"),": Through relevant configurations, Kubernetes single-point deployed operator applications can be flexibly shard deployed."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Canary upgrade"),": Depends on sharding, the controller instances can be updated in canary progress instead of updated in one time."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Circuit breaker and rate limiter"),": Not only Kubernetes operation requests, but also other external operation requests."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Multicluster routing and sharding")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"And more"),": Fault injection and Observability (Todo).")),(0,o.kt)("h2",{id:"architecture"},"Architecture"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"800",src:r(59569).Z})),(0,o.kt)("p",null,"Visit ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/ctrlmesh/started/install"},"Installation")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/ctrlmesh/started/try"},"Quick Start"),"."))}u.isMDXComponent=!0},59569:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/mesh-arch-2-d82d2166bfeff6b5e56364fda483e9c2.png"}}]); \ No newline at end of file diff --git a/assets/js/4032a3e5.3e801b32.js b/assets/js/4032a3e5.3e801b32.js new file mode 100644 index 00000000000..801c1e301cd --- /dev/null +++ b/assets/js/4032a3e5.3e801b32.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9450],{3905:(t,e,n)=>{n.d(e,{Zo:()=>d,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var p=a.createContext({}),s=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},d=function(t){var e=s(t.components);return a.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(n),c=r,g=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return n?a.createElement(g,i(i({ref:e},d),{},{components:n})):a.createElement(g,i({ref:e},d))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{n.r(e),n.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:2},i="Installation",o={unversionedId:"operating/started/install",id:"operating/started/install",title:"Installation",description:"Install with helm",source:"@site/docs/operating/started/install.md",sourceDirName:"operating/started",slug:"/operating/started/install",permalink:"/docs/next/operating/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/started/install.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"What is KusionStack Operating?",permalink:"/docs/next/operating/introduction/"},next:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/next/operating/started/demo-graceful-operation"}},p={},s=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Uninstall",id:"uninstall",level:3}],d={toc:s};function m(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"KusionStack Operating requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install operating kusionstack/operating \n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for Operating installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack-system"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"managerReplicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of Operating deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"3"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for operating image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/operating"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for operating-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"128Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))))),(0,r.kt)("h3",{id:"upgrade"},"Upgrade"),(0,r.kt)("p",null,"Run following command to upgrade KusionStack Operating to the latest version."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Upgrade to the latest version \n$ helm upgrade operating kusionstack/operating \n")),(0,r.kt)("h3",{id:"uninstall"},"Uninstall"),(0,r.kt)("p",null,"Run following command to uninstall KusionStack Operating."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Uninstall\n$ helm uninstall operating\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4032a3e5.8e8b71c9.js b/assets/js/4032a3e5.8e8b71c9.js deleted file mode 100644 index 0e43cfc9804..00000000000 --- a/assets/js/4032a3e5.8e8b71c9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9450],{3905:(t,e,n)=>{n.d(e,{Zo:()=>d,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var p=a.createContext({}),s=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},d=function(t){var e=s(t.components);return a.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(n),c=r,g=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return n?a.createElement(g,i(i({ref:e},d),{},{components:n})):a.createElement(g,i({ref:e},d))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{n.r(e),n.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:2},i="Installation",o={unversionedId:"operating/started/install",id:"operating/started/install",title:"Installation",description:"Install with helm",source:"@site/docs/operating/started/install.md",sourceDirName:"operating/started",slug:"/operating/started/install",permalink:"/docs/next/operating/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/started/install.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"What is KusionStack Operating?",permalink:"/docs/next/operating/introduction/"},next:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/next/operating/started/demo-graceful-operation"}},p={},s=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Uninstall",id:"uninstall",level:3}],d={toc:s};function m(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"KusionStack Operating requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install operating kusionstack/operating \n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for Operating installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack-system"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"managerReplicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of Operating deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"3"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for operating image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/operating"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for operating-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"128Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of operating-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))))),(0,r.kt)("h3",{id:"upgrade"},"Upgrade"),(0,r.kt)("p",null,"Run following command to upgrade KusionStack Operating to the latest version."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Upgrade to the latest version \n$ helm upgrade operating kusionstack/operating \n")),(0,r.kt)("h3",{id:"uninstall"},"Uninstall"),(0,r.kt)("p",null,"Run following command to uninstall KusionStack Operating."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Uninstall\n$ helm uninstall operating\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/407e1392.ea639fd9.js b/assets/js/407e1392.ea639fd9.js new file mode 100644 index 00000000000..4e4b843580c --- /dev/null +++ b/assets/js/407e1392.ea639fd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8119],{3905:(t,e,a)=>{a.d(e,{Zo:()=>p,kt:()=>m});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function o(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var i=n.createContext({}),s=function(t){var e=n.useContext(i),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},p=function(t){var e=s(t.components);return n.createElement(i.Provider,{value:e},t.children)},u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,i=t.parentName,p=d(t,["components","mdxType","originalType","parentName"]),c=s(a),m=r,k=c["".concat(i,".").concat(m)]||c[m]||u[m]||l;return a?n.createElement(k,o(o({ref:e},p),{},{components:a})):n.createElement(k,o({ref:e},p))}));function m(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,o=new Array(l);o[0]=c;var d={};for(var i in e)hasOwnProperty.call(e,i)&&(d[i]=e[i]);d.originalType=t,d.mdxType="string"==typeof t?t:r,o[1]=d;for(var s=2;s{a.r(e),a.d(e,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>d,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},o="database",d={unversionedId:"kusion/reference/model/catalog_models/database/doc_database",id:"version-v0.9/kusion/reference/model/catalog_models/database/doc_database",title:"database",description:"Schema Database",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/database/doc_database.md",sourceDirName:"kusion/reference/model/catalog_models/database",slug:"/kusion/reference/model/catalog_models/database/doc_database",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/database/doc_database.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Service",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service"},next:{title:"prometheus",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus"}},i={},s=[{value:"Schema Database",id:"schema-database",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function u(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},p,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"database"},"database"),(0,r.kt)("h2",{id:"schema-database"},"Schema Database"),(0,r.kt)("p",null,"As an important supporting accessory, Database describes the attributes",(0,r.kt)("br",null),"to locally deploy or create a cloud provider managed database instance for ",(0,r.kt)("br",null),"the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines the local deployment mode or the specific cloud vendor that ",(0,r.kt)("br",null),"provides the relational database service (rds)."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"engine"),(0,r.kt)("br",null),"Engine defines the database engine to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the database engine version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"instanceType"),(0,r.kt)("br",null),"InstanceType defines the type of the database which is required when ",(0,r.kt)("br",null),"creating an rds instance provided by the cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"size"),(0,r.kt)("br",null),"Size defines the allocated storage size of the rds instance provided by ",(0,r.kt)("br",null),"the cloud vendor in GB."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"10"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"category"),(0,r.kt)("br",null),"Category defines the edition of the rds instance provided by the cloud ",(0,r.kt)("br",null),"vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"username"),(0,r.kt)("br",null),"Username defines the operation account for the database."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},'"root"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"securityIPs"),(0,r.kt)("br",null),"SecurityIPs defines the list of IP addresses allowed to access the rds ",(0,r.kt)("br",null),"instance provided by the cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"subnetID"),(0,r.kt)("br",null),"SubnetID defines the virtual subnet ID associated with the VPC that the rds ",(0,r.kt)("br",null),"instance will be created in."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"privateLink"),(0,r.kt)("br",null),"PrivateLink defines whether the host address of the rds instance for the workload ",(0,r.kt)("br",null),"to connect with is via public network or private network of the cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"True"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"extraMap"),(0,r.kt)("br",null),"ExtraMap defines the diversified rds configuration items from different",(0,r.kt)("br",null),"cloud vendors."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate an aws rds with mysql 5.7. \n\nimport catalog.models.schema.v1.accessories.database as db\n\ndatabase: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/407e1392.f0923f60.js b/assets/js/407e1392.f0923f60.js deleted file mode 100644 index f5083520b27..00000000000 --- a/assets/js/407e1392.f0923f60.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8119],{3905:(t,e,a)=>{a.d(e,{Zo:()=>p,kt:()=>m});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function o(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var i=n.createContext({}),s=function(t){var e=n.useContext(i),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},p=function(t){var e=s(t.components);return n.createElement(i.Provider,{value:e},t.children)},u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,i=t.parentName,p=d(t,["components","mdxType","originalType","parentName"]),c=s(a),m=r,k=c["".concat(i,".").concat(m)]||c[m]||u[m]||l;return a?n.createElement(k,o(o({ref:e},p),{},{components:a})):n.createElement(k,o({ref:e},p))}));function m(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,o=new Array(l);o[0]=c;var d={};for(var i in e)hasOwnProperty.call(e,i)&&(d[i]=e[i]);d.originalType=t,d.mdxType="string"==typeof t?t:r,o[1]=d;for(var s=2;s{a.r(e),a.d(e,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>d,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},o="database",d={unversionedId:"kusion/reference/model/catalog_models/database/doc_database",id:"version-v0.9/kusion/reference/model/catalog_models/database/doc_database",title:"database",description:"Schema Database",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/database/doc_database.md",sourceDirName:"kusion/reference/model/catalog_models/database",slug:"/kusion/reference/model/catalog_models/database/doc_database",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/database/doc_database.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Service",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service"},next:{title:"prometheus",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus"}},i={},s=[{value:"Schema Database",id:"schema-database",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function u(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},p,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"database"},"database"),(0,r.kt)("h2",{id:"schema-database"},"Schema Database"),(0,r.kt)("p",null,"As an important supporting accessory, Database describes the attributes",(0,r.kt)("br",null),"to locally deploy or create a cloud provider managed database instance for ",(0,r.kt)("br",null),"the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines the local deployment mode or the specific cloud vendor that ",(0,r.kt)("br",null),"provides the relational database service (rds)."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"engine"),(0,r.kt)("br",null),"Engine defines the database engine to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the database engine version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"instanceType"),(0,r.kt)("br",null),"InstanceType defines the type of the database which is required when ",(0,r.kt)("br",null),"creating an rds instance provided by the cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"size"),(0,r.kt)("br",null),"Size defines the allocated storage size of the rds instance provided by ",(0,r.kt)("br",null),"the cloud vendor in GB."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"10"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"category"),(0,r.kt)("br",null),"Category defines the edition of the rds instance provided by the cloud ",(0,r.kt)("br",null),"vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"username"),(0,r.kt)("br",null),"Username defines the operation account for the database."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},'"root"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"securityIPs"),(0,r.kt)("br",null),"SecurityIPs defines the list of IP addresses allowed to access the rds ",(0,r.kt)("br",null),"instance provided by the cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"subnetID"),(0,r.kt)("br",null),"SubnetID defines the virtual subnet ID associated with the VPC that the rds ",(0,r.kt)("br",null),"instance will be created in."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"privateLink"),(0,r.kt)("br",null),"PrivateLink defines whether the host address of the rds instance for the workload ",(0,r.kt)("br",null),"to connect with is via public network or private network of the cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"True"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"extraMap"),(0,r.kt)("br",null),"ExtraMap defines the diversified rds configuration items from different",(0,r.kt)("br",null),"cloud vendors."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate an aws rds with mysql 5.7. \n\nimport catalog.models.schema.v1.accessories.database as db\n\ndatabase: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/434d80d9.8389b7c3.js b/assets/js/434d80d9.8389b7c3.js new file mode 100644 index 00000000000..1be32f94363 --- /dev/null +++ b/assets/js/434d80d9.8389b7c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1132],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),f=i,m=d["".concat(l,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion preview",s={unversionedId:"kusion/reference/commands/kusion-preview",id:"kusion/reference/commands/kusion-preview",title:"kusion preview",description:"Preview a series of resource changes within the stack",source:"@site/docs/kusion/6-reference/1-commands/kusion-preview.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-preview",permalink:"/docs/next/kusion/reference/commands/kusion-preview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-preview.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion init",permalink:"/docs/next/kusion/reference/commands/kusion-init"},next:{title:"kusion version",permalink:"/docs/next/kusion/reference/commands/kusion-version"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-preview"},"kusion preview"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack."),(0,i.kt)("p",null," Create, update or delete resources according to the intent described in the a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion preview [flags]\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' # Preview with specified work directory\n kusion preview -w /path/to/workdir\n \n # Preview with specified arguments\n kusion preview -D name=test -D age=18\n \n # Preview with specified intent file\n kusion preview --intent-file intent.yaml\n \n # Preview with ignored fields\n kusion preview --ignore-fields="metadata.generation,metadata.managedFields\n \n # Preview with json format result\n kusion preview -o json\n \n # Preview without output style and color\n kusion preview --no-style=true\n')),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n -h, --help help for preview\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/434d80d9.a0959f68.js b/assets/js/434d80d9.a0959f68.js deleted file mode 100644 index 513e9c46f72..00000000000 --- a/assets/js/434d80d9.a0959f68.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1132],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),f=i,m=d["".concat(l,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion preview",s={unversionedId:"kusion/reference/commands/kusion-preview",id:"kusion/reference/commands/kusion-preview",title:"kusion preview",description:"Preview a series of resource changes within the stack",source:"@site/docs/kusion/6-reference/1-commands/kusion-preview.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-preview",permalink:"/docs/next/kusion/reference/commands/kusion-preview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-preview.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion init",permalink:"/docs/next/kusion/reference/commands/kusion-init"},next:{title:"kusion version",permalink:"/docs/next/kusion/reference/commands/kusion-version"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-preview"},"kusion preview"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack."),(0,i.kt)("p",null," Create, update or delete resources according to the intent described in the a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion preview [flags]\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' # Preview with specified work directory\n kusion preview -w /path/to/workdir\n \n # Preview with specified arguments\n kusion preview -D name=test -D age=18\n \n # Preview with specified intent file\n kusion preview --intent-file intent.yaml\n \n # Preview with ignored fields\n kusion preview --ignore-fields="metadata.generation,metadata.managedFields\n \n # Preview with json format result\n kusion preview -o json\n \n # Preview without output style and color\n kusion preview --no-style=true\n')),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n -h, --help help for preview\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4406c285.72a024a5.js b/assets/js/4406c285.c769db72.js similarity index 61% rename from assets/js/4406c285.72a024a5.js rename to assets/js/4406c285.c769db72.js index c4b39c46f93..77bb194ffdb 100644 --- a/assets/js/4406c285.72a024a5.js +++ b/assets/js/4406c285.c769db72.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4360],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||p[m]||o;return r?n.createElement(f,l(l({ref:t},u),{},{components:r})):n.createElement(f,l({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",i={unversionedId:"kusion/reference/model/catalog_models/trait/doc_opsrule",id:"version-v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule",title:"opsrule",description:"Schema OpsRule",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule.md",sourceDirName:"kusion/reference/model/catalog_models/trait",slug:"/kusion/reference/model/catalog_models/trait/doc_opsrule",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"prometheus",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus"},next:{title:"container",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container"}},s={},c=[{value:"Schema OpsRule",id:"schema-opsrule",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("h2",{id:"schema-opsrule"},"Schema OpsRule"),(0,a.kt)("p",null,"OpsRule describes operation rules for various Day-2 Operations. Once declared, these",(0,a.kt)("br",null),"operation rules will be checked before any Day-2 operations."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.component.trait as t\n\nopsRule = t.OpsRule {\n maxUnavailable: "30%"\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4360],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,f=d["".concat(s,".").concat(m)]||d[m]||p[m]||o;return r?n.createElement(f,l(l({ref:t},u),{},{components:r})):n.createElement(f,l({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",i={unversionedId:"kusion/reference/model/catalog_models/trait/doc_opsrule",id:"version-v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule",title:"opsrule",description:"Schema OpsRule",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule.md",sourceDirName:"kusion/reference/model/catalog_models/trait",slug:"/kusion/reference/model/catalog_models/trait/doc_opsrule",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"prometheus",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus"},next:{title:"container",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container"}},s={},c=[{value:"Schema OpsRule",id:"schema-opsrule",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("h2",{id:"schema-opsrule"},"Schema OpsRule"),(0,a.kt)("p",null,"OpsRule describes operation rules for various Day-2 Operations. Once declared, these",(0,a.kt)("br",null),"operation rules will be checked before any Day-2 operations."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.component.trait as t\n\nopsRule = t.OpsRule {\n maxUnavailable: "30%"\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/44a7a3de.4a4e8a9d.js b/assets/js/44a7a3de.3f45a4db.js similarity index 72% rename from assets/js/44a7a3de.4a4e8a9d.js rename to assets/js/44a7a3de.3f45a4db.js index fd31f8e448c..6187a6b4ebc 100644 --- a/assets/js/44a7a3de.4a4e8a9d.js +++ b/assets/js/44a7a3de.3f45a4db.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5911],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),i=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=i(e.components);return r.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,u=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=i(n),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const s="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>N});var r=n(87462),a=n(67294),s=n(86010),o=n(12466),l=n(76775),u=n(91980),i=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.k6)(),s=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=d(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[u,i]=f({queryString:n,groupId:r}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),h=(()=>{const e=u??p;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{h&&l(h)}),[h]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),b(e)}),[i,b,s]),tabValues:s}}var h=n(72389);const k="tabList__CuJ",g="tabItem_LNqP";function v(e){let{className:t,block:n,selectedValue:l,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=i[n].value;r!==l&&(p(t),u(r))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},i.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,s.Z)("tabs__item",g,null==o?void 0:o.className,{"tabs__item--active":l===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},s.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function w(e){const t=b(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",k)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function N(e){const t=(0,h.Z)();return a.createElement(w,(0,r.Z)({key:String(t)},e))}},58748:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905)),s=n(74866),o=n(85162);const l={},u="Install Kusion",i={unversionedId:"kusion/getting-started/install-kusion",id:"kusion/getting-started/install-kusion",title:"Install Kusion",description:"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.",source:"@site/docs/kusion/2-getting-started/1-install-kusion.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/install-kusion",permalink:"/docs/next/kusion/getting-started/install-kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/2-getting-started/1-install-kusion.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion vs Other Software",permalink:"/docs/next/kusion/what-is-kusion/kusion-vs-x"},next:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/next/kusion/getting-started/deliver-wordpress"}},c={},p=[],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"install-kusion"},"Install Kusion"),(0,a.kt)("p",null,"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below."),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Homebrew",mdxType:"TabItem"},(0,a.kt)("p",null,"The recommended method for installing on MacOS and Linux is to use the brew package manager."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# tap formula repository Kusionstack/tap\nbrew tap KusionStack/tap\n\n# install Kusion \nbrew install KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Update Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# update formulae from remote\nbrew update\n\n# update Kusion\nbrew upgrade KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\nbrew uninstall KusionStack/tap/kusion\n"))),(0,a.kt)(o.Z,{value:"curl | sh",mdxType:"TabItem"},(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion, default latest version\ncurl https://www.kusionstack.io/scripts/install.sh | sh\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install the Specified Version of Kusion")),(0,a.kt)("p",null,"You can also install the specified version of Kusion by appointing the version as shell script parameter, where the version is the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/tags"},"available tag"),' trimming prefix "v", such as 0.10.0, 0.9.0, etc. In general, you don\'t need to specify Kusion version, just use the command above to install the latest version.'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion of specified version 0.10.0\ncurl https://www.kusionstack.io/scripts/install.sh | sh -s 0.10.0\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\ncurl https://www.kusionstack.io/scripts/uninstall.sh | sh\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5911],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),i=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=i(e.components);return r.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,u=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=i(n),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const s="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>N});var r=n(87462),a=n(67294),s=n(86010),o=n(12466),l=n(76775),u=n(91980),i=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.k6)(),s=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=d(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[u,i]=f({queryString:n,groupId:r}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),h=(()=>{const e=u??p;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{h&&l(h)}),[h]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),b(e)}),[i,b,s]),tabValues:s}}var h=n(72389);const k="tabList__CuJ",g="tabItem_LNqP";function v(e){let{className:t,block:n,selectedValue:l,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=i[n].value;r!==l&&(p(t),u(r))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},i.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,s.Z)("tabs__item",g,null==o?void 0:o.className,{"tabs__item--active":l===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},s.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function w(e){const t=b(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",k)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function N(e){const t=(0,h.Z)();return a.createElement(w,(0,r.Z)({key:String(t)},e))}},58748:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905)),s=n(74866),o=n(85162);const l={},u="Install Kusion",i={unversionedId:"kusion/getting-started/install-kusion",id:"kusion/getting-started/install-kusion",title:"Install Kusion",description:"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.",source:"@site/docs/kusion/2-getting-started/1-install-kusion.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/install-kusion",permalink:"/docs/next/kusion/getting-started/install-kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/2-getting-started/1-install-kusion.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion vs Other Software",permalink:"/docs/next/kusion/what-is-kusion/kusion-vs-x"},next:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/next/kusion/getting-started/deliver-wordpress"}},c={},p=[],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"install-kusion"},"Install Kusion"),(0,a.kt)("p",null,"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below."),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Homebrew",mdxType:"TabItem"},(0,a.kt)("p",null,"The recommended method for installing on MacOS and Linux is to use the brew package manager."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# tap formula repository Kusionstack/tap\nbrew tap KusionStack/tap\n\n# install Kusion \nbrew install KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Update Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# update formulae from remote\nbrew update\n\n# update Kusion\nbrew upgrade KusionStack/tap/kusion\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\nbrew uninstall KusionStack/tap/kusion\n"))),(0,a.kt)(o.Z,{value:"curl | sh",mdxType:"TabItem"},(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion, default latest version\ncurl https://www.kusionstack.io/scripts/install.sh | sh\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Install the Specified Version of Kusion")),(0,a.kt)("p",null,"You can also install the specified version of Kusion by appointing the version as shell script parameter, where the version is the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/tags"},"available tag"),' trimming prefix "v", such as 0.10.0, 0.9.0, etc. In general, you don\'t need to specify Kusion version, just use the command above to install the latest version.'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# install Kusion of specified version 0.10.0\ncurl https://www.kusionstack.io/scripts/install.sh | sh -s 0.10.0\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Uninstall Kusion")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"# uninstall Kusion\ncurl https://www.kusionstack.io/scripts/uninstall.sh | sh\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/45bfe338.470cc412.js b/assets/js/45bfe338.470cc412.js new file mode 100644 index 00000000000..84117968248 --- /dev/null +++ b/assets/js/45bfe338.470cc412.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4759],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),m=p(n),u=r,g=m["".concat(s,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(g,l(l({ref:t},d),{},{components:n})):a.createElement(g,l({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={},l="appconfiguration",i={unversionedId:"kusion/reference/modules/catalog-models/app-configuration",id:"version-v0.10/kusion/reference/modules/catalog-models/app-configuration",title:"appconfiguration",description:"Schema AppConfiguration",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models",slug:"/kusion/reference/modules/catalog-models/app-configuration",permalink:"/docs/kusion/reference/modules/catalog-models/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Modules",permalink:"/docs/kusion/reference/modules/"},next:{title:"mysql",permalink:"/docs/kusion/reference/modules/catalog-models/database/mysql"}},s={},p=[{value:"Schema AppConfiguration",id:"schema-appconfiguration",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"appconfiguration"},"appconfiguration"),(0,r.kt)("h2",{id:"schema-appconfiguration"},"Schema AppConfiguration"),(0,r.kt)("p",null,"AppConfiguration is a developer-centric definition that describes how to run an Application.",(0,r.kt)("br",null),"This application model builds upon a decade of experience at AntGroup running super large scale",(0,r.kt)("br",null),"internal developer platform, combined with best-of-breed ideas and practices from the community."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workload"),(0,r.kt)("br",null),"Workload defines how to run your application code. Currently supported workload profile",(0,r.kt)("br",null),"includes Service and Job."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/service#schema-service"},"workload.Service")," \\ "),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/job#schema-job"},"workload.Job")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"opsRule"),(0,r.kt)("br",null),"OpsRule specifies collection of rules that will be checked for Day-2 operation."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"trait/opsrule#schema-opsrule"},"trait.OpsRule")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"database"),(0,r.kt)("br",null),"Database describes a locally deployed or a cloud provider managed database instance for the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"database/mysql#schema-mysql"},"mysql.MySQL")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"database/postgres#schema-postgresql"},"postgres.PostgreSQL"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"monitoring")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"monitoring/prometheus#schema-prometheus"},"monitoring.Prometheus")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate an App with a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.accessories.database as db\nimport catalog.models.schema.v1.accessories.monitoring as m\nimport catalog.models.schema.v1.accessories.trait as t\n\nappConfiguration = ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n type: "CollaSet"\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n database: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/45bfe338.adb144b4.js b/assets/js/45bfe338.adb144b4.js deleted file mode 100644 index 2811b49f4c9..00000000000 --- a/assets/js/45bfe338.adb144b4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4759],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),m=p(n),u=r,g=m["".concat(s,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(g,l(l({ref:t},d),{},{components:n})):a.createElement(g,l({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const o={},l="appconfiguration",i={unversionedId:"kusion/reference/modules/catalog-models/app-configuration",id:"version-v0.10/kusion/reference/modules/catalog-models/app-configuration",title:"appconfiguration",description:"Schema AppConfiguration",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models",slug:"/kusion/reference/modules/catalog-models/app-configuration",permalink:"/docs/kusion/reference/modules/catalog-models/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Modules",permalink:"/docs/kusion/reference/modules/"},next:{title:"mysql",permalink:"/docs/kusion/reference/modules/catalog-models/database/mysql"}},s={},p=[{value:"Schema AppConfiguration",id:"schema-appconfiguration",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"appconfiguration"},"appconfiguration"),(0,r.kt)("h2",{id:"schema-appconfiguration"},"Schema AppConfiguration"),(0,r.kt)("p",null,"AppConfiguration is a developer-centric definition that describes how to run an Application.",(0,r.kt)("br",null),"This application model builds upon a decade of experience at AntGroup running super large scale",(0,r.kt)("br",null),"internal developer platform, combined with best-of-breed ideas and practices from the community."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workload"),(0,r.kt)("br",null),"Workload defines how to run your application code. Currently supported workload profile",(0,r.kt)("br",null),"includes Service and Job."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/service#schema-service"},"workload.Service")," \\ "),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"workload/job#schema-job"},"workload.Job")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"opsRule"),(0,r.kt)("br",null),"OpsRule specifies collection of rules that will be checked for Day-2 operation."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"trait/opsrule#schema-opsrule"},"trait.OpsRule")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"database"),(0,r.kt)("br",null),"Database describes a locally deployed or a cloud provider managed database instance for the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"database/mysql#schema-mysql"},"mysql.MySQL")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"database/postgres#schema-postgresql"},"postgres.PostgreSQL"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"monitoring")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"monitoring/prometheus#schema-prometheus"},"monitoring.Prometheus")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate an App with a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.accessories.database as db\nimport catalog.models.schema.v1.accessories.monitoring as m\nimport catalog.models.schema.v1.accessories.trait as t\n\nappConfiguration = ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n type: "CollaSet"\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n database: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/47d45151.18ace9fc.js b/assets/js/47d45151.18ace9fc.js deleted file mode 100644 index 4e131c98ab8..00000000000 --- a/assets/js/47d45151.18ace9fc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3537],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,k=u["".concat(c,".").concat(m)]||u[m]||d[m]||s;return n?r.createElement(k,o(o({ref:t},p),{},{components:n})):r.createElement(k,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=u;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const s={id:"secret"},o="Secrets",i={unversionedId:"kusion/configuration-walkthrough/secret",id:"version-v0.10/kusion/configuration-walkthrough/secret",title:"Secrets",description:"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/7-secret.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/secret",permalink:"/docs/kusion/configuration-walkthrough/secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/7-secret.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"secret"},sidebar:"kusion",previous:{title:"Managed Databases",permalink:"/docs/kusion/configuration-walkthrough/databse"},next:{title:"Application Monitoring",permalink:"/docs/kusion/configuration-walkthrough/monitoring"}},c={},l=[{value:"Using secrets in workload",id:"using-secrets-in-workload",level:2},{value:"Consume secret in an environment variable",id:"consume-secret-in-an-environment-variable",level:3},{value:"Consume all secret keys as environment variables",id:"consume-all-secret-keys-as-environment-variables",level:3},{value:"Types of secrets",id:"types-of-secrets",level:2},{value:"Basic secrets",id:"basic-secrets",level:3},{value:"Token secrets",id:"token-secrets",level:3},{value:"Opaque secrets",id:"opaque-secrets",level:3},{value:"Certificate secrets",id:"certificate-secrets",level:3},{value:"External secrets",id:"external-secrets",level:3},{value:"Immutable secrets",id:"immutable-secrets",level:2}],p={toc:l};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secrets"},"Secrets"),(0,a.kt)("p",null,"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers."),(0,a.kt)("p",null,"For application dependent cloud resources that are managed by Kusion, their credentials are automatically managed by Kusion (generated and injected into application runtime environment variable). You shouldn't have to manually create those."),(0,a.kt)("h2",{id:"using-secrets-in-workload"},"Using secrets in workload"),(0,a.kt)("p",null,"Secrets must be defined in AppConfiguration. The values can be generated by Kusion or reference existing secrets stored in third-party vault. Secrets can be consumed in containers by referencing them through the ",(0,a.kt)("inlineCode",{parentName:"p"},"secret:///")," URI syntax."),(0,a.kt)("h3",{id:"consume-secret-in-an-environment-variable"},"Consume secret in an environment variable"),(0,a.kt)("p",null,"You can consume the data in Secrets as environment variable in your container. For example the db container uses an environment variable to set the root password."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume db-root-password secret in environment\n "ROOT_PASSWORD": "secret://db-root-password/token"\n }\n }\n }\n # Secrets used to generate token\n secrets: {\n "init-info": sec.Secret {\n type: "token"\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The example shows the secret ",(0,a.kt)("inlineCode",{parentName:"p"},"root-password")," being consumed as an environment variable in the db container. The secret is of type token and will automatically be generated at runtime by Kusion."),(0,a.kt)("h3",{id:"consume-all-secret-keys-as-environment-variables"},"Consume all secret keys as environment variables"),(0,a.kt)("p",null,"Sometimes your secret contains multiple data that need to be consumed as environment variables. The example below shows how to consume all the values in a secret as environment variables named after the keys."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume all init-info secret keys as environment variables\n "secret://init-info": ""\n }\n }\n }\n # Secrets used to init mysql instance\n secrets: {\n "init-info": sec.Secret {\n type: "opaque"\n data: {\n "ROOT_PASSWORD": "admin"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,'This will set the environment variable "ROOT_PASSWORD" to the value "admin" in the db container.'),(0,a.kt)("h2",{id:"types-of-secrets"},"Types of secrets"),(0,a.kt)("p",null,"Kusion provides multiple types of secrets to application developers."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Basic: Used to generate and/or store usernames and passwords."),(0,a.kt)("li",{parentName:"ol"},"Token: Used to generate and/or store secret strings for password."),(0,a.kt)("li",{parentName:"ol"},"Opaque: A generic secret that can store arbitrary user-defined data."),(0,a.kt)("li",{parentName:"ol"},"Certificate: Used to store a certificate and its associated key that are typically used for TLS."),(0,a.kt)("li",{parentName:"ol"},"External: Used to retrieve secret form third-party vault.")),(0,a.kt)("h3",{id:"basic-secrets"},"Basic secrets"),(0,a.kt)("p",null,'Basic secrets are defined in the secrets block with the type "basic".'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "auth-info": sec.Secret {\n type: "basic"\n data: {\n "username": "admin"\n "password": "******"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The basic secret type is typically used for basic authentication. The key names must be username and password. If one or both of the fields are defined with a non-empty string, those values will be used. If the empty string, the default value, is used Acorn will generate random values for one or both."),(0,a.kt)("h3",{id:"token-secrets"},"Token secrets"),(0,a.kt)("p",null,"Token secrets are useful for generating a password or secure string used for passwords when the user is already known or not required."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-token": sec.Secret {\n type: "token"\n data: {\n "token": ""\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The token secret type must be defined. The ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," field in the data object is optional and if left empty Kusion will generate the token, which is 54 characters in length by default. If the ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," is defined that value will always be used."),(0,a.kt)("h3",{id:"opaque-secrets"},"Opaque secrets"),(0,a.kt)("p",null,"Opaque secrets have no defined structure and can have arbitrary key value pairs. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "opaque"\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"certificate-secrets"},"Certificate secrets"),(0,a.kt)("p",null,"Certificate secrets are useful for storing a certificate and its associated key. One common use for TLS Secrets is to configure encryption in transit for an Ingress, but you can also use it with other resources or directly in your workload."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "server-cert": sec.Secret {\n type: "certificate"\n data: {\n # Please do not put private keys in configuration files\n "tls.crt": "The cert file content"\n "tls.key": "The key file content"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"external-secrets"},"External secrets"),(0,a.kt)("p",null,"As a general principle, storing secrets in a plain text configuration file is highly discouraged, keeping secrets outside of Git is especially important for future-proofing, even encrypted secrets are not recommended to check into Git. The most common approach is to store secrets in a third-party vault (such as Hashicorp Vault, AWS Secrets Manager and Azure Key Vault, etc) and retrieve the secret in the runtime only. External secrets are used to retrieve sensitive data from external secret store to make it easy to be consumed in containers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-access-token": sec.Secret {\n type: "external"\n data: {\n # Please do not put private keys in configuration files\n "accessToken": "ref://api-auth-info/accessToken?version=1"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The value field in data object follow ",(0,a.kt)("inlineCode",{parentName:"p"},"ref://PATH[?version=]")," URI syntax. ",(0,a.kt)("inlineCode",{parentName:"p"},"PATH")," is the provider-specific path for the secret to be retried. Kusion provides out-of-the-box integration with ",(0,a.kt)("inlineCode",{parentName:"p"},"Hashicorp Vault"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"AWS Secrets Manager"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Azure Key Vault")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Alicloud Secrets Manager"),"."),(0,a.kt)("h2",{id:"immutable-secrets"},"Immutable secrets"),(0,a.kt)("p",null,"You can also declare a secret as immutable to prevent it from being changed accidentally."),(0,a.kt)("p",null,"To declare a secret as immutable:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n # ...\n immutable: True\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"You can change a secret from mutable to immutable but not the other way around. That is because the Kubelet will stop watching secrets that are immutable. As the name suggests, you can only delete and re-create immutable secrets but you cannot change them."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/47d45151.e66857e2.js b/assets/js/47d45151.e66857e2.js new file mode 100644 index 00000000000..b2e78217835 --- /dev/null +++ b/assets/js/47d45151.e66857e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3537],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,k=u["".concat(c,".").concat(m)]||u[m]||d[m]||s;return n?r.createElement(k,o(o({ref:t},p),{},{components:n})):r.createElement(k,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=u;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const s={id:"secret"},o="Secrets",i={unversionedId:"kusion/configuration-walkthrough/secret",id:"version-v0.10/kusion/configuration-walkthrough/secret",title:"Secrets",description:"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/7-secret.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/secret",permalink:"/docs/kusion/configuration-walkthrough/secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/7-secret.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"secret"},sidebar:"kusion",previous:{title:"Managed Databases",permalink:"/docs/kusion/configuration-walkthrough/databse"},next:{title:"Application Monitoring",permalink:"/docs/kusion/configuration-walkthrough/monitoring"}},c={},l=[{value:"Using secrets in workload",id:"using-secrets-in-workload",level:2},{value:"Consume secret in an environment variable",id:"consume-secret-in-an-environment-variable",level:3},{value:"Consume all secret keys as environment variables",id:"consume-all-secret-keys-as-environment-variables",level:3},{value:"Types of secrets",id:"types-of-secrets",level:2},{value:"Basic secrets",id:"basic-secrets",level:3},{value:"Token secrets",id:"token-secrets",level:3},{value:"Opaque secrets",id:"opaque-secrets",level:3},{value:"Certificate secrets",id:"certificate-secrets",level:3},{value:"External secrets",id:"external-secrets",level:3},{value:"Immutable secrets",id:"immutable-secrets",level:2}],p={toc:l};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secrets"},"Secrets"),(0,a.kt)("p",null,"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers."),(0,a.kt)("p",null,"For application dependent cloud resources that are managed by Kusion, their credentials are automatically managed by Kusion (generated and injected into application runtime environment variable). You shouldn't have to manually create those."),(0,a.kt)("h2",{id:"using-secrets-in-workload"},"Using secrets in workload"),(0,a.kt)("p",null,"Secrets must be defined in AppConfiguration. The values can be generated by Kusion or reference existing secrets stored in third-party vault. Secrets can be consumed in containers by referencing them through the ",(0,a.kt)("inlineCode",{parentName:"p"},"secret:///")," URI syntax."),(0,a.kt)("h3",{id:"consume-secret-in-an-environment-variable"},"Consume secret in an environment variable"),(0,a.kt)("p",null,"You can consume the data in Secrets as environment variable in your container. For example the db container uses an environment variable to set the root password."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume db-root-password secret in environment\n "ROOT_PASSWORD": "secret://db-root-password/token"\n }\n }\n }\n # Secrets used to generate token\n secrets: {\n "init-info": sec.Secret {\n type: "token"\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The example shows the secret ",(0,a.kt)("inlineCode",{parentName:"p"},"root-password")," being consumed as an environment variable in the db container. The secret is of type token and will automatically be generated at runtime by Kusion."),(0,a.kt)("h3",{id:"consume-all-secret-keys-as-environment-variables"},"Consume all secret keys as environment variables"),(0,a.kt)("p",null,"Sometimes your secret contains multiple data that need to be consumed as environment variables. The example below shows how to consume all the values in a secret as environment variables named after the keys."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\nsampledb: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "db": c.Container {\n image: "mysql"\n env: {\n # Consume all init-info secret keys as environment variables\n "secret://init-info": ""\n }\n }\n }\n # Secrets used to init mysql instance\n secrets: {\n "init-info": sec.Secret {\n type: "opaque"\n data: {\n "ROOT_PASSWORD": "admin"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,'This will set the environment variable "ROOT_PASSWORD" to the value "admin" in the db container.'),(0,a.kt)("h2",{id:"types-of-secrets"},"Types of secrets"),(0,a.kt)("p",null,"Kusion provides multiple types of secrets to application developers."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Basic: Used to generate and/or store usernames and passwords."),(0,a.kt)("li",{parentName:"ol"},"Token: Used to generate and/or store secret strings for password."),(0,a.kt)("li",{parentName:"ol"},"Opaque: A generic secret that can store arbitrary user-defined data."),(0,a.kt)("li",{parentName:"ol"},"Certificate: Used to store a certificate and its associated key that are typically used for TLS."),(0,a.kt)("li",{parentName:"ol"},"External: Used to retrieve secret form third-party vault.")),(0,a.kt)("h3",{id:"basic-secrets"},"Basic secrets"),(0,a.kt)("p",null,'Basic secrets are defined in the secrets block with the type "basic".'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "auth-info": sec.Secret {\n type: "basic"\n data: {\n "username": "admin"\n "password": "******"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The basic secret type is typically used for basic authentication. The key names must be username and password. If one or both of the fields are defined with a non-empty string, those values will be used. If the empty string, the default value, is used Acorn will generate random values for one or both."),(0,a.kt)("h3",{id:"token-secrets"},"Token secrets"),(0,a.kt)("p",null,"Token secrets are useful for generating a password or secure string used for passwords when the user is already known or not required."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-token": sec.Secret {\n type: "token"\n data: {\n "token": ""\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The token secret type must be defined. The ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," field in the data object is optional and if left empty Kusion will generate the token, which is 54 characters in length by default. If the ",(0,a.kt)("inlineCode",{parentName:"p"},"token")," is defined that value will always be used."),(0,a.kt)("h3",{id:"opaque-secrets"},"Opaque secrets"),(0,a.kt)("p",null,"Opaque secrets have no defined structure and can have arbitrary key value pairs. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "opaque"\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"certificate-secrets"},"Certificate secrets"),(0,a.kt)("p",null,"Certificate secrets are useful for storing a certificate and its associated key. One common use for TLS Secrets is to configure encryption in transit for an Ingress, but you can also use it with other resources or directly in your workload."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "server-cert": sec.Secret {\n type: "certificate"\n data: {\n # Please do not put private keys in configuration files\n "tls.crt": "The cert file content"\n "tls.key": "The key file content"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"external-secrets"},"External secrets"),(0,a.kt)("p",null,"As a general principle, storing secrets in a plain text configuration file is highly discouraged, keeping secrets outside of Git is especially important for future-proofing, even encrypted secrets are not recommended to check into Git. The most common approach is to store secrets in a third-party vault (such as Hashicorp Vault, AWS Secrets Manager and Azure Key Vault, etc) and retrieve the secret in the runtime only. External secrets are used to retrieve sensitive data from external secret store to make it easy to be consumed in containers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "api-access-token": sec.Secret {\n type: "external"\n data: {\n # Please do not put private keys in configuration files\n "accessToken": "ref://api-auth-info/accessToken?version=1"\n }\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"The value field in data object follow ",(0,a.kt)("inlineCode",{parentName:"p"},"ref://PATH[?version=]")," URI syntax. ",(0,a.kt)("inlineCode",{parentName:"p"},"PATH")," is the provider-specific path for the secret to be retried. Kusion provides out-of-the-box integration with ",(0,a.kt)("inlineCode",{parentName:"p"},"Hashicorp Vault"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"AWS Secrets Manager"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Azure Key Vault")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Alicloud Secrets Manager"),"."),(0,a.kt)("h2",{id:"immutable-secrets"},"Immutable secrets"),(0,a.kt)("p",null,"You can also declare a secret as immutable to prevent it from being changed accidentally."),(0,a.kt)("p",null,"To declare a secret as immutable:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.secret as sec\n\nsampleapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n # ...\n immutable: True\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"You can change a secret from mutable to immutable but not the other way around. That is because the Kubelet will stop watching secrets that are immutable. As the name suggests, you can only delete and re-create immutable secrets but you cannot change them."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/497c7ba5.6e9bf2ab.js b/assets/js/497c7ba5.6e9bf2ab.js new file mode 100644 index 00000000000..a389970f7f3 --- /dev/null +++ b/assets/js/497c7ba5.6e9bf2ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2364],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(n),d=r,h=m["".concat(c,".").concat(d)]||m[d]||u[d]||o;return n?a.createElement(h,i(i({ref:t},p),{},{components:n})):a.createElement(h,i({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var a=n(87462),r=(n(67294),n(3905));const o={sidebar_position:7},i="Secret Management",s={unversionedId:"kusion/config-walkthrough/secret",id:"version-v0.9/kusion/config-walkthrough/secret",title:"Secret Management",description:"You can manage application secrets via the secrets attribute in the workload schema. Depending on the context of your application, this might include pieces of credentials required to access a third-party application.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/secret.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/secret",permalink:"/docs/v0.9/kusion/config-walkthrough/secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/secret.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"kusion",previous:{title:"Managed Databases",permalink:"/docs/v0.9/kusion/config-walkthrough/database"},next:{title:"Application Monitoring",permalink:"/docs/v0.9/kusion/config-walkthrough/monitoring"}},c={},l=[{value:"Import",id:"import",level:2},{value:"Creating a secret",id:"creating-a-secret",level:2},{value:"Immutable secrets",id:"immutable-secrets",level:2}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"secret-management"},"Secret Management"),(0,r.kt)("p",null,"You can manage application secrets via the ",(0,r.kt)("inlineCode",{parentName:"p"},"secrets")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"workload")," schema. Depending on the context of your application, this might include pieces of credentials required to access a third-party application."),(0,r.kt)("p",null,"If your application depends on any cloud resources that are managed by Kusion, their credentials are automatically managed by Kusion (generated and injected into application runtime environment variable). You shouldn't have to manually create those."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If your application workloads are also running on the cloud, it's recommended to leverage identity-based keyless authentication as much as possible to minimize the nuisance of secret management. Application identities will be supported in a future version of Kusion.")),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.secret as sec\n")),(0,r.kt)("h2",{id:"creating-a-secret"},"Creating a secret"),(0,r.kt)("p",null,"As of version 0.9.0, Kusion supports creating secrets by turning the ",(0,r.kt)("inlineCode",{parentName:"p"},"secrets")," declared in the configuration files into Kubernetes secrets."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"As a general principle, storing secrets in a plain text configuration file is highly discouraged. The recommended approach is to store the secrets in a third-party vault (such as Hashicorp Vault, AWS Secrets Manager and KMS, Azure Key Vault, etc) and retrieve the secret in the runtime only.")),(0,r.kt)("p",null,"Create a secret with the type ",(0,r.kt)("inlineCode",{parentName:"p"},"Opaque"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "opaque"\n data: {\n "hello": "world"\n "foo": "bar"\n }\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"Create a secret with the type ",(0,r.kt)("inlineCode",{parentName:"p"},"kubernetes.io/basic-auth"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "basic"\n data: {\n "username": "admin"\n "password": "******"\n }\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"When creating a ",(0,r.kt)("inlineCode",{parentName:"p"},"kubernetes.io/basic-auth")," type secret, the ",(0,r.kt)("inlineCode",{parentName:"p"},"data")," field must have at least one of ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"password"),"."),(0,r.kt)("p",null,"For more details about the secret types, please see the ",(0,r.kt)("a",{parentName:"p",href:"https://kubernetes.io/docs/concepts/configuration/secret/"},"Kubernetes secret documentation"),"."),(0,r.kt)("h2",{id:"immutable-secrets"},"Immutable secrets"),(0,r.kt)("p",null,"You can also declare a secret as immutable to prevent it from being changed accidentally."),(0,r.kt)("p",null,"To declare a secret as immutable:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n # ...\n immutable: True\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"You can change a secret from mutable to immutable but not the other way around. That is because the Kubelet will stop watching secrets that are immutable. As the name suggests, you can only delete and re-create immutable secrets but you cannot change them."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/497c7ba5.a4ee2553.js b/assets/js/497c7ba5.a4ee2553.js deleted file mode 100644 index 3fda7bcb26b..00000000000 --- a/assets/js/497c7ba5.a4ee2553.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2364],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(n),d=r,h=m["".concat(c,".").concat(d)]||m[d]||u[d]||o;return n?a.createElement(h,i(i({ref:t},p),{},{components:n})):a.createElement(h,i({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var a=n(87462),r=(n(67294),n(3905));const o={sidebar_position:7},i="Secret Management",s={unversionedId:"kusion/config-walkthrough/secret",id:"version-v0.9/kusion/config-walkthrough/secret",title:"Secret Management",description:"You can manage application secrets via the secrets attribute in the workload schema. Depending on the context of your application, this might include pieces of credentials required to access a third-party application.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/secret.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/secret",permalink:"/docs/v0.9/kusion/config-walkthrough/secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/secret.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"kusion",previous:{title:"Managed Databases",permalink:"/docs/v0.9/kusion/config-walkthrough/database"},next:{title:"Application Monitoring",permalink:"/docs/v0.9/kusion/config-walkthrough/monitoring"}},c={},l=[{value:"Import",id:"import",level:2},{value:"Creating a secret",id:"creating-a-secret",level:2},{value:"Immutable secrets",id:"immutable-secrets",level:2}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"secret-management"},"Secret Management"),(0,r.kt)("p",null,"You can manage application secrets via the ",(0,r.kt)("inlineCode",{parentName:"p"},"secrets")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"workload")," schema. Depending on the context of your application, this might include pieces of credentials required to access a third-party application."),(0,r.kt)("p",null,"If your application depends on any cloud resources that are managed by Kusion, their credentials are automatically managed by Kusion (generated and injected into application runtime environment variable). You shouldn't have to manually create those."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If your application workloads are also running on the cloud, it's recommended to leverage identity-based keyless authentication as much as possible to minimize the nuisance of secret management. Application identities will be supported in a future version of Kusion.")),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.secret as sec\n")),(0,r.kt)("h2",{id:"creating-a-secret"},"Creating a secret"),(0,r.kt)("p",null,"As of version 0.9.0, Kusion supports creating secrets by turning the ",(0,r.kt)("inlineCode",{parentName:"p"},"secrets")," declared in the configuration files into Kubernetes secrets."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"As a general principle, storing secrets in a plain text configuration file is highly discouraged. The recommended approach is to store the secrets in a third-party vault (such as Hashicorp Vault, AWS Secrets Manager and KMS, Azure Key Vault, etc) and retrieve the secret in the runtime only.")),(0,r.kt)("p",null,"Create a secret with the type ",(0,r.kt)("inlineCode",{parentName:"p"},"Opaque"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "opaque"\n data: {\n "hello": "world"\n "foo": "bar"\n }\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"Create a secret with the type ",(0,r.kt)("inlineCode",{parentName:"p"},"kubernetes.io/basic-auth"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n type: "basic"\n data: {\n "username": "admin"\n "password": "******"\n }\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"When creating a ",(0,r.kt)("inlineCode",{parentName:"p"},"kubernetes.io/basic-auth")," type secret, the ",(0,r.kt)("inlineCode",{parentName:"p"},"data")," field must have at least one of ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"password"),"."),(0,r.kt)("p",null,"For more details about the secret types, please see the ",(0,r.kt)("a",{parentName:"p",href:"https://kubernetes.io/docs/concepts/configuration/secret/"},"Kubernetes secret documentation"),"."),(0,r.kt)("h2",{id:"immutable-secrets"},"Immutable secrets"),(0,r.kt)("p",null,"You can also declare a secret as immutable to prevent it from being changed accidentally."),(0,r.kt)("p",null,"To declare a secret as immutable:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n secrets: {\n "my-secret": sec.Secret {\n # ...\n immutable: True\n }\n }\n }\n}\n')),(0,r.kt)("p",null,"You can change a secret from mutable to immutable but not the other way around. That is because the Kubelet will stop watching secrets that are immutable. As the name suggests, you can only delete and re-create immutable secrets but you cannot change them."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4a6d5a33.33808d51.js b/assets/js/4a6d5a33.33808d51.js new file mode 100644 index 00000000000..cba301e8578 --- /dev/null +++ b/assets/js/4a6d5a33.33808d51.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5612],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return n?o.createElement(h,a(a({ref:t},p),{},{components:n})):o.createElement(h,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:2},a="PodOpsLifecycle",l={unversionedId:"operating/concepts/podopslifecycle",id:"version-v0.9/operating/concepts/podopslifecycle",title:"PodOpsLifecycle",description:"Background",source:"@site/versioned_docs/version-v0.9/operating/concepts/podopslifecycle.md",sourceDirName:"operating/concepts",slug:"/operating/concepts/podopslifecycle",permalink:"/docs/v0.9/operating/concepts/podopslifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/concepts/podopslifecycle.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/v0.9/operating/started/demo-graceful-operation"},next:{title:"CollaSet",permalink:"/docs/v0.9/operating/manuals/collaset"}},c={},s=[{value:"Background",id:"background",level:2},{value:"Introduction",id:"introduction",level:2},{value:"Developer's Guide",id:"developers-guide",level:2},{value:"Operation Controller",id:"operation-controller",level:3},{value:"Pod Cooperation Controller",id:"pod-cooperation-controller",level:3},{value:"Key Features",id:"key-features",level:2},{value:"Concurrency Support",id:"concurrency-support",level:3}],p={toc:s};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"podopslifecycle"},"PodOpsLifecycle"),(0,r.kt)("h2",{id:"background"},"Background"),(0,r.kt)("p",null,"Kubernetes provides a set of default controllers for workload management, such as StatefulSet, Deployment, and DaemonSet, which are responsible for Pod operations.\nMeanwhile, application users may also have some services outside the Kubernetes cluster that are closely related to the Pod Lifecycle, including traffic routing, service discovery, or alert monitoring.\nHowever, they face challenges in participating in the operational lifecycle of a Pod, even if they are connected to Kubernetes by developing a controller that watches the Pods."),(0,r.kt)("p",null,"PodOpsLifecycle aims to offer Kubernetes administrators and developers finer-grained control over the entire lifecycle of a Pod.\nIt enables developers to execute necessary actions before, during, and after specific phases of a Pod operation.\nFor instance, removing the Pod's IP from the traffic route before initiating the Pod operation, performing the actual Pod operations, and adding it back after the Pod operation is completed to achieve a smooth and graceful Pod operation, and prevent any traffic loss."),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"In PodOpsLifecycle, participants are classified into two roles: ",(0,r.kt)("inlineCode",{parentName:"p"},"operation controllers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"cooperation controllers"),"."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operation controllers")," are responsible for operating Pods, such as Deployments and StatefulSets from Kubernetes, and CollaSets from Operating which intend to scale, update, or recreate Pods."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Cooperation controllers")," are sensitive with Pod status. They handle resources or configurations around Pods, which may include traffic controller, alert monitoring controller, etc. These controllers typically reconcile Kubernetes resources around Pods with external services, such as sync Pod IPs with the LB provider, or maintaining Pods' metadata with application monitoring system.")),(0,r.kt)("p",null,"The two types of controllers do not need to be aware of each other. All controllers are organized by PodOpsLifecycle. Additionally, KusionStack Operating introduces extra phases around the native Kubernetes Pod Lifecycle: ServiceAvailable, Preparing, and Completing."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle",src:n(79164).Z,width:"1500",height:"978"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Completing"),": After a Pod is created or updated and becomes ready, Operating marks its PodOpsLifecycle as the ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing")," phase. During this phase, the Pod is in a ready condition, prompting cooperation controllers to perform actions such as registering the Pod IP in the traffic route. Once all cooperation controllers complete their tasks, Operating sets the PodOpsLifecycle to the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"ServiceAvailable"),": This phase indicates that the Pod is in a normal state and ready to serve. If everything goes smoothly, the Pod remains in the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase until the next operation."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Preparing"),": When an operation controller needs to operate the Pod, it triggers a new PodOpsLifecycle. The Pod then transitions from the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase to the ",(0,r.kt)("inlineCode",{parentName:"li"},"Preparing")," phase. During this phase, the Pod is initially marked as Unready by setting ReadinessGate to false. All cooperation controllers then begin preparing tasks, such as removing the Pod's IP from the traffic route. After completing these tasks, the Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operating"),": If a Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase, it is expected to accept any kind of operation without any damage, including recreation, scaling-in, upgrading, etc. Operation controllers are permitted to apply any changes to this Pod. Once all these operations are completed, the Pod advances to the next phase \u2014 ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing"),", and the PodOpsLifecycle continues.")),(0,r.kt)("p",null,"The PodOpsLifecycle detail and the relationship with Kubernetes native Pod Lifecycle is showed by following sequence diagram."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle-sequence-diagram",src:n(57590).Z,width:"1500",height:"694"})),(0,r.kt)("h2",{id:"developers-guide"},"Developer's Guide"),(0,r.kt)("p",null,"This section introduces how to develop operation controllers and cooperation controllers to interact with PodOpsLifecycle."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The operation controller is responsible for a set of Pod operation tasks. KusionStack Operating has already provided various types of operation controllers. Users only need to develop a new operation controller if a new kind of Pod operation needs to be added."),(0,r.kt)("li",{parentName:"ul"},"The cooperation controller participates in PodOpsLifecycle before and after operating on a Pod, such as the Traffic controller, alert monitoring controller, and other controllers responsible for maintaining the Pod and application status. Users should develop a new cooperation controller only when there is a new type of service or status around the Pod that needs to be maintained, such as integrating with a new traffic provider.")),(0,r.kt)("h3",{id:"operation-controller"},"Operation Controller"),(0,r.kt)("p",null,"The operation controller is responsible for Pod operations. The tasks that an operation controller needs to perform during PodOpsLifecycle include triggering a PodOpsLifecycle, checking whether the Pod has entered the Operating phase, performing Pod operations, and marking Pod operations as finished. These actions interacting with PodOpsLifecycle are provided in the package ",(0,r.kt)("inlineCode",{parentName:"p"},"kusionstack.io/operating/pkg/controllers/utils/podopslifecycle/utils.go"),"."),(0,r.kt)("p",null,"A simple operation controller reconcile method would look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n "sigs.k8s.io/controller-runtime/pkg/client"\n \n "kusionstack.io/operating/pkg/controllers/utils/podopslifecycle"\n)\n\nvar operationAdapter = &OperationOpsLifecycleAdapter{}\n\ntype OperationOpsLifecycleAdapter struct {\n}\n\n// GetID indicates ID of the PodOpsLifecycle\nfunc (a *OperationOpsLifecycleAdapter) GetID() string {\n return "new-id"\n}\n\n// GetType indicates type for this Operation Controller\nfunc (a *OperationOpsLifecycleAdapter) GetType() podopslifecycle.OperationType {\n return "new-type"\n}\n\n// AllowMultiType indicates whether multiple IDs which have the same Type are allowed\nfunc (a *OperationOpsLifecycleAdapter) AllowMultiType() bool {\n return true\n}\n\n// WhenBegin is a hook, which will be executed when begin a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenBegin(pod client.Object) (bool, error) {\n return false, nil\n}\n\n// WhenFinish is a hook, which will be executed when finish a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenFinish(pod client.Object) (bool, error) {\n return false, nil\n}\n\n......\nfunc (r *PodOperationReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n // check if the Pod needs operation\n if !r.needOperation(pod) {\n return reconcile.Result{}, nil\n }\n\n // if PodOpsLifecycle has not been triggered, trigger it\n if !podopslifecycle.IsDuringOps(OpsLifecycleAdapter, pod) {\n if updated, err := podopslifecycle.Begin(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n } else if updated {\n return reconcile.Result{}, nil\n }\n }\n\n // waiting until Pod enters operating phase\n if _, allowed := podopslifecycle.AllowOps(operationAdapter, 0, pod); !allowed {\n return reconcile.Result{}, nil\n }\n\n // do operation works\n if completed := r.doPodOperation(pod); !completed {\n return reconcile.Result{}, nil\n }\n\n // after operation works completed, finish operating phase to continue PodOpsLifecycle\n if _, err := podopslifecycle.Finish(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n }\n}\n')),(0,r.kt)("h3",{id:"pod-cooperation-controller"},"Pod Cooperation Controller"),(0,r.kt)("p",null,"There are two ways to develop a cooperation controller.\nOne way is to develop a controller using the controller runtime and adhering to some conventions of PodOpsLifecycle and Kubernetes.\nAnother way is to take the use of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist"},"ResourceConsist")," framework provided by KusionStack, which can be referenced from its ",(0,r.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/resourceconsist"},"documentation"),"."),(0,r.kt)("p",null,"The following outlines the first approach."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "k8s.io/apimachinery/pkg/api/errors"\n k8spod "k8s.io/kubernetes/pkg/api/v1/pod/util.go"\n "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n\n operatingapps "kusionstack.io/operating/apis/apps/v1alpha1"\n)\n\nconst (\n // Finalizer needs to have prefix: `prot.podopslifecycle.kusionstack.io`.\n // KusionStack Operating keeps this prefix back-compatible,\n // so that it can be hard code to decouple with KusionStack Operating.\n finalizerPrefix = operatingapps.PodOperationProtectionFinalizerPrefix\n\n protectionFinalizer = finalizerPrefix + "/" + "unique-id"\n)\n\n......\nfunc (r *PodResourceReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n if k8spod.IsPodReady(pod) {\n // do resource reconcile like add Pod IP to traffic route\n r.trafficOn(pod.status.PodIP)\n // It is important to add a unique finalizer on this Pod\n return reconcile.Result{}, r.addFinalizer(ctx, pod, protectionFinalizer)\n }\n\n if !k8spod.IsPodReady(pod) {\n // do resource reconcile like remove Pod IP from traffic route\n r.trafficOff(pod.status.PodIP)\n // It is important to remove the unique finalizer from this Pod\n return reconcile.Result{}, r.removeFinalizer(ctx, pod, protectionFinalizer)\n }\n}\n\nfunc (r *PodResourceReconciler) addFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.AddFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n\nfunc (r *PodResourceReconciler) removeFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if !controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.RemoveFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n')),(0,r.kt)("h2",{id:"key-features"},"Key Features"),(0,r.kt)("h3",{id:"concurrency-support"},"Concurrency Support"),(0,r.kt)("p",null,"PodOpsLifecycle in KusionStack Operating supports concurrency.\nIt means PodOpsLifecycle is able to organize and track multi controllers operating the same pod at the same time.\nFor example, when a controller is going to update Pod, other controllers are allowed to do other operations at the same time, like delete, restart, recreate it,\nalthough the result may not be meaningful."))}d.isMDXComponent=!0},57590:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-sequence-diagram-47bc9fbcab1c539cb11e8bc5f3987cf5.png"},79164:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-6ed0948e3faaf60bcd3ddb5c572038cf.png"}}]); \ No newline at end of file diff --git a/assets/js/4a6d5a33.749feba8.js b/assets/js/4a6d5a33.749feba8.js deleted file mode 100644 index 1f8e7e5a657..00000000000 --- a/assets/js/4a6d5a33.749feba8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5612],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return n?o.createElement(h,a(a({ref:t},p),{},{components:n})):o.createElement(h,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:2},a="PodOpsLifecycle",l={unversionedId:"operating/concepts/podopslifecycle",id:"version-v0.9/operating/concepts/podopslifecycle",title:"PodOpsLifecycle",description:"Background",source:"@site/versioned_docs/version-v0.9/operating/concepts/podopslifecycle.md",sourceDirName:"operating/concepts",slug:"/operating/concepts/podopslifecycle",permalink:"/docs/v0.9/operating/concepts/podopslifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/concepts/podopslifecycle.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/v0.9/operating/started/demo-graceful-operation"},next:{title:"CollaSet",permalink:"/docs/v0.9/operating/manuals/collaset"}},c={},s=[{value:"Background",id:"background",level:2},{value:"Introduction",id:"introduction",level:2},{value:"Developer's Guide",id:"developers-guide",level:2},{value:"Operation Controller",id:"operation-controller",level:3},{value:"Pod Cooperation Controller",id:"pod-cooperation-controller",level:3},{value:"Key Features",id:"key-features",level:2},{value:"Concurrency Support",id:"concurrency-support",level:3}],p={toc:s};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"podopslifecycle"},"PodOpsLifecycle"),(0,r.kt)("h2",{id:"background"},"Background"),(0,r.kt)("p",null,"Kubernetes provides a set of default controllers for workload management, such as StatefulSet, Deployment, and DaemonSet, which are responsible for Pod operations.\nMeanwhile, application users may also have some services outside the Kubernetes cluster that are closely related to the Pod Lifecycle, including traffic routing, service discovery, or alert monitoring.\nHowever, they face challenges in participating in the operational lifecycle of a Pod, even if they are connected to Kubernetes by developing a controller that watches the Pods."),(0,r.kt)("p",null,"PodOpsLifecycle aims to offer Kubernetes administrators and developers finer-grained control over the entire lifecycle of a Pod.\nIt enables developers to execute necessary actions before, during, and after specific phases of a Pod operation.\nFor instance, removing the Pod's IP from the traffic route before initiating the Pod operation, performing the actual Pod operations, and adding it back after the Pod operation is completed to achieve a smooth and graceful Pod operation, and prevent any traffic loss."),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"In PodOpsLifecycle, participants are classified into two roles: ",(0,r.kt)("inlineCode",{parentName:"p"},"operation controllers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"cooperation controllers"),"."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operation controllers")," are responsible for operating Pods, such as Deployments and StatefulSets from Kubernetes, and CollaSets from Operating which intend to scale, update, or recreate Pods."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Cooperation controllers")," are sensitive with Pod status. They handle resources or configurations around Pods, which may include traffic controller, alert monitoring controller, etc. These controllers typically reconcile Kubernetes resources around Pods with external services, such as sync Pod IPs with the LB provider, or maintaining Pods' metadata with application monitoring system.")),(0,r.kt)("p",null,"The two types of controllers do not need to be aware of each other. All controllers are organized by PodOpsLifecycle. Additionally, KusionStack Operating introduces extra phases around the native Kubernetes Pod Lifecycle: ServiceAvailable, Preparing, and Completing."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle",src:n(79164).Z,width:"1500",height:"978"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Completing"),": After a Pod is created or updated and becomes ready, Operating marks its PodOpsLifecycle as the ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing")," phase. During this phase, the Pod is in a ready condition, prompting cooperation controllers to perform actions such as registering the Pod IP in the traffic route. Once all cooperation controllers complete their tasks, Operating sets the PodOpsLifecycle to the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"ServiceAvailable"),": This phase indicates that the Pod is in a normal state and ready to serve. If everything goes smoothly, the Pod remains in the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase until the next operation."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Preparing"),": When an operation controller needs to operate the Pod, it triggers a new PodOpsLifecycle. The Pod then transitions from the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase to the ",(0,r.kt)("inlineCode",{parentName:"li"},"Preparing")," phase. During this phase, the Pod is initially marked as Unready by setting ReadinessGate to false. All cooperation controllers then begin preparing tasks, such as removing the Pod's IP from the traffic route. After completing these tasks, the Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operating"),": If a Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase, it is expected to accept any kind of operation without any damage, including recreation, scaling-in, upgrading, etc. Operation controllers are permitted to apply any changes to this Pod. Once all these operations are completed, the Pod advances to the next phase \u2014 ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing"),", and the PodOpsLifecycle continues.")),(0,r.kt)("p",null,"The PodOpsLifecycle detail and the relationship with Kubernetes native Pod Lifecycle is showed by following sequence diagram."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle-sequence-diagram",src:n(57590).Z,width:"1500",height:"694"})),(0,r.kt)("h2",{id:"developers-guide"},"Developer's Guide"),(0,r.kt)("p",null,"This section introduces how to develop operation controllers and cooperation controllers to interact with PodOpsLifecycle."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The operation controller is responsible for a set of Pod operation tasks. KusionStack Operating has already provided various types of operation controllers. Users only need to develop a new operation controller if a new kind of Pod operation needs to be added."),(0,r.kt)("li",{parentName:"ul"},"The cooperation controller participates in PodOpsLifecycle before and after operating on a Pod, such as the Traffic controller, alert monitoring controller, and other controllers responsible for maintaining the Pod and application status. Users should develop a new cooperation controller only when there is a new type of service or status around the Pod that needs to be maintained, such as integrating with a new traffic provider.")),(0,r.kt)("h3",{id:"operation-controller"},"Operation Controller"),(0,r.kt)("p",null,"The operation controller is responsible for Pod operations. The tasks that an operation controller needs to perform during PodOpsLifecycle include triggering a PodOpsLifecycle, checking whether the Pod has entered the Operating phase, performing Pod operations, and marking Pod operations as finished. These actions interacting with PodOpsLifecycle are provided in the package ",(0,r.kt)("inlineCode",{parentName:"p"},"kusionstack.io/operating/pkg/controllers/utils/podopslifecycle/utils.go"),"."),(0,r.kt)("p",null,"A simple operation controller reconcile method would look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n "sigs.k8s.io/controller-runtime/pkg/client"\n \n "kusionstack.io/operating/pkg/controllers/utils/podopslifecycle"\n)\n\nvar operationAdapter = &OperationOpsLifecycleAdapter{}\n\ntype OperationOpsLifecycleAdapter struct {\n}\n\n// GetID indicates ID of the PodOpsLifecycle\nfunc (a *OperationOpsLifecycleAdapter) GetID() string {\n return "new-id"\n}\n\n// GetType indicates type for this Operation Controller\nfunc (a *OperationOpsLifecycleAdapter) GetType() podopslifecycle.OperationType {\n return "new-type"\n}\n\n// AllowMultiType indicates whether multiple IDs which have the same Type are allowed\nfunc (a *OperationOpsLifecycleAdapter) AllowMultiType() bool {\n return true\n}\n\n// WhenBegin is a hook, which will be executed when begin a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenBegin(pod client.Object) (bool, error) {\n return false, nil\n}\n\n// WhenFinish is a hook, which will be executed when finish a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenFinish(pod client.Object) (bool, error) {\n return false, nil\n}\n\n......\nfunc (r *PodOperationReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n // check if the Pod needs operation\n if !r.needOperation(pod) {\n return reconcile.Result{}, nil\n }\n\n // if PodOpsLifecycle has not been triggered, trigger it\n if !podopslifecycle.IsDuringOps(OpsLifecycleAdapter, pod) {\n if updated, err := podopslifecycle.Begin(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n } else if updated {\n return reconcile.Result{}, nil\n }\n }\n\n // waiting until Pod enters operating phase\n if _, allowed := podopslifecycle.AllowOps(operationAdapter, 0, pod); !allowed {\n return reconcile.Result{}, nil\n }\n\n // do operation works\n if completed := r.doPodOperation(pod); !completed {\n return reconcile.Result{}, nil\n }\n\n // after operation works completed, finish operating phase to continue PodOpsLifecycle\n if _, err := podopslifecycle.Finish(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n }\n}\n')),(0,r.kt)("h3",{id:"pod-cooperation-controller"},"Pod Cooperation Controller"),(0,r.kt)("p",null,"There are two ways to develop a cooperation controller.\nOne way is to develop a controller using the controller runtime and adhering to some conventions of PodOpsLifecycle and Kubernetes.\nAnother way is to take the use of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist"},"ResourceConsist")," framework provided by KusionStack, which can be referenced from its ",(0,r.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/resourceconsist"},"documentation"),"."),(0,r.kt)("p",null,"The following outlines the first approach."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "k8s.io/apimachinery/pkg/api/errors"\n k8spod "k8s.io/kubernetes/pkg/api/v1/pod/util.go"\n "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n\n operatingapps "kusionstack.io/operating/apis/apps/v1alpha1"\n)\n\nconst (\n // Finalizer needs to have prefix: `prot.podopslifecycle.kusionstack.io`.\n // KusionStack Operating keeps this prefix back-compatible,\n // so that it can be hard code to decouple with KusionStack Operating.\n finalizerPrefix = operatingapps.PodOperationProtectionFinalizerPrefix\n\n protectionFinalizer = finalizerPrefix + "/" + "unique-id"\n)\n\n......\nfunc (r *PodResourceReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n if k8spod.IsPodReady(pod) {\n // do resource reconcile like add Pod IP to traffic route\n r.trafficOn(pod.status.PodIP)\n // It is important to add a unique finalizer on this Pod\n return reconcile.Result{}, r.addFinalizer(ctx, pod, protectionFinalizer)\n }\n\n if !k8spod.IsPodReady(pod) {\n // do resource reconcile like remove Pod IP from traffic route\n r.trafficOff(pod.status.PodIP)\n // It is important to remove the unique finalizer from this Pod\n return reconcile.Result{}, r.removeFinalizer(ctx, pod, protectionFinalizer)\n }\n}\n\nfunc (r *PodResourceReconciler) addFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.AddFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n\nfunc (r *PodResourceReconciler) removeFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if !controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.RemoveFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n')),(0,r.kt)("h2",{id:"key-features"},"Key Features"),(0,r.kt)("h3",{id:"concurrency-support"},"Concurrency Support"),(0,r.kt)("p",null,"PodOpsLifecycle in KusionStack Operating supports concurrency.\nIt means PodOpsLifecycle is able to organize and track multi controllers operating the same pod at the same time.\nFor example, when a controller is going to update Pod, other controllers are allowed to do other operations at the same time, like delete, restart, recreate it,\nalthough the result may not be meaningful."))}d.isMDXComponent=!0},57590:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-sequence-diagram-47bc9fbcab1c539cb11e8bc5f3987cf5.png"},79164:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-6ed0948e3faaf60bcd3ddb5c572038cf.png"}}]); \ No newline at end of file diff --git a/assets/js/4ac8e691.0fda8509.js b/assets/js/4ac8e691.0fda8509.js new file mode 100644 index 00000000000..e50109de6df --- /dev/null +++ b/assets/js/4ac8e691.0fda8509.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3677],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var m=a.createContext({}),p=function(t){var e=a.useContext(m),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},s=function(t){var e=p(t.components);return a.createElement(m.Provider,{value:e},t.children)},d={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(n),c=r,k=u["".concat(m,".").concat(c)]||u[c]||d[c]||l;return n?a.createElement(k,i(i({ref:e},s),{},{components:n})):a.createElement(k,i({ref:e},s))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var p=2;p{n.r(e),n.d(e,{assets:()=>m,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:1},i="Installation",o={unversionedId:"ctrlmesh/started/install",id:"ctrlmesh/started/install",title:"Installation",description:"Install with helm",source:"@site/docs/ctrlmesh/started/install.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/install",permalink:"/docs/next/ctrlmesh/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/started/install.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Concepts",permalink:"/docs/next/ctrlmesh/concepts/"},next:{title:"Try a Sample",permalink:"/docs/next/ctrlmesh/started/try"}},m={},p=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3}],s={toc:p};function d(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Upgrade to the latest version \n$ helm upgrade ctrlmesh kusionstack/ctrlmesh \n\n# Uninstall\n$ helm uninstall ctrlmesh\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for controller mesh installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"ctrlmesh"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.replicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of ctrlmesh-manager deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"2"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-manager"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"512Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-proxy image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-proxy"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-init image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-init"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-init"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"shardingGroupVersionKinds")),(0,r.kt)("td",{parentName:"tr",align:null},"Sharding resource lists\uff08yaml\uff09"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("p",null,"config ",(0,r.kt)("inlineCode",{parentName:"p"},"groupVersionKinds")," in file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"ctrlmesh.kusionstack.io/v1alpha1:\n- '*'\nv1:\n- Pod\n- PersistentVolumeClaim\n- Service\n- ConfigMap\n- Endpoint\napps/v1:\n- StatefulSet\n- ReplicaSet\n- ControllerRevision\n")),(0,r.kt)("p",null,"Specify each parameter using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--set key=value")," argument to ",(0,r.kt)("inlineCode",{parentName:"p"},"helm install")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4ac8e691.9bed4cad.js b/assets/js/4ac8e691.9bed4cad.js deleted file mode 100644 index 724991a8cf3..00000000000 --- a/assets/js/4ac8e691.9bed4cad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3677],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>c});var a=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function i(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var m=a.createContext({}),p=function(t){var e=a.useContext(m),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},s=function(t){var e=p(t.components);return a.createElement(m.Provider,{value:e},t.children)},d={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,r=t.mdxType,l=t.originalType,m=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(n),c=r,k=u["".concat(m,".").concat(c)]||u[c]||d[c]||l;return n?a.createElement(k,i(i({ref:e},s),{},{components:n})):a.createElement(k,i({ref:e},s))}));function c(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=n.length,i=new Array(l);i[0]=u;var o={};for(var m in e)hasOwnProperty.call(e,m)&&(o[m]=e[m]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var p=2;p{n.r(e),n.d(e,{assets:()=>m,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={sidebar_position:1},i="Installation",o={unversionedId:"ctrlmesh/started/install",id:"ctrlmesh/started/install",title:"Installation",description:"Install with helm",source:"@site/docs/ctrlmesh/started/install.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/install",permalink:"/docs/next/ctrlmesh/started/install",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/started/install.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Concepts",permalink:"/docs/next/ctrlmesh/concepts/"},next:{title:"Try a Sample",permalink:"/docs/next/ctrlmesh/started/try"}},m={},p=[{value:"Install with helm",id:"install-with-helm",level:2},{value:"Optional: chart parameters",id:"optional-chart-parameters",level:3}],s={toc:p};function d(t){let{components:e,...n}=t;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"installation"},"Installation"),(0,r.kt)("h2",{id:"install-with-helm"},"Install with helm"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# Firstly add charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Upgrade to the latest version \n$ helm upgrade ctrlmesh kusionstack/ctrlmesh \n\n# Uninstall\n$ helm uninstall ctrlmesh\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/helm/helm"},"Helm")," is a tool for managing packages of pre-configured Kubernetes resources."),(0,r.kt)("h3",{id:"optional-chart-parameters"},"Optional: chart parameters"),(0,r.kt)("p",null,"The following table lists the configurable parameters of the chart and their default values."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Default"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespace")),(0,r.kt)("td",{parentName:"tr",align:null},"namespace for controller mesh installation"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"ctrlmesh"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"namespaceEnabled")),(0,r.kt)("td",{parentName:"tr",align:null},"Whether to create the installation.namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"true"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.replicas")),(0,r.kt)("td",{parentName:"tr",align:null},"Replicas of ctrlmesh-manager deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"2"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-manager image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-manager"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-manager"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"500m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource limit of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"512Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"10m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"manager.resources.requests.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource request of ctrlmesh-manager container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"64Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-proxy image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-proxy"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.pullPolicy")),(0,r.kt)("td",{parentName:"tr",align:null},"Image pull policy for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IfNotPresent"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-proxy"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.cpu")),(0,r.kt)("td",{parentName:"tr",align:null},"CPU resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100m"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"proxy.resources.limits.memory")),(0,r.kt)("td",{parentName:"tr",align:null},"Memory resource requests of ctrlmesh-proxy container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"100Mi"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.repo")),(0,r.kt)("td",{parentName:"tr",align:null},"Repository for ctrlmesh-init image"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"kusionstack/ctrlmesh-init"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"init.image.tag")),(0,r.kt)("td",{parentName:"tr",align:null},"Tag for ctrlmesh-init"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"v0.1.0"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"shardingGroupVersionKinds")),(0,r.kt)("td",{parentName:"tr",align:null},"Sharding resource lists\uff08yaml\uff09"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("p",null,"config ",(0,r.kt)("inlineCode",{parentName:"p"},"groupVersionKinds")," in file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"ctrlmesh.kusionstack.io/v1alpha1:\n- '*'\nv1:\n- Pod\n- PersistentVolumeClaim\n- Service\n- ConfigMap\n- Endpoint\napps/v1:\n- StatefulSet\n- ReplicaSet\n- ControllerRevision\n")),(0,r.kt)("p",null,"Specify each parameter using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--set key=value")," argument to ",(0,r.kt)("inlineCode",{parentName:"p"},"helm install")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4b36b697.b28ddd16.js b/assets/js/4b36b697.141e98b4.js similarity index 64% rename from assets/js/4b36b697.b28ddd16.js rename to assets/js/4b36b697.141e98b4.js index 898d228695f..dd70da799f4 100644 --- a/assets/js/4b36b697.b28ddd16.js +++ b/assets/js/4b36b697.141e98b4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1130],{3905:(e,t,o)=>{o.d(t,{Zo:()=>l,kt:()=>f});var r=o(67294);function n(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var s=r.createContext({}),p=function(e){var t=r.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=p(o),f=n,v=d["".concat(s,".").concat(f)]||d[f]||u[f]||i;return o?r.createElement(v,a(a({ref:t},l),{},{components:o})):r.createElement(v,a({ref:t},l))}));function f(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=o.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:n,a[1]=c;for(var p=2;p{o.r(t),o.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=o(87462),n=(o(67294),o(3905));const i={sidebar_label:"Overview",id:"overview"},a="Overview",c={unversionedId:"kusion/concepts/project/overview",id:"kusion/concepts/project/overview",title:"Overview",description:"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications.",source:"@site/docs/kusion/3-concepts/1-project/1-overview.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/overview",permalink:"/docs/next/kusion/concepts/project/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/1-project/1-overview.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/next/kusion/getting-started/deliver-wordpress"},next:{title:"Project Configuration",permalink:"/docs/next/kusion/concepts/project/configuration"}},s={},p=[],l={toc:p};function u(e){let{components:t,...o}=e;return(0,n.kt)("wrapper",(0,r.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"overview"},"Overview"),(0,n.kt)("p",null,"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications."),(0,n.kt)("p",null,"The purpose of the project is to bundle application configurations and refer to a Git repository. Specifically, it organizes logical configurations for internal components to orchestrate the application and assembles these configurations to suit different roles, such as developers and SREs, thereby covering the entire life cycle of application development."),(0,n.kt)("p",null,"From the perspective of the application development life cycle, the configuration delineated by the project is decoupled from the application code. It takes an immutable image as input, allowing users to perform operations and maintain the application within an independent configuration codebase."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1130],{3905:(e,t,o)=>{o.d(t,{Zo:()=>l,kt:()=>f});var r=o(67294);function n(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var s=r.createContext({}),p=function(e){var t=r.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=p(o),f=n,v=d["".concat(s,".").concat(f)]||d[f]||u[f]||i;return o?r.createElement(v,a(a({ref:t},l),{},{components:o})):r.createElement(v,a({ref:t},l))}));function f(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=o.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:n,a[1]=c;for(var p=2;p{o.r(t),o.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=o(87462),n=(o(67294),o(3905));const i={sidebar_label:"Overview",id:"overview"},a="Overview",c={unversionedId:"kusion/concepts/project/overview",id:"kusion/concepts/project/overview",title:"Overview",description:"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications.",source:"@site/docs/kusion/3-concepts/1-project/1-overview.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/overview",permalink:"/docs/next/kusion/concepts/project/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/1-project/1-overview.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/next/kusion/getting-started/deliver-wordpress"},next:{title:"Project Configuration",permalink:"/docs/next/kusion/concepts/project/configuration"}},s={},p=[],l={toc:p};function u(e){let{components:t,...o}=e;return(0,n.kt)("wrapper",(0,r.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"overview"},"Overview"),(0,n.kt)("p",null,"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications."),(0,n.kt)("p",null,"The purpose of the project is to bundle application configurations and refer to a Git repository. Specifically, it organizes logical configurations for internal components to orchestrate the application and assembles these configurations to suit different roles, such as developers and SREs, thereby covering the entire life cycle of application development."),(0,n.kt)("p",null,"From the perspective of the application development life cycle, the configuration delineated by the project is decoupled from the application code. It takes an immutable image as input, allowing users to perform operations and maintain the application within an independent configuration codebase."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4c493feb.2493bdf2.js b/assets/js/4c493feb.2493bdf2.js new file mode 100644 index 00000000000..3fccc29df6a --- /dev/null +++ b/assets/js/4c493feb.2493bdf2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9666],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(t),m=i,k=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(k,o(o({ref:n},c),{},{components:t})):a.createElement(k,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=t(87462),i=(t(67294),t(3905));const r={},o="Configure Containers",l={unversionedId:"kusion/user-guides/working-with-k8s/container",id:"kusion/user-guides/working-with-k8s/container",title:"Configure Containers",description:"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/2-container.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/container",permalink:"/docs/next/kusion/user-guides/working-with-k8s/container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/2-container.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application",permalink:"/docs/next/kusion/user-guides/working-with-k8s/deploy-application"},next:{title:"Expose Service",permalink:"/docs/next/kusion/user-guides/working-with-k8s/service"}},s={},p=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Apply",id:"apply",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function d(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configure-containers"},"Configure Containers"),(0,i.kt)("p",null,"You can manage container-level configurations in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). By default, everything defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field will be treated as application containers. Sidecar containers will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the full ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,i.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the last guide, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/service"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,i.kt)("h2",{id:"apply"},"Apply"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new container configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the container (in the deployment template) now has the updated attributes as defined in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n - name: env1\n value: VALUE\n - name: env2\n value: VALUE2\n image: gcr.io/google-samples/gb-frontend:v4\n imagePullPolicy: IfNotPresent\n name: helloworld\n readinessProbe:\n failureThreshold: 3\n httpGet:\n host: localhost\n path: /\n port: 80\n scheme: HTTP\n initialDelaySeconds: 10\n periodSeconds: 10\n successThreshold: 1\n timeoutSeconds: 1\n resources:\n limits:\n cpu: 500m\n memory: 512M\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4c493feb.c1159b54.js b/assets/js/4c493feb.c1159b54.js deleted file mode 100644 index 26668350482..00000000000 --- a/assets/js/4c493feb.c1159b54.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9666],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(t),m=i,k=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(k,o(o({ref:n},c),{},{components:t})):a.createElement(k,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=t(87462),i=(t(67294),t(3905));const r={},o="Configure Containers",l={unversionedId:"kusion/user-guides/working-with-k8s/container",id:"kusion/user-guides/working-with-k8s/container",title:"Configure Containers",description:"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/2-container.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/container",permalink:"/docs/next/kusion/user-guides/working-with-k8s/container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/2-container.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application",permalink:"/docs/next/kusion/user-guides/working-with-k8s/deploy-application"},next:{title:"Expose Service",permalink:"/docs/next/kusion/user-guides/working-with-k8s/service"}},s={},p=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Apply",id:"apply",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function d(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configure-containers"},"Configure Containers"),(0,i.kt)("p",null,"You can manage container-level configurations in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). By default, everything defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field will be treated as application containers. Sidecar containers will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the full ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,i.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the last guide, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/service"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,i.kt)("h2",{id:"apply"},"Apply"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new container configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the container (in the deployment template) now has the updated attributes as defined in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n - name: env1\n value: VALUE\n - name: env2\n value: VALUE2\n image: gcr.io/google-samples/gb-frontend:v4\n imagePullPolicy: IfNotPresent\n name: helloworld\n readinessProbe:\n failureThreshold: 3\n httpGet:\n host: localhost\n path: /\n port: 80\n scheme: HTTP\n initialDelaySeconds: 10\n periodSeconds: 10\n successThreshold: 1\n timeoutSeconds: 1\n resources:\n limits:\n cpu: 500m\n memory: 512M\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4d1b877d.4f983a44.js b/assets/js/4d1b877d.4f983a44.js new file mode 100644 index 00000000000..cc62cf873aa --- /dev/null +++ b/assets/js/4d1b877d.4f983a44.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6176],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>h});var n=o(67294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function r(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var l=n.createContext({}),p=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var o=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(o),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||r;return o?n.createElement(m,a(a({ref:t},c),{},{components:o})):n.createElement(m,a({ref:t},c))}));function h(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=o.length,a=new Array(r);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var n=o(87462),i=(o(67294),o(3905));const r={sidebar_position:1,sidebar_label:"Overview",title:"Overview",slug:"/"},a="Introduction to Kusion",s={unversionedId:"kusion/intro/overview",id:"version-v0.9/kusion/intro/overview",title:"Overview",description:"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.",source:"@site/versioned_docs/version-v0.9/kusion/intro/overview.md",sourceDirName:"kusion/intro",slug:"/",permalink:"/docs/v0.9/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/intro/overview.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1,sidebar_label:"Overview",title:"Overview",slug:"/"},sidebar:"kusion",next:{title:"Kusion vs. Other Software",permalink:"/docs/v0.9/kusion/intro/kusion-vs-x"}},l={},p=[{value:"What is Kusion?",id:"what-is-kusion",level:2},{value:"Why Kusion?",id:"why-kusion",level:2},{value:"Kusion Highlights",id:"kusion-highlights",level:2}],c={toc:p};function u(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"introduction-to-kusion"},"Introduction to Kusion"),(0,i.kt)("p",null,"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the ",(0,i.kt)("a",{parentName:"p",href:"kusion/getting-started/install-kusion"},"Getting Started")," section."),(0,i.kt)("h2",{id:"what-is-kusion"},"What is Kusion?"),(0,i.kt)("p",null,"Kusion is a modern application delivery and management toolchain that enables developers to specify desired intent in a declarative way and then using a consistent workflow to drive continuous deployment through application lifecycle. Inspired by the phrase ",(0,i.kt)("strong",{parentName:"p"},"Fusion on Kubernetes"),", Kusion aims to help application and platform developers to develop and deliver in a self-serviceable, fast, reliable, and collaborative way."),(0,i.kt)("p",null,(0,i.kt)("img",{src:o(90647).Z,width:"1906",height:"742"})),(0,i.kt)("h2",{id:"why-kusion"},"Why Kusion?"),(0,i.kt)("p",null,"Developers should be able to deploy and run their applications and services end to end. ",(0,i.kt)("strong",{parentName:"p"},'"You build it, you run it", the original promise of DevOps.')),(0,i.kt)("p",null,"But the modern day for most software organizations this promise quickly become unrelalistic since the increasingly complex cloud-native toolchains, while cloud native technologies made huge improvements in areas such as scalability, availability and operability, it also brings downside - the growing burden on developers, which leads to the rise of ",(0,i.kt)("a",{parentName:"p",href:"https://platformengineering.org/"},"Platform Engineering"),"."),(0,i.kt)("p",null,"Another challenge we saw is that a series of ",(0,i.kt)("a",{parentName:"p",href:"https://web.devopstopologies.com/#anti-types"},"antipatterns")," emerge when regular software organizations tries to implement true DevOps. Without well proven reference architecture and supporting tools, it's much more difficult to accomplish the original promise."),(0,i.kt)("p",null,"On one hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion was build to minimize developer's cognitive load"),". With application-centric configuration model, you don't need to deal with tedious infrastructure and configuration management tooling, all you need to be familiar with is ",(0,i.kt)("a",{parentName:"p",href:"kusion/config-walkthrough/overview"},"AppConfigation"),". This approach shields developers from the configurational complexity of Kubernetes but still enable standardization by design."),(0,i.kt)("p",null,"On the other hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion defines a new way of how different engineering teams collaboration"),". With the separation of concerns, different roles could focus on their work based on their knowledge and responsibility. Through such a division of labor, the platform team can better manage the differences and complexities of the platform, and app developers could participate in ops work with less cognitive load."),(0,i.kt)("h2",{id:"kusion-highlights"},"Kusion Highlights"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Platform as Code")),(0,i.kt)("p",{parentName:"li"},"Specify desired application intent through declarative configuration code, drive continuous deployment with any CI/CD systems or GitOps to match that intent. No ad-hoc scripts, no hard maintain custom workflows, just declarative configuration code.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Dynamic Configuration Management")),(0,i.kt)("p",{parentName:"li"},"Enable platform teams to set baseline-templates, control how and where to deploy application workloads and provision accessory resources. While still enabling application developers freedom via workload-centric specification and deployment. ")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Security & Compliance Built In")),(0,i.kt)("p",{parentName:"li"},"Enforce security and infrastructure best practices with out-of-box ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"base models"),", create security and compliance guardrails for any Kusion deploy with third-party Policy as Code tools. All accessory resource secrets are automatically injected into Workloads.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Lightweight and Open Model Ecosystem")),(0,i.kt)("p",{parentName:"li"},"Pure client-side solution ensures good portability and the rich APIs make it easier to integrate and automate. Large growing model ecosystem covers all stages in application lifecycle, with extensive connections to various infrastructure capabilities. "))),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"Kusion is an early project.")," The end goal of Kusion is to boost ",(0,i.kt)("a",{parentName:"p",href:"https://internaldeveloperplatform.org/"},"Internal Developer Platform")," revolution and we are iterating on Kusion quickly to strive towards this goal. For any help or feedback, please contract us in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/community/discussions/categories/meeting"},"Slack")," or ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"issues"),".")))}u.isMDXComponent=!0},90647:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-b78c8632647fb8e4ed182914fe67185e.png"}}]); \ No newline at end of file diff --git a/assets/js/4d1b877d.bf2731fe.js b/assets/js/4d1b877d.bf2731fe.js deleted file mode 100644 index 6ef82db0f5d..00000000000 --- a/assets/js/4d1b877d.bf2731fe.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6176],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>h});var n=o(67294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function r(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var l=n.createContext({}),p=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var o=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(o),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||r;return o?n.createElement(m,a(a({ref:t},c),{},{components:o})):n.createElement(m,a({ref:t},c))}));function h(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=o.length,a=new Array(r);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var n=o(87462),i=(o(67294),o(3905));const r={sidebar_position:1,sidebar_label:"Overview",title:"Overview",slug:"/"},a="Introduction to Kusion",s={unversionedId:"kusion/intro/overview",id:"version-v0.9/kusion/intro/overview",title:"Overview",description:"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.",source:"@site/versioned_docs/version-v0.9/kusion/intro/overview.md",sourceDirName:"kusion/intro",slug:"/",permalink:"/docs/v0.9/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/intro/overview.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1,sidebar_label:"Overview",title:"Overview",slug:"/"},sidebar:"kusion",next:{title:"Kusion vs. Other Software",permalink:"/docs/v0.9/kusion/intro/kusion-vs-x"}},l={},p=[{value:"What is Kusion?",id:"what-is-kusion",level:2},{value:"Why Kusion?",id:"why-kusion",level:2},{value:"Kusion Highlights",id:"kusion-highlights",level:2}],c={toc:p};function u(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"introduction-to-kusion"},"Introduction to Kusion"),(0,i.kt)("p",null,"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the ",(0,i.kt)("a",{parentName:"p",href:"kusion/getting-started/install-kusion"},"Getting Started")," section."),(0,i.kt)("h2",{id:"what-is-kusion"},"What is Kusion?"),(0,i.kt)("p",null,"Kusion is a modern application delivery and management toolchain that enables developers to specify desired intent in a declarative way and then using a consistent workflow to drive continuous deployment through application lifecycle. Inspired by the phrase ",(0,i.kt)("strong",{parentName:"p"},"Fusion on Kubernetes"),", Kusion aims to help application and platform developers to develop and deliver in a self-serviceable, fast, reliable, and collaborative way."),(0,i.kt)("p",null,(0,i.kt)("img",{src:o(90647).Z,width:"1906",height:"742"})),(0,i.kt)("h2",{id:"why-kusion"},"Why Kusion?"),(0,i.kt)("p",null,"Developers should be able to deploy and run their applications and services end to end. ",(0,i.kt)("strong",{parentName:"p"},'"You build it, you run it", the original promise of DevOps.')),(0,i.kt)("p",null,"But the modern day for most software organizations this promise quickly become unrelalistic since the increasingly complex cloud-native toolchains, while cloud native technologies made huge improvements in areas such as scalability, availability and operability, it also brings downside - the growing burden on developers, which leads to the rise of ",(0,i.kt)("a",{parentName:"p",href:"https://platformengineering.org/"},"Platform Engineering"),"."),(0,i.kt)("p",null,"Another challenge we saw is that a series of ",(0,i.kt)("a",{parentName:"p",href:"https://web.devopstopologies.com/#anti-types"},"antipatterns")," emerge when regular software organizations tries to implement true DevOps. Without well proven reference architecture and supporting tools, it's much more difficult to accomplish the original promise."),(0,i.kt)("p",null,"On one hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion was build to minimize developer's cognitive load"),". With application-centric configuration model, you don't need to deal with tedious infrastructure and configuration management tooling, all you need to be familiar with is ",(0,i.kt)("a",{parentName:"p",href:"kusion/config-walkthrough/overview"},"AppConfigation"),". This approach shields developers from the configurational complexity of Kubernetes but still enable standardization by design."),(0,i.kt)("p",null,"On the other hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion defines a new way of how different engineering teams collaboration"),". With the separation of concerns, different roles could focus on their work based on their knowledge and responsibility. Through such a division of labor, the platform team can better manage the differences and complexities of the platform, and app developers could participate in ops work with less cognitive load."),(0,i.kt)("h2",{id:"kusion-highlights"},"Kusion Highlights"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Platform as Code")),(0,i.kt)("p",{parentName:"li"},"Specify desired application intent through declarative configuration code, drive continuous deployment with any CI/CD systems or GitOps to match that intent. No ad-hoc scripts, no hard maintain custom workflows, just declarative configuration code.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Dynamic Configuration Management")),(0,i.kt)("p",{parentName:"li"},"Enable platform teams to set baseline-templates, control how and where to deploy application workloads and provision accessory resources. While still enabling application developers freedom via workload-centric specification and deployment. ")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Security & Compliance Built In")),(0,i.kt)("p",{parentName:"li"},"Enforce security and infrastructure best practices with out-of-box ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"base models"),", create security and compliance guardrails for any Kusion deploy with third-party Policy as Code tools. All accessory resource secrets are automatically injected into Workloads.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Lightweight and Open Model Ecosystem")),(0,i.kt)("p",{parentName:"li"},"Pure client-side solution ensures good portability and the rich APIs make it easier to integrate and automate. Large growing model ecosystem covers all stages in application lifecycle, with extensive connections to various infrastructure capabilities. "))),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"Kusion is an early project.")," The end goal of Kusion is to boost ",(0,i.kt)("a",{parentName:"p",href:"https://internaldeveloperplatform.org/"},"Internal Developer Platform")," revolution and we are iterating on Kusion quickly to strive towards this goal. For any help or feedback, please contract us in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/community/discussions/categories/meeting"},"Slack")," or ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"issues"),".")))}u.isMDXComponent=!0},90647:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-b78c8632647fb8e4ed182914fe67185e.png"}}]); \ No newline at end of file diff --git a/assets/js/4df25393.3cb01d89.js b/assets/js/4df25393.3cb01d89.js new file mode 100644 index 00000000000..ce3c010d071 --- /dev/null +++ b/assets/js/4df25393.3cb01d89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1690],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),c=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,h=m["".concat(i,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(h,l(l({ref:t},p),{},{components:n})):r.createElement(h,l({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},l="Concepts",s={unversionedId:"ctrlmesh/concepts/concepts",id:"version-v0.10/ctrlmesh/concepts/concepts",title:"Concepts",description:"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.",source:"@site/versioned_docs/version-v0.10/ctrlmesh/concepts/concepts.md",sourceDirName:"ctrlmesh/concepts",slug:"/ctrlmesh/concepts/",permalink:"/docs/ctrlmesh/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/concepts/concepts.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",previous:{title:"Controller Mesh",permalink:"/docs/ctrlmesh/intro/"},next:{title:"Installation",permalink:"/docs/ctrlmesh/started/install"}},i={},c=[],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"concepts"},"Concepts"),(0,o.kt)("p",null,"Generally, a ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy")," container will be injected into each operator Pod that has configured in ShardingConfigs.\nThis proxy container will intercept and handle the connection by between API/Oth Server and controllers/webhooks in the Pod."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"550",src:n(61527).Z})),(0,o.kt)("p",null,"ApiServer proxy method:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"iptables nat"),": "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"fake kubeconfig"),": ")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-manager")," dispatches rules to the proxies, so that they can route requests according to the rules."),(0,o.kt)("p",null,"A core CRD of ControllerMesh is ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),". It contains all rules for user's controller:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-demo\n namespace: operator-demo\nspec:\n controller:\n leaderElectionName: operator-leader\n webhook:\n certDir: /tmp/webhook-certs\n port: 9443\n limits:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - pods\n - services\n selector:\n matchExpressions:\n - key: ctrlmesh.kusionstack.io/namespace\n operator: In\n values:\n - ns-a\n - ns-b\n matchLabels:\n app: foo\n selector:\n matchExpressions:\n - key: statefulset.kubernetes.io/pod-name\n operator: In\n values:\n - operator-demo-0\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"selector: for all pods under a shard. It can be a subset of pods under a StatefulSet."),(0,o.kt)("li",{parentName:"ul"},"controller: configuration for controller, including leader election name"),(0,o.kt)("li",{parentName:"ul"},"webhook: configuration for webhook, including certDir and port of this webhook"),(0,o.kt)("li",{parentName:"ul"},"limits: shard isolation is achieved through a set of ",(0,o.kt)("inlineCode",{parentName:"li"},"ObjectSelector"),".")),(0,o.kt)("p",null,"When ",(0,o.kt)("inlineCode",{parentName:"p"},"manager")," is first launched, shard labels will be added to all configured resources."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/sharding-hash"),": the hash value calculated based on the namespace ranges from 0 to 31."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/namespace"),": the namespace referring to this resource."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/control"),": under ctrlmesh-manager control.")),(0,o.kt)("p",null,"In this repo, we only support ",(0,o.kt)("inlineCode",{parentName:"p"},"ObjectSelector")," type of flow control,\nwhich means the ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy "),"will proxy http/s requests to the ApiServer,\nand inject a ",(0,o.kt)("inlineCode",{parentName:"p"},"LabelSelector")," into the request param for the requested resource type."),(0,o.kt)("p",null,"Router:"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"600",src:n(28234).Z})))}u.isMDXComponent=!0},61527:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/fake-configmap-532e288cad1389abce66dcd4b67cd817.png"},28234:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/mesh-proxy-4103e0c9a907b1df91258341cd841c52.png"}}]); \ No newline at end of file diff --git a/assets/js/4df25393.dd212270.js b/assets/js/4df25393.dd212270.js deleted file mode 100644 index 3979b6572e9..00000000000 --- a/assets/js/4df25393.dd212270.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1690],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),c=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,h=m["".concat(i,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(h,l(l({ref:t},p),{},{components:n})):r.createElement(h,l({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},l="Concepts",s={unversionedId:"ctrlmesh/concepts/concepts",id:"version-v0.10/ctrlmesh/concepts/concepts",title:"Concepts",description:"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.",source:"@site/versioned_docs/version-v0.10/ctrlmesh/concepts/concepts.md",sourceDirName:"ctrlmesh/concepts",slug:"/ctrlmesh/concepts/",permalink:"/docs/ctrlmesh/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/concepts/concepts.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",previous:{title:"Controller Mesh",permalink:"/docs/ctrlmesh/intro/"},next:{title:"Installation",permalink:"/docs/ctrlmesh/started/install"}},i={},c=[],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"concepts"},"Concepts"),(0,o.kt)("p",null,"Generally, a ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy")," container will be injected into each operator Pod that has configured in ShardingConfigs.\nThis proxy container will intercept and handle the connection by between API/Oth Server and controllers/webhooks in the Pod."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"550",src:n(61527).Z})),(0,o.kt)("p",null,"ApiServer proxy method:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"iptables nat"),": "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"fake kubeconfig"),": ")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-manager")," dispatches rules to the proxies, so that they can route requests according to the rules."),(0,o.kt)("p",null,"A core CRD of ControllerMesh is ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),". It contains all rules for user's controller:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-demo\n namespace: operator-demo\nspec:\n controller:\n leaderElectionName: operator-leader\n webhook:\n certDir: /tmp/webhook-certs\n port: 9443\n limits:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - pods\n - services\n selector:\n matchExpressions:\n - key: ctrlmesh.kusionstack.io/namespace\n operator: In\n values:\n - ns-a\n - ns-b\n matchLabels:\n app: foo\n selector:\n matchExpressions:\n - key: statefulset.kubernetes.io/pod-name\n operator: In\n values:\n - operator-demo-0\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"selector: for all pods under a shard. It can be a subset of pods under a StatefulSet."),(0,o.kt)("li",{parentName:"ul"},"controller: configuration for controller, including leader election name"),(0,o.kt)("li",{parentName:"ul"},"webhook: configuration for webhook, including certDir and port of this webhook"),(0,o.kt)("li",{parentName:"ul"},"limits: shard isolation is achieved through a set of ",(0,o.kt)("inlineCode",{parentName:"li"},"ObjectSelector"),".")),(0,o.kt)("p",null,"When ",(0,o.kt)("inlineCode",{parentName:"p"},"manager")," is first launched, shard labels will be added to all configured resources."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/sharding-hash"),": the hash value calculated based on the namespace ranges from 0 to 31."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/namespace"),": the namespace referring to this resource."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/control"),": under ctrlmesh-manager control.")),(0,o.kt)("p",null,"In this repo, we only support ",(0,o.kt)("inlineCode",{parentName:"p"},"ObjectSelector")," type of flow control,\nwhich means the ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy "),"will proxy http/s requests to the ApiServer,\nand inject a ",(0,o.kt)("inlineCode",{parentName:"p"},"LabelSelector")," into the request param for the requested resource type."),(0,o.kt)("p",null,"Router:"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"600",src:n(28234).Z})))}u.isMDXComponent=!0},61527:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/fake-configmap-532e288cad1389abce66dcd4b67cd817.png"},28234:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/mesh-proxy-4103e0c9a907b1df91258341cd841c52.png"}}]); \ No newline at end of file diff --git a/assets/js/4e363eb9.4b344b64.js b/assets/js/4e363eb9.4909794c.js similarity index 57% rename from assets/js/4e363eb9.4b344b64.js rename to assets/js/4e363eb9.4909794c.js index 49a718cf251..52ed7efcf10 100644 --- a/assets/js/4e363eb9.4b344b64.js +++ b/assets/js/4e363eb9.4909794c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4588],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>k});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(n),k=o,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function k(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace delete",i={unversionedId:"kusion/reference/commands/kusion-workspace-delete",id:"kusion/reference/commands/kusion-workspace-delete",title:"kusion workspace delete",description:"Delete a workspace",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-delete.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-delete",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-delete",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-delete.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace create",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-create"},next:{title:"kusion workspace list",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-list"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-delete"},"kusion workspace delete"),(0,o.kt)("p",null,"Delete a workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command deletes a specified workspace."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace delete\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete a workspace\n kusion workspace delete dev\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for delete\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4588],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>k});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(n),k=o,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function k(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace delete",i={unversionedId:"kusion/reference/commands/kusion-workspace-delete",id:"kusion/reference/commands/kusion-workspace-delete",title:"kusion workspace delete",description:"Delete a workspace",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-delete.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-delete",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-delete",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-delete.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace create",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-create"},next:{title:"kusion workspace list",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-list"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-delete"},"kusion workspace delete"),(0,o.kt)("p",null,"Delete a workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command deletes a specified workspace."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace delete\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete a workspace\n kusion workspace delete dev\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for delete\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/50dd26bc.407076be.js b/assets/js/50dd26bc.407076be.js new file mode 100644 index 00000000000..7320476a854 --- /dev/null +++ b/assets/js/50dd26bc.407076be.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8625],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var i=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=i.createContext({}),s=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=s(e.components);return i.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},u=i.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=s(t),m=a,g=u["".concat(l,".").concat(m)]||u[m]||d[m]||r;return t?i.createElement(g,o(o({ref:n},c),{},{components:t})):i.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,o=new Array(r);o[0]=u;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>p,toc:()=>s});var i=t(87462),a=(t(67294),t(3905));const r={},o="Upgrade Image",p={unversionedId:"kusion/user-guides/working-with-k8s/image-upgrade",id:"kusion/user-guides/working-with-k8s/image-upgrade",title:"Upgrade Image",description:"You can declare the application's container image via image field of the Container schema.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/image-upgrade",permalink:"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Service",permalink:"/docs/next/kusion/user-guides/working-with-k8s/service"},next:{title:"Configure Resource Specification",permalink:"/docs/next/kusion/user-guides/working-with-k8s/resource-spec"}},l={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"upgrade-image"},"Upgrade Image"),(0,a.kt)("p",null,"You can declare the application's container image via ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," field of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"For the full ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,a.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,a.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,a.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,a.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,a.kt)("h2",{id:"example"},"Example"),(0,a.kt)("p",null,"Update the image value in ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.nginx: {\n ...\n # before: \n # image = "gcr.io/google-samples/gb-frontend:v4"\n # after: \n image = "gcr.io/google-samples/gb-frontend:v5"\n ...\n }\n}\n')),(0,a.kt)("p",null,"Everything else in ",(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Re-run steps in ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", update image is completed."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,a.kt)("h2",{id:"validation"},"Validation"),(0,a.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated image (v5) as defined in the container configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/50dd26bc.b1ec5a82.js b/assets/js/50dd26bc.b1ec5a82.js deleted file mode 100644 index d04b5fbe716..00000000000 --- a/assets/js/50dd26bc.b1ec5a82.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8625],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var i=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=i.createContext({}),s=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=s(e.components);return i.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},u=i.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=s(t),m=a,g=u["".concat(l,".").concat(m)]||u[m]||d[m]||r;return t?i.createElement(g,o(o({ref:n},c),{},{components:t})):i.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,o=new Array(r);o[0]=u;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>p,toc:()=>s});var i=t(87462),a=(t(67294),t(3905));const r={},o="Upgrade Image",p={unversionedId:"kusion/user-guides/working-with-k8s/image-upgrade",id:"kusion/user-guides/working-with-k8s/image-upgrade",title:"Upgrade Image",description:"You can declare the application's container image via image field of the Container schema.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/image-upgrade",permalink:"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Service",permalink:"/docs/next/kusion/user-guides/working-with-k8s/service"},next:{title:"Configure Resource Specification",permalink:"/docs/next/kusion/user-guides/working-with-k8s/resource-spec"}},l={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"upgrade-image"},"Upgrade Image"),(0,a.kt)("p",null,"You can declare the application's container image via ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," field of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"For the full ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,a.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,a.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,a.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,a.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,a.kt)("h2",{id:"example"},"Example"),(0,a.kt)("p",null,"Update the image value in ",(0,a.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.nginx: {\n ...\n # before: \n # image = "gcr.io/google-samples/gb-frontend:v4"\n # after: \n image = "gcr.io/google-samples/gb-frontend:v5"\n ...\n }\n}\n')),(0,a.kt)("p",null,"Everything else in ",(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Re-run steps in ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", update image is completed."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,a.kt)("h2",{id:"validation"},"Validation"),(0,a.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated image (v5) as defined in the container configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5114ba79.e6452f9d.js b/assets/js/5114ba79.48a06846.js similarity index 60% rename from assets/js/5114ba79.e6452f9d.js rename to assets/js/5114ba79.48a06846.js index 106d32a5313..ad31c1b2c0f 100644 --- a/assets/js/5114ba79.e6452f9d.js +++ b/assets/js/5114ba79.48a06846.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4539],{3905:(e,t,o)=>{o.d(t,{Zo:()=>l,kt:()=>f});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var s=n.createContext({}),u=function(e){var t=n.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),m=u(o),f=r,d=m["".concat(s,".").concat(f)]||m[f]||p[f]||i;return o?n.createElement(d,a(a({ref:t},l),{},{components:o})):n.createElement(d,a({ref:t},l))}));function f(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:r,a[1]=c;for(var u=2;u{o.r(t),o.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=o(87462),r=(o(67294),o(3905));const i={sidebar_position:1},a="Community",c={unversionedId:"community/intro/intro",id:"community/intro/intro",title:"Community",description:"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.",source:"@site/docs/community/intro/intro.md",sourceDirName:"community/intro",slug:"/community/intro/",permalink:"/docs/next/community/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/community/intro/intro.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"community"},s={},u=[],l={toc:u};function p(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"community"},"Community"),(0,r.kt)("p",null,"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/orgs/KusionStack/discussions"},"Open a New Discussion on GitHub")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://app.slack.com/client/T03H6QE4VL0/setup-welcome"},"Contact Us on Slack"))),(0,r.kt)("h1",{id:"contributing"},"CONTRIBUTING"),(0,r.kt)("p",null,"We appreciate contributions from the community! To submit changes, please refer to the contributing file in the corresponding KusionStack repository. The files are available at the following links:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion/blob/main/docs/contributing.md"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/operating/blob/main/docs/contributing.md"},"Operating"))),(0,r.kt)("h1",{id:"code-of-conduct"},"CODE OF CONDUCT"),(0,r.kt)("p",null,"To make KusionStack a welcoming and harassment-free experience for everyone, we follow the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/CODE_OF_CONDUCT.md"},"KusionStack Code of Conduct"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4539],{3905:(e,t,o)=>{o.d(t,{Zo:()=>l,kt:()=>f});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var s=n.createContext({}),u=function(e){var t=n.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),m=u(o),f=r,d=m["".concat(s,".").concat(f)]||m[f]||p[f]||i;return o?n.createElement(d,a(a({ref:t},l),{},{components:o})):n.createElement(d,a({ref:t},l))}));function f(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:r,a[1]=c;for(var u=2;u{o.r(t),o.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=o(87462),r=(o(67294),o(3905));const i={sidebar_position:1},a="Community",c={unversionedId:"community/intro/intro",id:"community/intro/intro",title:"Community",description:"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.",source:"@site/docs/community/intro/intro.md",sourceDirName:"community/intro",slug:"/community/intro/",permalink:"/docs/next/community/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/community/intro/intro.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"community"},s={},u=[],l={toc:u};function p(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"community"},"Community"),(0,r.kt)("p",null,"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/orgs/KusionStack/discussions"},"Open a New Discussion on GitHub")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://app.slack.com/client/T03H6QE4VL0/setup-welcome"},"Contact Us on Slack"))),(0,r.kt)("h1",{id:"contributing"},"CONTRIBUTING"),(0,r.kt)("p",null,"We appreciate contributions from the community! To submit changes, please refer to the contributing file in the corresponding KusionStack repository. The files are available at the following links:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion/blob/main/docs/contributing.md"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/operating/blob/main/docs/contributing.md"},"Operating"))),(0,r.kt)("h1",{id:"code-of-conduct"},"CODE OF CONDUCT"),(0,r.kt)("p",null,"To make KusionStack a welcoming and harassment-free experience for everyone, we follow the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/CODE_OF_CONDUCT.md"},"KusionStack Code of Conduct"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5276ed9c.c5d1e5be.js b/assets/js/5276ed9c.c5d1e5be.js deleted file mode 100644 index 0ed6c4af799..00000000000 --- a/assets/js/5276ed9c.c5d1e5be.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1567],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return n?a.createElement(k,i(i({ref:t},d),{},{components:n})):a.createElement(k,i({ref:t},d))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=n(87462),o=(n(67294),n(3905));const r={id:"deliver-wordpress"},i="Deliver the WordPress Application on Kubernetes",l={unversionedId:"kusion/getting-started/deliver-wordpress",id:"version-v0.10/kusion/getting-started/deliver-wordpress",title:"Deliver the WordPress Application on Kubernetes",description:"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.",source:"@site/versioned_docs/version-v0.10/kusion/2-getting-started/2-deliver-wordpress.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/deliver-wordpress",permalink:"/docs/kusion/getting-started/deliver-wordpress",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/2-getting-started/2-deliver-wordpress.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"deliver-wordpress"},sidebar:"kusion",previous:{title:"Install Kusion",permalink:"/docs/kusion/getting-started/install-kusion"},next:{title:"Overview",permalink:"/docs/kusion/concepts/project/overview"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"deliver-the-wordpress-application-on-kubernetes"},"Deliver the WordPress Application on Kubernetes"),(0,o.kt)("p",null,"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion. "),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Before we start to play with this example, we need to have the Kusion CLI installed and run a Kubernetes cluster. Here are some helpful documentations: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/getting-started/install-kusion"},"Kusion")," CLI"),(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," CLI and run a ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," cluster. Some light and convenient options for local deployment include ",(0,o.kt)("a",{parentName:"li",href:"https://docs.k3s.io/quick-start"},"k3s"),", ",(0,o.kt)("a",{parentName:"li",href:"https://k3d.io/v5.4.4/#installation"},"k3d"),", and ",(0,o.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"MiniKube"),". ")),(0,o.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,o.kt)("p",null,"To deploy the WordPress application, we need to first initiate a ",(0,o.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (we are using ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," here). Please copy the following example YAML file to your local ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# example workspace configs for local mysql database\nruntimes: \n kubernetes: \n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n\nmodules: \n mysql: \n default: \n suffix: "-mysql" # The suffix of the MySQL database name\n')),(0,o.kt)("p",null,"You can replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," and execute the following command line to initiate the workspace configuration for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,o.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,o.kt)("inlineCode",{parentName:"p"},"Kubernetes")," runtime config and ",(0,o.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,o.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,o.kt)("h2",{id:"init-project"},"Init Project"),(0,o.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,o.kt)("p",null,"All init templates are listed as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-local-db A sample wordpress project with local database\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-local-db\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-local-db'\n")),(0,o.kt)("p",null,"Please select ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db")," and press ",(0,o.kt)("inlineCode",{parentName:"p"},"Enter"),", after which we will see the hints below and use the default values to configure this project and stack. "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(63617).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"The directory structure looks like the following: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-local-db/dev && tree\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-local-db/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,o.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/project/overview"},"Project")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/stack/overview"},"Stack"),". ")),(0,o.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,o.kt)("p",null,"Now let's have a glance at the configuration file of ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),": "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stack.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n')),(0,o.kt)("p",null,"The configuration file ",(0,o.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,o.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,o.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a local ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,o.kt)("inlineCode",{parentName:"p"},"8.0")," for the application. The necessary Kubernetes resources for deploying and using the local database will be generated, and users can get the ",(0,o.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"paasword")," of the database through the ",(0,o.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,o.kt)("p",null,"This model hides the major complexity of Kubernetes resources such as ",(0,o.kt)("inlineCode",{parentName:"p"},"Namespace"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),", providing the concepts that are application-centric and infrastructure-agnostic. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the Models can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,o.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,o.kt)("p",null,"We will deliver the WordPress application in the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db/dev")," folder into the Kubernetes cluster with one command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion apply --watch"),". "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(41809).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"Check ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," status. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n wordpress-local-db get deployment\n")),(0,o.kt)("p",null,"The expected output is shown as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl -n wordpress-local-db get deployment\nNAME READY UP-TO-DATE AVAILABLE AGE\nwordpress-local-db-dev-wordpress 1/1 1 1 2m56s\nwordpress-mysql 1/1 1 1 2m56s\n")),(0,o.kt)("p",null,"In the above two resources, ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db-dev-wordpress")," corresponds to the Kubernetes ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the WordPress application, while ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-mysql")," corresponds to the ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the local MySQL database. "),(0,o.kt)("p",null,"Port-forward our WordPress with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\nForwarding from 127.0.0.1:12345 -> 80\nForwarding from [::1]:12345 -> 80\n\n")),(0,o.kt)("p",null,"Now we can visit ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:12345"},"http://localhost:12345")," in our browser and enjoy!"),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(85773).Z,width:"1500",height:"803"})),(0,o.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,o.kt)("p",null,"We can delete the WordPress application and related database resources using the following command line: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(21192).Z,width:"2560",height:"1440"})))}c.isMDXComponent=!0},41809:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/apply-wordpress-local-db-6a391cbf9576c88494710eb17f8c8396.gif"},21192:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/destroy-wordpress-local-db-93038beed84dadd31cbefdbbfb632ee1.gif"},63617:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/init-wordpress-local-db-34d0778e8b48028ad7a1394543a1dfb2.gif"},85773:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/5276ed9c.eefa78c9.js b/assets/js/5276ed9c.eefa78c9.js new file mode 100644 index 00000000000..2aeab85d8c2 --- /dev/null +++ b/assets/js/5276ed9c.eefa78c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1567],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return n?a.createElement(k,i(i({ref:t},d),{},{components:n})):a.createElement(k,i({ref:t},d))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=n(87462),o=(n(67294),n(3905));const r={id:"deliver-wordpress"},i="Deliver the WordPress Application on Kubernetes",l={unversionedId:"kusion/getting-started/deliver-wordpress",id:"version-v0.10/kusion/getting-started/deliver-wordpress",title:"Deliver the WordPress Application on Kubernetes",description:"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.",source:"@site/versioned_docs/version-v0.10/kusion/2-getting-started/2-deliver-wordpress.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/deliver-wordpress",permalink:"/docs/kusion/getting-started/deliver-wordpress",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/2-getting-started/2-deliver-wordpress.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"deliver-wordpress"},sidebar:"kusion",previous:{title:"Install Kusion",permalink:"/docs/kusion/getting-started/install-kusion"},next:{title:"Overview",permalink:"/docs/kusion/concepts/project/overview"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"deliver-the-wordpress-application-on-kubernetes"},"Deliver the WordPress Application on Kubernetes"),(0,o.kt)("p",null,"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion. "),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Before we start to play with this example, we need to have the Kusion CLI installed and run a Kubernetes cluster. Here are some helpful documentations: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/getting-started/install-kusion"},"Kusion")," CLI"),(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," CLI and run a ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," cluster. Some light and convenient options for local deployment include ",(0,o.kt)("a",{parentName:"li",href:"https://docs.k3s.io/quick-start"},"k3s"),", ",(0,o.kt)("a",{parentName:"li",href:"https://k3d.io/v5.4.4/#installation"},"k3d"),", and ",(0,o.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"MiniKube"),". ")),(0,o.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,o.kt)("p",null,"To deploy the WordPress application, we need to first initiate a ",(0,o.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (we are using ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," here). Please copy the following example YAML file to your local ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# example workspace configs for local mysql database\nruntimes: \n kubernetes: \n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n\nmodules: \n mysql: \n default: \n suffix: "-mysql" # The suffix of the MySQL database name\n')),(0,o.kt)("p",null,"You can replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," and execute the following command line to initiate the workspace configuration for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,o.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,o.kt)("inlineCode",{parentName:"p"},"Kubernetes")," runtime config and ",(0,o.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,o.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,o.kt)("h2",{id:"init-project"},"Init Project"),(0,o.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,o.kt)("p",null,"All init templates are listed as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-local-db A sample wordpress project with local database\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-local-db\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-local-db'\n")),(0,o.kt)("p",null,"Please select ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db")," and press ",(0,o.kt)("inlineCode",{parentName:"p"},"Enter"),", after which we will see the hints below and use the default values to configure this project and stack. "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(63617).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"The directory structure looks like the following: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-local-db/dev && tree\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-local-db/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,o.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/project/overview"},"Project")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/stack/overview"},"Stack"),". ")),(0,o.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,o.kt)("p",null,"Now let's have a glance at the configuration file of ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),": "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stack.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n')),(0,o.kt)("p",null,"The configuration file ",(0,o.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,o.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,o.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a local ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,o.kt)("inlineCode",{parentName:"p"},"8.0")," for the application. The necessary Kubernetes resources for deploying and using the local database will be generated, and users can get the ",(0,o.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"paasword")," of the database through the ",(0,o.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,o.kt)("p",null,"This model hides the major complexity of Kubernetes resources such as ",(0,o.kt)("inlineCode",{parentName:"p"},"Namespace"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),", providing the concepts that are application-centric and infrastructure-agnostic. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the Models can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,o.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,o.kt)("p",null,"We will deliver the WordPress application in the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db/dev")," folder into the Kubernetes cluster with one command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion apply --watch"),". "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(41809).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"Check ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," status. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n wordpress-local-db get deployment\n")),(0,o.kt)("p",null,"The expected output is shown as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl -n wordpress-local-db get deployment\nNAME READY UP-TO-DATE AVAILABLE AGE\nwordpress-local-db-dev-wordpress 1/1 1 1 2m56s\nwordpress-mysql 1/1 1 1 2m56s\n")),(0,o.kt)("p",null,"In the above two resources, ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db-dev-wordpress")," corresponds to the Kubernetes ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the WordPress application, while ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-mysql")," corresponds to the ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the local MySQL database. "),(0,o.kt)("p",null,"Port-forward our WordPress with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\nForwarding from 127.0.0.1:12345 -> 80\nForwarding from [::1]:12345 -> 80\n\n")),(0,o.kt)("p",null,"Now we can visit ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:12345"},"http://localhost:12345")," in our browser and enjoy!"),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(85773).Z,width:"1500",height:"803"})),(0,o.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,o.kt)("p",null,"We can delete the WordPress application and related database resources using the following command line: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(21192).Z,width:"2560",height:"1440"})))}c.isMDXComponent=!0},41809:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/apply-wordpress-local-db-6a391cbf9576c88494710eb17f8c8396.gif"},21192:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/destroy-wordpress-local-db-93038beed84dadd31cbefdbbfb632ee1.gif"},63617:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/init-wordpress-local-db-34d0778e8b48028ad7a1394543a1dfb2.gif"},85773:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/55141fa2.1c98af2d.js b/assets/js/55141fa2.1c98af2d.js new file mode 100644 index 00000000000..c138ea32d4a --- /dev/null +++ b/assets/js/55141fa2.1c98af2d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2934],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),m=s(n),u=r,g=m["".concat(p,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(g,l(l({ref:t},d),{},{components:n})):a.createElement(g,l({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const o={id:"doc_app_configuration",sidebar_label:"App Configuration",sidebar_position:1},l="app_configuration",i={unversionedId:"kusion/reference/model/catalog_models/doc_app_configuration",id:"version-v0.9/kusion/reference/model/catalog_models/doc_app_configuration",title:"app_configuration",description:"Schema AppConfiguration",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/doc_app_configuration.md",sourceDirName:"kusion/reference/model/catalog_models",slug:"/kusion/reference/model/catalog_models/doc_app_configuration",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/doc_app_configuration.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"doc_app_configuration",sidebar_label:"App Configuration",sidebar_position:1},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/v0.9/kusion/reference/model/overview"},next:{title:"Job",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job"}},p={},s=[{value:"Schema AppConfiguration",id:"schema-appconfiguration",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"app_configuration"},"app_configuration"),(0,r.kt)("h2",{id:"schema-appconfiguration"},"Schema AppConfiguration"),(0,r.kt)("p",null,"AppConfiguration is a developer-centric definition that describes how to run an Application.",(0,r.kt)("br",null),"This application model builds upon a decade of experience at AntGroup running super large scale",(0,r.kt)("br",null),"internal developer platform, combined with best-of-breed ideas and practices from the community."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workload"),(0,r.kt)("br",null),"Workload defines how to run your application code. Currently supported workload profile",(0,r.kt)("br",null),"includes Service and Job."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service#schema-service"},"workload.Service")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job#schema-job"},"workload.Job")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"opsRule"),(0,r.kt)("br",null),"OpsRule specifies collection of rules that will be checked for Day-2 operation."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule#schema-opsrule"},"trait.OpsRule")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"database")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database#schema-database"},"database.Database")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"monitoring")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus#schema-prometheus"},"monitoring.Prometheus")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate an App with a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.accessories.database as db\nimport catalog.models.schema.v1.accessories.monitoring as m\nimport catalog.models.schema.v1.accessories.trait as t\n\nappConfiguration = ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n type: "CollaSet"\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n database: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/55141fa2.6b6b35ce.js b/assets/js/55141fa2.6b6b35ce.js deleted file mode 100644 index da76ef02269..00000000000 --- a/assets/js/55141fa2.6b6b35ce.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2934],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),m=s(n),u=r,g=m["".concat(p,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(g,l(l({ref:t},d),{},{components:n})):a.createElement(g,l({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const o={id:"doc_app_configuration",sidebar_label:"App Configuration",sidebar_position:1},l="app_configuration",i={unversionedId:"kusion/reference/model/catalog_models/doc_app_configuration",id:"version-v0.9/kusion/reference/model/catalog_models/doc_app_configuration",title:"app_configuration",description:"Schema AppConfiguration",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/doc_app_configuration.md",sourceDirName:"kusion/reference/model/catalog_models",slug:"/kusion/reference/model/catalog_models/doc_app_configuration",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/doc_app_configuration.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"doc_app_configuration",sidebar_label:"App Configuration",sidebar_position:1},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/v0.9/kusion/reference/model/overview"},next:{title:"Job",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job"}},p={},s=[{value:"Schema AppConfiguration",id:"schema-appconfiguration",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"app_configuration"},"app_configuration"),(0,r.kt)("h2",{id:"schema-appconfiguration"},"Schema AppConfiguration"),(0,r.kt)("p",null,"AppConfiguration is a developer-centric definition that describes how to run an Application.",(0,r.kt)("br",null),"This application model builds upon a decade of experience at AntGroup running super large scale",(0,r.kt)("br",null),"internal developer platform, combined with best-of-breed ideas and practices from the community."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workload"),(0,r.kt)("br",null),"Workload defines how to run your application code. Currently supported workload profile",(0,r.kt)("br",null),"includes Service and Job."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service#schema-service"},"workload.Service")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job#schema-job"},"workload.Job")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"opsRule"),(0,r.kt)("br",null),"OpsRule specifies collection of rules that will be checked for Day-2 operation."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule#schema-opsrule"},"trait.OpsRule")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"database")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database#schema-database"},"database.Database")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"monitoring")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus#schema-prometheus"},"monitoring.Prometheus")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate an App with a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.accessories.database as db\nimport catalog.models.schema.v1.accessories.monitoring as m\nimport catalog.models.schema.v1.accessories.trait as t\n\nappConfiguration = ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n type: "CollaSet"\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n database: db.Database {\n type: "aws"\n engine: "mysql"\n version: "5.7"\n instanceType: "db.t3.micro"\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/551843d2.362a0ef6.js b/assets/js/551843d2.362a0ef6.js new file mode 100644 index 00000000000..b7aa5b91938 --- /dev/null +++ b/assets/js/551843d2.362a0ef6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6925],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=o.createContext({}),p=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=i,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||r;return t?o.createElement(m,a(a({ref:n},c),{},{components:t})):o.createElement(m,a({ref:n},c))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,a=new Array(r);a[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,a[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var o=t(87462),i=(t(67294),t(3905));const r={},a="Schedule a Job",l={unversionedId:"kusion/user-guides/working-with-k8s/job",id:"version-v0.10/kusion/user-guides/working-with-k8s/job",title:"Schedule a Job",description:'The guides above provide examples on how to configure workloads of the type wl.Service, which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely wl.Job which corresponds to a one-off or recurring execution of tasks that run to completion and then stop.',source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/7-job.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/job",permalink:"/docs/kusion/user-guides/working-with-k8s/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/7-job.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{},sidebar:"kusion",previous:{title:"Set up Operational Rules",permalink:"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules"},next:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/kusion/user-guides/observability/prometheus"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"schedule-a-job"},"Schedule a Job"),(0,i.kt)("p",null,"The guides above provide examples on how to configure workloads of the type ",(0,i.kt)("inlineCode",{parentName:"p"},"wl.Service"),', which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely ',(0,i.kt)("inlineCode",{parentName:"p"},"wl.Job")," which corresponds to a one-off or recurring execution of tasks that run to completion and then stop."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for scheduling a job."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there. Alternatively, if you have updated your workspace config in the previous guides, no changes need to be made either."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/job"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"To schedule a job with cron expression, update ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k")," to the following:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Job {\n containers: {\n "busybox": c.Container {\n # The target image\n image: "busybox:1.28"\n # Run the following command as defined\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n # Run every minute.\n schedule: "* * * * *"\n }\n}\n')),(0,i.kt)("p",null,"The KCL snippet above schedules a job. Alternatively, if you want a one-time job without cron, simply remove the ",(0,i.kt)("inlineCode",{parentName:"p"},"schedule")," from the configuration."),(0,i.kt)("p",null,"You can find the full example in here in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/simple-job"},"konfig repo"),"."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying")," and schedule the job. Your output might look like one of the following:"),(0,i.kt)("p",null,"If you are starting from scratch, all resources are created on the spot:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u2514\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create batch/v1:CronJob:simple-service:helloworld-dev-helloworld success \nCreate batch/v1:CronJob:simple-service:simple-service-dev-helloworld success [2/2] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("p",null,"If you are starting from the last guide which configures an ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule"),", the output looks like the following which destroys the ",(0,i.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," and replace it with a ",(0,i.kt)("inlineCode",{parentName:"p"},"CronJob"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n* \u251c\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Delete\n* \u2514\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Delete\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Delete apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \n SUCCESS Create batch/v1:CronJob:simple-service:simple-service-dev-helloworld success \n SUCCESS Delete v1:Service:simple-service:simple-service-dev-helloworld-private success \nDelete v1:Service:simple-service:simple-service-dev-helloworld-private success [4/4] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 1 created, 0 updated, 2 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the job has now been scheduled:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get cronjob -n simple-service\nNAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE\nsimple-service-dev-helloworld * * * * * False 0 2m18s\n")),(0,i.kt)("p",null,"Verify the job has been triggered after the minute mark since we scheduled it to run every minute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get job -n simple-service\nNAME COMPLETIONS DURATION AGE\nsimple-service-dev-helloworld-28415748 1/1 5s 11s\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/551843d2.41313eba.js b/assets/js/551843d2.41313eba.js deleted file mode 100644 index 327be813f7a..00000000000 --- a/assets/js/551843d2.41313eba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6925],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=o.createContext({}),p=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=i,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||r;return t?o.createElement(m,a(a({ref:n},c),{},{components:t})):o.createElement(m,a({ref:n},c))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,a=new Array(r);a[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,a[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var o=t(87462),i=(t(67294),t(3905));const r={},a="Schedule a Job",l={unversionedId:"kusion/user-guides/working-with-k8s/job",id:"version-v0.10/kusion/user-guides/working-with-k8s/job",title:"Schedule a Job",description:'The guides above provide examples on how to configure workloads of the type wl.Service, which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely wl.Job which corresponds to a one-off or recurring execution of tasks that run to completion and then stop.',source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/7-job.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/job",permalink:"/docs/kusion/user-guides/working-with-k8s/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/7-job.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{},sidebar:"kusion",previous:{title:"Set up Operational Rules",permalink:"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules"},next:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/kusion/user-guides/observability/prometheus"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"schedule-a-job"},"Schedule a Job"),(0,i.kt)("p",null,"The guides above provide examples on how to configure workloads of the type ",(0,i.kt)("inlineCode",{parentName:"p"},"wl.Service"),', which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely ',(0,i.kt)("inlineCode",{parentName:"p"},"wl.Job")," which corresponds to a one-off or recurring execution of tasks that run to completion and then stop."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for scheduling a job."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there. Alternatively, if you have updated your workspace config in the previous guides, no changes need to be made either."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/job"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"To schedule a job with cron expression, update ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k")," to the following:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Job {\n containers: {\n "busybox": c.Container {\n # The target image\n image: "busybox:1.28"\n # Run the following command as defined\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n # Run every minute.\n schedule: "* * * * *"\n }\n}\n')),(0,i.kt)("p",null,"The KCL snippet above schedules a job. Alternatively, if you want a one-time job without cron, simply remove the ",(0,i.kt)("inlineCode",{parentName:"p"},"schedule")," from the configuration."),(0,i.kt)("p",null,"You can find the full example in here in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/simple-job"},"konfig repo"),"."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying")," and schedule the job. Your output might look like one of the following:"),(0,i.kt)("p",null,"If you are starting from scratch, all resources are created on the spot:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u2514\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create batch/v1:CronJob:simple-service:helloworld-dev-helloworld success \nCreate batch/v1:CronJob:simple-service:simple-service-dev-helloworld success [2/2] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("p",null,"If you are starting from the last guide which configures an ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule"),", the output looks like the following which destroys the ",(0,i.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," and replace it with a ",(0,i.kt)("inlineCode",{parentName:"p"},"CronJob"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n* \u251c\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Delete\n* \u2514\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Delete\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Delete apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \n SUCCESS Create batch/v1:CronJob:simple-service:simple-service-dev-helloworld success \n SUCCESS Delete v1:Service:simple-service:simple-service-dev-helloworld-private success \nDelete v1:Service:simple-service:simple-service-dev-helloworld-private success [4/4] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 1 created, 0 updated, 2 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the job has now been scheduled:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get cronjob -n simple-service\nNAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE\nsimple-service-dev-helloworld * * * * * False 0 2m18s\n")),(0,i.kt)("p",null,"Verify the job has been triggered after the minute mark since we scheduled it to run every minute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get job -n simple-service\nNAME COMPLETIONS DURATION AGE\nsimple-service-dev-helloworld-28415748 1/1 5s 11s\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/56362d1e.67075293.js b/assets/js/56362d1e.67075293.js deleted file mode 100644 index 1bfe1ba0ba9..00000000000 --- a/assets/js/56362d1e.67075293.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9242],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,g=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(g,o(o({ref:t},p),{},{components:n})):r.createElement(g,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const s={},o="Using Cloud Secrets Manager",i={unversionedId:"kusion/user-guides/secrets-management/using-cloud-secrets",id:"version-v0.10/kusion/user-guides/secrets-management/using-cloud-secrets",title:"Using Cloud Secrets Manager",description:"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",sourceDirName:"kusion/5-user-guides/5-secrets-management",slug:"/kusion/user-guides/secrets-management/using-cloud-secrets",permalink:"/docs/kusion/user-guides/secrets-management/using-cloud-secrets",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions"},next:{title:"Kusion Commands",permalink:"/docs/kusion/reference/commands/"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Setting up workspace",id:"setting-up-workspace",level:2},{value:"Update AppConfiguration",id:"update-appconfiguration",level:2},{value:"Apply and Verify",id:"apply-and-verify",level:2}],p={toc:l};function u(e){let{components:t,...s}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"using-cloud-secrets-manager"},"Using Cloud Secrets Manager"),(0,a.kt)("p",null,"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc"),(0,a.kt)("p",null,"Kusion provides out-of-the-box support to reference existing external secrets management solution, this tutorial introduces that how to pull the secret from AWS Secrets Manager to make it available to applications."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,a.kt)("p",null,"Additionally, you also need to configure the obtained AccessKey and SecretKey as environment variables: "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"aws iam account",src:n(24838).Z,width:"2874",height:"1398"})),(0,a.kt)("h2",{id:"setting-up-workspace"},"Setting up workspace"),(0,a.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,a.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,a.kt)("p",null,"In the case of setting up cloud secrets manager, platform teams need to specify which secrets management solution to use and necessary information to access on the workspace level."),(0,a.kt)("p",null,"A sample ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with AWS Secrets Manager settings:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"modules:\n ...\nsecretStore:\n provider:\n aws:\n region: us-east-1\n profile: The optional profile to be used to interact with AWS Secrets Manager.\n...\n")),(0,a.kt)("h2",{id:"update-appconfiguration"},"Update AppConfiguration"),(0,a.kt)("p",null,"At this point we are set up for good! Now you can declare external type of secrets via the ",(0,a.kt)("inlineCode",{parentName:"p"},"secrets")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model to consume sensitive data stored in AWS Secrets Manager."),(0,a.kt)("p",null,"See the example below for a full, deployable AppConfiguration."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\ngitsync: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "syncer": c.Container {\n image: "dyrnq/git-sync"\n # Run the following command as defined\n command: [\n "--repo=https://github.com/KusionStack/kusion"\n "--ref=HEAD"\n "--root=/mnt/git"\n ]\n # Consume secrets in environment variables\n env: {\n "GIT_SYNC_USERNAME": "secret://git-auth/username"\n "GIT_SYNC_PASSWORD": "secret://git-auth/password"\n }\n }\n }\n # Secrets used to retrieve secret data from AWS Secrets Manager\n secrets: {\n "git-auth": sec.Secret {\n type: "external"\n data: {\n "username": "ref://git-auth-info/username"\n "password": "ref://git-auth-info/password"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"apply-and-verify"},"Apply and Verify"),(0,a.kt)("p",null,"Run ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply")," command to deploy above application, then use the below command to verify if the secret got deployed:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get secret -n secretdemo\n")),(0,a.kt)("p",null,"You will find ",(0,a.kt)("inlineCode",{parentName:"p"},"git-auth")," of type Opaque automatically created and contains sensitive information pulled from AWS Secrets Manager."))}u.isMDXComponent=!0},24838:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"}}]); \ No newline at end of file diff --git a/assets/js/56362d1e.7f27268d.js b/assets/js/56362d1e.7f27268d.js new file mode 100644 index 00000000000..d4618da4222 --- /dev/null +++ b/assets/js/56362d1e.7f27268d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9242],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,g=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(g,o(o({ref:t},p),{},{components:n})):r.createElement(g,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const s={},o="Using Cloud Secrets Manager",i={unversionedId:"kusion/user-guides/secrets-management/using-cloud-secrets",id:"version-v0.10/kusion/user-guides/secrets-management/using-cloud-secrets",title:"Using Cloud Secrets Manager",description:"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",sourceDirName:"kusion/5-user-guides/5-secrets-management",slug:"/kusion/user-guides/secrets-management/using-cloud-secrets",permalink:"/docs/kusion/user-guides/secrets-management/using-cloud-secrets",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions"},next:{title:"Kusion Commands",permalink:"/docs/kusion/reference/commands/"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Setting up workspace",id:"setting-up-workspace",level:2},{value:"Update AppConfiguration",id:"update-appconfiguration",level:2},{value:"Apply and Verify",id:"apply-and-verify",level:2}],p={toc:l};function u(e){let{components:t,...s}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"using-cloud-secrets-manager"},"Using Cloud Secrets Manager"),(0,a.kt)("p",null,"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc"),(0,a.kt)("p",null,"Kusion provides out-of-the-box support to reference existing external secrets management solution, this tutorial introduces that how to pull the secret from AWS Secrets Manager to make it available to applications."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,a.kt)("p",null,"Additionally, you also need to configure the obtained AccessKey and SecretKey as environment variables: "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"aws iam account",src:n(24838).Z,width:"2874",height:"1398"})),(0,a.kt)("h2",{id:"setting-up-workspace"},"Setting up workspace"),(0,a.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,a.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,a.kt)("p",null,"In the case of setting up cloud secrets manager, platform teams need to specify which secrets management solution to use and necessary information to access on the workspace level."),(0,a.kt)("p",null,"A sample ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with AWS Secrets Manager settings:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"modules:\n ...\nsecretStore:\n provider:\n aws:\n region: us-east-1\n profile: The optional profile to be used to interact with AWS Secrets Manager.\n...\n")),(0,a.kt)("h2",{id:"update-appconfiguration"},"Update AppConfiguration"),(0,a.kt)("p",null,"At this point we are set up for good! Now you can declare external type of secrets via the ",(0,a.kt)("inlineCode",{parentName:"p"},"secrets")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model to consume sensitive data stored in AWS Secrets Manager."),(0,a.kt)("p",null,"See the example below for a full, deployable AppConfiguration."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\ngitsync: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "syncer": c.Container {\n image: "dyrnq/git-sync"\n # Run the following command as defined\n command: [\n "--repo=https://github.com/KusionStack/kusion"\n "--ref=HEAD"\n "--root=/mnt/git"\n ]\n # Consume secrets in environment variables\n env: {\n "GIT_SYNC_USERNAME": "secret://git-auth/username"\n "GIT_SYNC_PASSWORD": "secret://git-auth/password"\n }\n }\n }\n # Secrets used to retrieve secret data from AWS Secrets Manager\n secrets: {\n "git-auth": sec.Secret {\n type: "external"\n data: {\n "username": "ref://git-auth-info/username"\n "password": "ref://git-auth-info/password"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"apply-and-verify"},"Apply and Verify"),(0,a.kt)("p",null,"Run ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply")," command to deploy above application, then use the below command to verify if the secret got deployed:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get secret -n secretdemo\n")),(0,a.kt)("p",null,"You will find ",(0,a.kt)("inlineCode",{parentName:"p"},"git-auth")," of type Opaque automatically created and contains sensitive information pulled from AWS Secrets Manager."))}u.isMDXComponent=!0},24838:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"}}]); \ No newline at end of file diff --git a/assets/js/566dbdc9.3f454234.js b/assets/js/566dbdc9.310585c2.js similarity index 82% rename from assets/js/566dbdc9.3f454234.js rename to assets/js/566dbdc9.310585c2.js index 6727c7b8530..25ae7313582 100644 --- a/assets/js/566dbdc9.3f454234.js +++ b/assets/js/566dbdc9.310585c2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7288],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),u=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(c.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=u(r),f=o,k=d["".concat(c,".").concat(f)]||d[f]||l[f]||i;return r?n.createElement(k,s(s({ref:t},p),{},{components:r})):n.createElement(k,s({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var n=r(87462),o=(r(67294),r(3905));const i={},s="Kubernetes",a={unversionedId:"kusion/guides/working-with-k8s/index",id:"version-v0.9/kusion/guides/working-with-k8s/index",title:"Kubernetes",description:"",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/index.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/index.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/v0.9/kusion/guides/cloud-resources/expose-service"},next:{title:"Deploy Application",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application"}},c={},u=[],p={toc:u};function l(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kubernetes"},"Kubernetes"))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7288],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),u=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(c.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=u(r),f=o,k=d["".concat(c,".").concat(f)]||d[f]||l[f]||i;return r?n.createElement(k,s(s({ref:t},p),{},{components:r})):n.createElement(k,s({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var n=r(87462),o=(r(67294),r(3905));const i={},s="Kubernetes",a={unversionedId:"kusion/guides/working-with-k8s/index",id:"version-v0.9/kusion/guides/working-with-k8s/index",title:"Kubernetes",description:"",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/index.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/index.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/v0.9/kusion/guides/cloud-resources/expose-service"},next:{title:"Deploy Application",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application"}},c={},u=[],p={toc:u};function l(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kubernetes"},"Kubernetes"))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5674e156.7499a6c1.js b/assets/js/5674e156.7499a6c1.js new file mode 100644 index 00000000000..93aca4b543c --- /dev/null +++ b/assets/js/5674e156.7499a6c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[538],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=o.createContext({}),s=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=s(e.components);return o.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=s(n),h=r,m=u["".concat(p,".").concat(h)]||u[h]||c[h]||i;return n?o.createElement(m,a(a({ref:t},d),{},{components:n})):o.createElement(m,a({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={},a="Expose Service",l={unversionedId:"kusion/guides/working-with-k8s/service",id:"version-v0.9/kusion/guides/working-with-k8s/service",title:"Expose Service",description:"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/3-service.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/service",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/3-service.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Containers",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/container"},next:{title:"Upgrade Image",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],d={toc:s};function c(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},d,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"expose-service"},"Expose Service"),(0,r.kt)("p",null,"You can determine how to expose your service in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,r.kt)("inlineCode",{parentName:"p"},"ports")," field (under the ",(0,r.kt)("inlineCode",{parentName:"p"},"workload")," schemas). The ",(0,r.kt)("inlineCode",{parentName:"p"},"ports")," field defines a list of all the ",(0,r.kt)("inlineCode",{parentName:"p"},"Port"),"s you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications."),(0,r.kt)("p",null,"Unless explicitly defined, each of the ports exposed is by default exposed privately as a ",(0,r.kt)("inlineCode",{parentName:"p"},"ClusterIP")," type service. You can expose a port publicly by specifying the ",(0,r.kt)("inlineCode",{parentName:"p"},"exposeInternet")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"Port")," schema. At the moment, the implementation for publicly access is done via Load Balancer type service backed by cloud providers. Ingress will be supported in a future version of kusion."),(0,r.kt)("p",null,"For the ",(0,r.kt)("inlineCode",{parentName:"p"},"Port")," schema reference, please see ",(0,r.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-port"},"here")," for more details."),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"example"},"Example"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 8080\n targetPort: 80\n }\n ]\n }\n}\n')),(0,r.kt)("p",null,"The code above changes the service port to expose from ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," in the last guide to ",(0,r.kt)("inlineCode",{parentName:"p"},"8080"),", but still targeting the container port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," because that's what the application is listening on."),(0,r.kt)("h2",{id:"applying"},"Applying"),(0,r.kt)("p",null,"Re-run steps in ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new service configuration can be applied."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private Update\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld UnChanged\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS Update v1:Service:helloworld:helloworld-dev-helloworld-private success \n SUCCESS UnChanged apps/v1:Deployment:helloworld:helloworld-dev-helloworld, skip \nUnChanged apps/v1:Deployment:helloworld:helloworld-dev-helloworld, skip [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,r.kt)("h2",{id:"validation"},"Validation"),(0,r.kt)("p",null,"We can verify the Kubernetes service now has the updated attributes (mapping service port 8080 to container port 80) as defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"ports")," configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl get svc -n helloworld -o yaml\n...\n spec:\n ...\n ports:\n - name: helloworld-dev-helloworld-private-8080-tcp\n port: 8080\n protocol: TCP\n targetPort: 80\n...\n")),(0,r.kt)("p",null,"Exposing service port 8080:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/helloworld-dev-helloworld-private -n helloworld 30000:8080\n")),(0,r.kt)("p",null,"Open browser and visit ",(0,r.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),", the application should be up and running\uff1a"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}c.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/5674e156.b028d47e.js b/assets/js/5674e156.b028d47e.js deleted file mode 100644 index dcbdcf26ae9..00000000000 --- a/assets/js/5674e156.b028d47e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[538],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=o.createContext({}),s=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=s(e.components);return o.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=s(n),h=r,m=u["".concat(p,".").concat(h)]||u[h]||c[h]||i;return n?o.createElement(m,a(a({ref:t},d),{},{components:n})):o.createElement(m,a({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={},a="Expose Service",l={unversionedId:"kusion/guides/working-with-k8s/service",id:"version-v0.9/kusion/guides/working-with-k8s/service",title:"Expose Service",description:"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/3-service.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/service",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/3-service.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Containers",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/container"},next:{title:"Upgrade Image",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],d={toc:s};function c(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},d,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"expose-service"},"Expose Service"),(0,r.kt)("p",null,"You can determine how to expose your service in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,r.kt)("inlineCode",{parentName:"p"},"ports")," field (under the ",(0,r.kt)("inlineCode",{parentName:"p"},"workload")," schemas). The ",(0,r.kt)("inlineCode",{parentName:"p"},"ports")," field defines a list of all the ",(0,r.kt)("inlineCode",{parentName:"p"},"Port"),"s you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications."),(0,r.kt)("p",null,"Unless explicitly defined, each of the ports exposed is by default exposed privately as a ",(0,r.kt)("inlineCode",{parentName:"p"},"ClusterIP")," type service. You can expose a port publicly by specifying the ",(0,r.kt)("inlineCode",{parentName:"p"},"exposeInternet")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"Port")," schema. At the moment, the implementation for publicly access is done via Load Balancer type service backed by cloud providers. Ingress will be supported in a future version of kusion."),(0,r.kt)("p",null,"For the ",(0,r.kt)("inlineCode",{parentName:"p"},"Port")," schema reference, please see ",(0,r.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-port"},"here")," for more details."),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"example"},"Example"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 8080\n targetPort: 80\n }\n ]\n }\n}\n')),(0,r.kt)("p",null,"The code above changes the service port to expose from ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," in the last guide to ",(0,r.kt)("inlineCode",{parentName:"p"},"8080"),", but still targeting the container port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," because that's what the application is listening on."),(0,r.kt)("h2",{id:"applying"},"Applying"),(0,r.kt)("p",null,"Re-run steps in ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new service configuration can be applied."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private Update\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld UnChanged\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS Update v1:Service:helloworld:helloworld-dev-helloworld-private success \n SUCCESS UnChanged apps/v1:Deployment:helloworld:helloworld-dev-helloworld, skip \nUnChanged apps/v1:Deployment:helloworld:helloworld-dev-helloworld, skip [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,r.kt)("h2",{id:"validation"},"Validation"),(0,r.kt)("p",null,"We can verify the Kubernetes service now has the updated attributes (mapping service port 8080 to container port 80) as defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"ports")," configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl get svc -n helloworld -o yaml\n...\n spec:\n ...\n ports:\n - name: helloworld-dev-helloworld-private-8080-tcp\n port: 8080\n protocol: TCP\n targetPort: 80\n...\n")),(0,r.kt)("p",null,"Exposing service port 8080:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/helloworld-dev-helloworld-private -n helloworld 30000:8080\n")),(0,r.kt)("p",null,"Open browser and visit ",(0,r.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),", the application should be up and running\uff1a"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}c.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/56d50f7c.0e2ca84e.js b/assets/js/56d50f7c.0e2ca84e.js new file mode 100644 index 00000000000..da659a620af --- /dev/null +++ b/assets/js/56d50f7c.0e2ca84e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7360],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(a),m=r,h=u["".concat(l,".").concat(m)]||u[m]||p[m]||o;return a?n.createElement(h,s(s({ref:t},d),{},{components:a})):n.createElement(h,s({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.d(t,{Z:()=>s});var n=a(67294),r=a(86010);const o="tabItem_Ymn6";function s(e){let{children:t,hidden:a,className:s}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,s),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>S});var n=a(87462),r=a(67294),o=a(86010),s=a(12466),i=a(76775),l=a(91980),c=a(67392),d=a(50012);function p(e){return function(e){var t;return(null==(t=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function u(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??p(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function m(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function f(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,o=u(e),[s,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[l,c]=h({queryString:a,groupId:n}),[p,f]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,d.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&o.set(e)}),[a,o])]}({groupId:n}),k=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{k&&i(k)}),[k]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),f(e)}),[c,f,o]),tabValues:o}}var k=a(72389);const g="tabList__CuJ",v="tabItem_LNqP";function w(e){let{className:t,block:a,selectedValue:i,selectValue:l,tabValues:c}=e;const d=[],{blockElementScrollPositionUntilNextRender:p}=(0,s.o5)(),u=e=>{const t=e.currentTarget,a=d.indexOf(t),n=c[a].value;n!==i&&(p(t),l(n))},m=e=>{var t;let a=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=d.indexOf(e.currentTarget)+1;a=d[t]??d[0];break}case"ArrowLeft":{const t=d.indexOf(e.currentTarget)-1;a=d[t]??d[d.length-1];break}}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:s}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>d.push(e),onKeyDown:m,onClick:u},s,{className:(0,o.Z)("tabs__item",v,null==s?void 0:s.className,{"tabs__item--active":i===t})}),a??t)})))}function b(e){let{lazy:t,children:a,selectedValue:n}=e;const o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function y(e){const t=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(w,(0,n.Z)({},e,t)),r.createElement(b,(0,n.Z)({},e,t)))}function S(e){const t=(0,k.Z)();return r.createElement(y,(0,n.Z)({key:String(t)},e))}},60825:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=a(87462),r=(a(67294),a(3905)),o=a(74866),s=a(85162);const i={},l="Deliver the WordPress Application with Cloud RDS",c={unversionedId:"kusion/guides/cloud-resources/database",id:"version-v0.9/kusion/guides/cloud-resources/database",title:"Deliver the WordPress Application with Cloud RDS",description:"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.",source:"@site/versioned_docs/version-v0.9/kusion/guides/cloud-resources/database.md",sourceDirName:"kusion/guides/cloud-resources",slug:"/kusion/guides/cloud-resources/database",permalink:"/docs/v0.9/kusion/guides/cloud-resources/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/cloud-resources/database.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"User Guide",permalink:"/docs/v0.9/kusion/guides/"},next:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/v0.9/kusion/guides/cloud-resources/expose-service"}},d={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Config Files",id:"review-config-files",level:3},{value:"Deliver WordPress Application",id:"deliver-wordpress-application",level:2},{value:"Verify WordPress Application",id:"verify-wordpress-application",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],u={toc:p};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-with-cloud-rds"},"Deliver the WordPress Application with Cloud RDS"),(0,r.kt)("p",null,"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"../../getting-started/install-kusion"},"Install Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Deploy Kubernetes")," or ",(0,r.kt)("a",{parentName:"li",href:"https://kind.sigs.k8s.io/"},"Kind")," or ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.terraform.io/"},"Install Terraform")),(0,r.kt)("li",{parentName:"ul"},"Prepare a cloud service account and create a user with ",(0,r.kt)("inlineCode",{parentName:"li"},"VPCFullAccess")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"RDSFullAccess")," permissions to use the Relational Database Service (RDS). This kind of user can be created and managed in the Identity and Access Management (IAM) console"),(0,r.kt)("li",{parentName:"ul"},"The environment that executes ",(0,r.kt)("inlineCode",{parentName:"li"},"kusion")," need to have connectivity to terraform registry to download the terraform providers")),(0,r.kt)("p",null,"Additionally, we also need to configure the obtained AccessKey and SecretKey as environment variables, along with the region if you are using certain cloud provider: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\nexport AWS_PROVIDER_REGION="xx-xxxx-x" # replace it with your AWS Region\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws iam account",src:a(24838).Z,width:"2874",height:"1398"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export ALICLOUD_ACCESS_KEY="LTAI5txxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="nxuowIxxx" # replace it with your SecretKey\nexport ALICLOUD_PROVIDER_REGION="xx-xxxxxxx" # replace it with your AliCloud Region\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud iam account",src:a(73725).Z,width:"1500",height:"629"})))),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-cloud-rds A sample wordpress project with cloud rds\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? Project Name: wordpress-cloud-rds\n? AppName: wordpress\n? ProjectName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-cloud-rds'\n")),(0,r.kt)("p",null,"Select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),". After that, we will see hints below and use the default value to config this project and stack."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(82605).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground tree wordpress-cloud-rds\nwordpress-cloud-rds\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u251c\u2500\u2500 platform.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n1 directory, 6 files\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in\n",(0,r.kt)("a",{parentName:"p",href:"../../concepts/glossary"},"Concepts"),".")),(0,r.kt)("h3",{id:"review-config-files"},"Review Config Files"),(0,r.kt)("p",null,"Let's take a look at the configuration files located in ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds/dev"),"."),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.trait as t\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.secret as sec\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.accessories.database as db\n\n# main.k declares reusable configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: db.Database {\n type: "aws"\n engine: "MySQL"\n version: "8.0"\n size: 20\n instanceType: "db.t3.micro"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"import catalog.models.schema.v1 as ac\n\n# platform.k declares customized configurations\nwordpress: ac.AppConfiguration {\n database: {\n privateRouting = False\n\n # SubnetID defines the virtual subnet ID associated with the VPC that the rds\n # instance will be created in. The rds instance won't be created in user's own VPC\n # but in default VPC of cloud vendor, if this field is not provided.\n # subnetID = [your-subnet-id]\n\n # category = \"serverless_basic\"\n }\n}\n")),(0,r.kt)("p",null,"The template project defaults to use ",(0,r.kt)("inlineCode",{parentName:"p"},"AWS")," RDS instance for the WordPress application. If you would like to try creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Alicloud")," RDS instance, you could modify the ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")," to the following and replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"[your-subnet-id]")," in ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")," with the ",(0,r.kt)("inlineCode",{parentName:"p"},"vSwitchID")," to provision the database in. "),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.trait as t\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.secret as sec\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.accessories.database as db\n\n# main.k declares reusable configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "8.0"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"import catalog.models.schema.v1 as ac\n\n# platform.k declares customized configurations\nwordpress: ac.AppConfiguration {\n database: {\n privateRouting = False\n\n # SubnetID defines the virtual subnet ID associated with the VPC that the rds\n # instance will be created in. The rds instance won't be created in user's own VPC\n # but in default VPC of cloud vendor, if this field is not provided.\n subnetID = [your-subnet-id]\n\n category = \"serverless_basic\"\n }\n}\n")),(0,r.kt)("p",null,"The configuration code files you need to pay attention are mainly ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k"),". Specifically: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dev/main.k")," contains configurations for the ",(0,r.kt)("strong",{parentName:"li"},"Development team")," to fill out on how the application should run in the dev environment. In addition to declaring its application container attributes such as image, environment variables, resource requirements, its network attributes such as opening the port 80 to provide service, it also declares that it needs an RDS instance."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dev/platform.k")," contains config codes for ",(0,r.kt)("strong",{parentName:"li"},"Platform team")," to fill out for the WordPress application deployment in the dev environment on AliCloud. Here, the main purpose is to specify the details on the cloud database (such as how network access is managed, what category of service to get from the cloud vendor) for it to be connected from the WordPress application container.")),(0,r.kt)("p",null,"As shown above, benefiting from the advanced features of KCL concerning variable, function, and schema definition, we can abstract and encapsulate the RDS resources, which shields many properties that the Developer does not need to be aware of. The developer only needs to fill in a few necessary fields in the AppConfiguration instance to complete the declaration of RDS resources, so that the application configuration can be organized more flexibly and efficiently. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about Catalog models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("h2",{id:"deliver-wordpress-application"},"Deliver WordPress Application"),(0,r.kt)("p",null,"You can complete the delivery of the WordPress application using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-cloud-rds && kusion apply --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with aws rds",src:a(87103).Z,width:"2276",height:"766"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with alicloud rds",src:a(30263).Z,width:"2504",height:"1996"})))),(0,r.kt)("p",null,"After all the resources reconciled, we can port-forward our local port (e.g. 12345) to the WordPress frontend service port (80) in the cluster:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress svc/wordpress-dev-wordpress-private 12345:80\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kubectl port-forward for wordpress",src:a(86535).Z,width:"2384",height:"234"})),(0,r.kt)("h2",{id:"verify-wordpress-application"},"Verify WordPress Application"),(0,r.kt)("p",null,"Next, we will verify the WordPress site service we just delivered, along with the creation of the RDS instance it depends on. We can start using the WordPress site by accessing the link of local-forwarded port ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"(http://localhost:12345)")," we just configured in the browser. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"wordpress site page",src:a(85773).Z,width:"1500",height:"803"})),(0,r.kt)("p",null,"In addition, we can also log in to the cloud service console page to view the RDS instance we just created."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws rds instance",src:a(68678).Z,width:"2876",height:"964"}),"\n",(0,r.kt)("img",{alt:"aws rds instance detailed information",src:a(86915).Z,width:"1224",height:"274"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud rds instance",src:a(34811).Z,width:"1500",height:"748"})))),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"You can delete the WordPress application and related RDS resources using the following command line. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with aws rds",src:a(37589).Z,width:"2184",height:"730"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with alicloud rds",src:a(75775).Z,width:"1462",height:"776"})))))}m.isMDXComponent=!0},34811:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alicloud-rds-instance-88d560e7fdab77f7d83592ae1ded6866.png"},87103:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-application-with-aws-rds-580915491e85e04d050cf19bbf0f96cd.png"},30263:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-application-b757aedd0d5513207e0bd65019d7a4c2.png"},24838:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"},86915:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-rds-instance-detail-e0f1e737f54491f738769b152de96806.png"},68678:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-rds-instance-12f87b94fbc4a76319d8d9d39fd465d2.png"},82605:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/init-wordpress-with-rds-d6c58387ae3d8ce26394e6e2f7402efd.gif"},37589:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-destroy-wordpress-with-aws-rds-304a7051e2646ad78490fb641fe5a776.png"},75775:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-destroy-wordpress-917a4bf29dfb33b39f8b306df03d9f6a.png"},73725:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/set-rds-access-9347ae09377aeb94d9f6d1e5d8688ab5.png"},86535:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-port-forward-2a83514580f7cf81d890841495f9441e.png"},85773:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/56d50f7c.bc0aede7.js b/assets/js/56d50f7c.bc0aede7.js deleted file mode 100644 index b475761d668..00000000000 --- a/assets/js/56d50f7c.bc0aede7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7360],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(a),m=r,h=u["".concat(l,".").concat(m)]||u[m]||p[m]||o;return a?n.createElement(h,s(s({ref:t},d),{},{components:a})):n.createElement(h,s({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.d(t,{Z:()=>s});var n=a(67294),r=a(86010);const o="tabItem_Ymn6";function s(e){let{children:t,hidden:a,className:s}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,s),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>S});var n=a(87462),r=a(67294),o=a(86010),s=a(12466),i=a(76775),l=a(91980),c=a(67392),d=a(50012);function p(e){return function(e){var t;return(null==(t=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function u(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??p(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function m(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function f(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,o=u(e),[s,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[l,c]=h({queryString:a,groupId:n}),[p,f]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,d.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&o.set(e)}),[a,o])]}({groupId:n}),k=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{k&&i(k)}),[k]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),f(e)}),[c,f,o]),tabValues:o}}var k=a(72389);const g="tabList__CuJ",v="tabItem_LNqP";function w(e){let{className:t,block:a,selectedValue:i,selectValue:l,tabValues:c}=e;const d=[],{blockElementScrollPositionUntilNextRender:p}=(0,s.o5)(),u=e=>{const t=e.currentTarget,a=d.indexOf(t),n=c[a].value;n!==i&&(p(t),l(n))},m=e=>{var t;let a=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=d.indexOf(e.currentTarget)+1;a=d[t]??d[0];break}case"ArrowLeft":{const t=d.indexOf(e.currentTarget)-1;a=d[t]??d[d.length-1];break}}null==(t=a)||t.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:s}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>d.push(e),onKeyDown:m,onClick:u},s,{className:(0,o.Z)("tabs__item",v,null==s?void 0:s.className,{"tabs__item--active":i===t})}),a??t)})))}function b(e){let{lazy:t,children:a,selectedValue:n}=e;const o=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function y(e){const t=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(w,(0,n.Z)({},e,t)),r.createElement(b,(0,n.Z)({},e,t)))}function S(e){const t=(0,k.Z)();return r.createElement(y,(0,n.Z)({key:String(t)},e))}},60825:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=a(87462),r=(a(67294),a(3905)),o=a(74866),s=a(85162);const i={},l="Deliver the WordPress Application with Cloud RDS",c={unversionedId:"kusion/guides/cloud-resources/database",id:"version-v0.9/kusion/guides/cloud-resources/database",title:"Deliver the WordPress Application with Cloud RDS",description:"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.",source:"@site/versioned_docs/version-v0.9/kusion/guides/cloud-resources/database.md",sourceDirName:"kusion/guides/cloud-resources",slug:"/kusion/guides/cloud-resources/database",permalink:"/docs/v0.9/kusion/guides/cloud-resources/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/cloud-resources/database.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"User Guide",permalink:"/docs/v0.9/kusion/guides/"},next:{title:"Expose Application Service Deployed on CSP Kubernetes",permalink:"/docs/v0.9/kusion/guides/cloud-resources/expose-service"}},d={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Config Files",id:"review-config-files",level:3},{value:"Deliver WordPress Application",id:"deliver-wordpress-application",level:2},{value:"Verify WordPress Application",id:"verify-wordpress-application",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],u={toc:p};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"deliver-the-wordpress-application-with-cloud-rds"},"Deliver the WordPress Application with Cloud RDS"),(0,r.kt)("p",null,"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article. "),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"../../getting-started/install-kusion"},"Install Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Deploy Kubernetes")," or ",(0,r.kt)("a",{parentName:"li",href:"https://kind.sigs.k8s.io/"},"Kind")," or ",(0,r.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"Minikube")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.terraform.io/"},"Install Terraform")),(0,r.kt)("li",{parentName:"ul"},"Prepare a cloud service account and create a user with ",(0,r.kt)("inlineCode",{parentName:"li"},"VPCFullAccess")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"RDSFullAccess")," permissions to use the Relational Database Service (RDS). This kind of user can be created and managed in the Identity and Access Management (IAM) console"),(0,r.kt)("li",{parentName:"ul"},"The environment that executes ",(0,r.kt)("inlineCode",{parentName:"li"},"kusion")," need to have connectivity to terraform registry to download the terraform providers")),(0,r.kt)("p",null,"Additionally, we also need to configure the obtained AccessKey and SecretKey as environment variables, along with the region if you are using certain cloud provider: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\nexport AWS_PROVIDER_REGION="xx-xxxx-x" # replace it with your AWS Region\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws iam account",src:a(24838).Z,width:"2874",height:"1398"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'export ALICLOUD_ACCESS_KEY="LTAI5txxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="nxuowIxxx" # replace it with your SecretKey\nexport ALICLOUD_PROVIDER_REGION="xx-xxxxxxx" # replace it with your AliCloud Region\n')),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud iam account",src:a(73725).Z,width:"1500",height:"629"})))),(0,r.kt)("h2",{id:"init-project"},"Init Project"),(0,r.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,r.kt)("p",null,"All init templates are listed as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-cloud-rds A sample wordpress project with cloud rds\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? Project Name: wordpress-cloud-rds\n? AppName: wordpress\n? ProjectName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-cloud-rds'\n")),(0,r.kt)("p",null,"Select ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds")," and press ",(0,r.kt)("inlineCode",{parentName:"p"},"Enter"),". After that, we will see hints below and use the default value to config this project and stack."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(82605).Z,width:"2560",height:"1440"})),(0,r.kt)("p",null,"The directory structure looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground tree wordpress-cloud-rds\nwordpress-cloud-rds\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod.lock\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u251c\u2500\u2500 platform.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n\n1 directory, 6 files\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in\n",(0,r.kt)("a",{parentName:"p",href:"../../concepts/glossary"},"Concepts"),".")),(0,r.kt)("h3",{id:"review-config-files"},"Review Config Files"),(0,r.kt)("p",null,"Let's take a look at the configuration files located in ",(0,r.kt)("inlineCode",{parentName:"p"},"wordpress-cloud-rds/dev"),"."),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.trait as t\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.secret as sec\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.accessories.database as db\n\n# main.k declares reusable configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: db.Database {\n type: "aws"\n engine: "MySQL"\n version: "8.0"\n size: 20\n instanceType: "db.t3.micro"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"import catalog.models.schema.v1 as ac\n\n# platform.k declares customized configurations\nwordpress: ac.AppConfiguration {\n database: {\n privateRouting = False\n\n # SubnetID defines the virtual subnet ID associated with the VPC that the rds\n # instance will be created in. The rds instance won't be created in user's own VPC\n # but in default VPC of cloud vendor, if this field is not provided.\n # subnetID = [your-subnet-id]\n\n # category = \"serverless_basic\"\n }\n}\n")),(0,r.kt)("p",null,"The template project defaults to use ",(0,r.kt)("inlineCode",{parentName:"p"},"AWS")," RDS instance for the WordPress application. If you would like to try creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Alicloud")," RDS instance, you could modify the ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")," to the following and replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"[your-subnet-id]")," in ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")," with the ",(0,r.kt)("inlineCode",{parentName:"p"},"vSwitchID")," to provision the database in. "),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.trait as t\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.secret as sec\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.accessories.database as db\n\n# main.k declares reusable configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "8.0"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"import catalog.models.schema.v1 as ac\n\n# platform.k declares customized configurations\nwordpress: ac.AppConfiguration {\n database: {\n privateRouting = False\n\n # SubnetID defines the virtual subnet ID associated with the VPC that the rds\n # instance will be created in. The rds instance won't be created in user's own VPC\n # but in default VPC of cloud vendor, if this field is not provided.\n subnetID = [your-subnet-id]\n\n category = \"serverless_basic\"\n }\n}\n")),(0,r.kt)("p",null,"The configuration code files you need to pay attention are mainly ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/main.k")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"dev/platform.k"),". Specifically: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dev/main.k")," contains configurations for the ",(0,r.kt)("strong",{parentName:"li"},"Development team")," to fill out on how the application should run in the dev environment. In addition to declaring its application container attributes such as image, environment variables, resource requirements, its network attributes such as opening the port 80 to provide service, it also declares that it needs an RDS instance."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dev/platform.k")," contains config codes for ",(0,r.kt)("strong",{parentName:"li"},"Platform team")," to fill out for the WordPress application deployment in the dev environment on AliCloud. Here, the main purpose is to specify the details on the cloud database (such as how network access is managed, what category of service to get from the cloud vendor) for it to be connected from the WordPress application container.")),(0,r.kt)("p",null,"As shown above, benefiting from the advanced features of KCL concerning variable, function, and schema definition, we can abstract and encapsulate the RDS resources, which shields many properties that the Developer does not need to be aware of. The developer only needs to fill in a few necessary fields in the AppConfiguration instance to complete the declaration of RDS resources, so that the application configuration can be organized more flexibly and efficiently. "),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about Catalog models can be found in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,r.kt)("h2",{id:"deliver-wordpress-application"},"Deliver WordPress Application"),(0,r.kt)("p",null,"You can complete the delivery of the WordPress application using the following command line: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-cloud-rds && kusion apply --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with aws rds",src:a(87103).Z,width:"2276",height:"766"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"apply the wordpress application with alicloud rds",src:a(30263).Z,width:"2504",height:"1996"})))),(0,r.kt)("p",null,"After all the resources reconciled, we can port-forward our local port (e.g. 12345) to the WordPress frontend service port (80) in the cluster:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress svc/wordpress-dev-wordpress-private 12345:80\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kubectl port-forward for wordpress",src:a(86535).Z,width:"2384",height:"234"})),(0,r.kt)("h2",{id:"verify-wordpress-application"},"Verify WordPress Application"),(0,r.kt)("p",null,"Next, we will verify the WordPress site service we just delivered, along with the creation of the RDS instance it depends on. We can start using the WordPress site by accessing the link of local-forwarded port ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:12345"},"(http://localhost:12345)")," we just configured in the browser. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"wordpress site page",src:a(85773).Z,width:"1500",height:"803"})),(0,r.kt)("p",null,"In addition, we can also log in to the cloud service console page to view the RDS instance we just created."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"aws rds instance",src:a(68678).Z,width:"2876",height:"964"}),"\n",(0,r.kt)("img",{alt:"aws rds instance detailed information",src:a(86915).Z,width:"1224",height:"274"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"alicloud rds instance",src:a(34811).Z,width:"1500",height:"748"})))),(0,r.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,r.kt)("p",null,"You can delete the WordPress application and related RDS resources using the following command line. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"AWS",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with aws rds",src:a(37589).Z,width:"2184",height:"730"}))),(0,r.kt)(s.Z,{value:"Alicloud",mdxType:"TabItem"},(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion destroy wordpress with alicloud rds",src:a(75775).Z,width:"1462",height:"776"})))))}m.isMDXComponent=!0},34811:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alicloud-rds-instance-88d560e7fdab77f7d83592ae1ded6866.png"},87103:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-application-with-aws-rds-580915491e85e04d050cf19bbf0f96cd.png"},30263:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-wordpress-application-b757aedd0d5513207e0bd65019d7a4c2.png"},24838:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"},86915:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-rds-instance-detail-e0f1e737f54491f738769b152de96806.png"},68678:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/aws-rds-instance-12f87b94fbc4a76319d8d9d39fd465d2.png"},82605:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/init-wordpress-with-rds-d6c58387ae3d8ce26394e6e2f7402efd.gif"},37589:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-destroy-wordpress-with-aws-rds-304a7051e2646ad78490fb641fe5a776.png"},75775:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-destroy-wordpress-917a4bf29dfb33b39f8b306df03d9f6a.png"},73725:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/set-rds-access-9347ae09377aeb94d9f6d1e5d8688ab5.png"},86535:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-port-forward-2a83514580f7cf81d890841495f9441e.png"},85773:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/595d2708.6fc2fd7a.js b/assets/js/595d2708.6fc2fd7a.js deleted file mode 100644 index f057b536199..00000000000 --- a/assets/js/595d2708.6fc2fd7a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1049],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=d(n),u=r,k=c["".concat(s,".").concat(u)]||c[u]||p[u]||l;return n?a.createElement(k,i(i({ref:t},m),{},{components:n})):a.createElement(k,i({ref:t},m))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},i="container",o={unversionedId:"kusion/reference/modules/catalog-models/internal/container/container",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/container/container",title:"container",description:"Schema Container",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container",slug:"/kusion/reference/modules/catalog-models/internal/container/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"common",permalink:"/docs/kusion/reference/modules/catalog-models/internal/common"},next:{title:"lifecycle",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/"}},s={},d=[{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3}],m={toc:d};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"container"},"container"),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/595d2708.b1d29a11.js b/assets/js/595d2708.b1d29a11.js new file mode 100644 index 00000000000..5fc58535591 --- /dev/null +++ b/assets/js/595d2708.b1d29a11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1049],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=d(n),u=r,k=c["".concat(s,".").concat(u)]||c[u]||p[u]||l;return n?a.createElement(k,i(i({ref:t},m),{},{components:n})):a.createElement(k,i({ref:t},m))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},i="container",o={unversionedId:"kusion/reference/modules/catalog-models/internal/container/container",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/container/container",title:"container",description:"Schema Container",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container",slug:"/kusion/reference/modules/catalog-models/internal/container/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"common",permalink:"/docs/kusion/reference/modules/catalog-models/internal/common"},next:{title:"lifecycle",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/"}},s={},d=[{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3}],m={toc:d};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"container"},"container"),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5ad344a5.6fa21c2b.js b/assets/js/5ad344a5.2e48a8bf.js similarity index 54% rename from assets/js/5ad344a5.6fa21c2b.js rename to assets/js/5ad344a5.2e48a8bf.js index 4f0352f8267..0d9630c343f 100644 --- a/assets/js/5ad344a5.6fa21c2b.js +++ b/assets/js/5ad344a5.2e48a8bf.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5203],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>k});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var u=r.createContext({}),l=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},c=function(e){var n=l(e.components);return r.createElement(u.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),f=l(t),k=o,d=f["".concat(u,".").concat(k)]||f[k]||p[k]||i;return t?r.createElement(d,s(s({ref:n},c),{},{components:t})):r.createElement(d,s({ref:n},c))}));function k(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=f;var a={};for(var u in n)hasOwnProperty.call(n,u)&&(a[u]=n[u]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var l=2;l{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const i={},s="Kusion Commands",a={unversionedId:"kusion/reference/cli/kusion/index",id:"version-v0.9/kusion/reference/cli/kusion/index",title:"Kusion Commands",description:"Kusion is the platform engineering engine of KusionStack",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/index.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/",permalink:"/docs/v0.9/kusion/reference/cli/kusion/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/index.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Command Line Tools",permalink:"/docs/v0.9/kusion/reference/cli/"},next:{title:"kusion apply",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply"}},u={},l=[{value:"Synopsis",id:"synopsis",level:2},{value:"Options",id:"options",level:2},{value:"SEE ALSO",id:"see-also",level:2},{value:"Auto generated by spf13/cobra on 15-Jul-2023",id:"auto-generated-by-spf13cobra-on-15-jul-2023",level:6}],c={toc:l};function p(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-commands"},"Kusion Commands"),(0,o.kt)("p",null,"Kusion is the platform engineering engine of KusionStack"),(0,o.kt)("h2",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Kusion is the platform engineering engine of KusionStack. It delivers intentions to Kubernetes, Clouds, and On-Premise resources."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion [flags]\n")),(0,o.kt)("h2",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for kusion\n")),(0,o.kt)("h2",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply"},"kusion apply"),"\t - Apply the operation intents of various resources to multiple runtimes"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile"},"kusion compile"),"\t - Compile KCL into YAML"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy"},"kusion destroy"),"\t - Delete the specified resources in runtime"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init"},"kusion init"),"\t - Initialize the scaffolding for a project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview"},"kusion preview"),"\t - Preview a series of resource changes within the stack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version"},"kusion version"),"\t - Print the Kusion version information for the current context")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-15-jul-2023"},"Auto generated by spf13/cobra on 15-Jul-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5203],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>k});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var u=r.createContext({}),l=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},c=function(e){var n=l(e.components);return r.createElement(u.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),f=l(t),k=o,d=f["".concat(u,".").concat(k)]||f[k]||p[k]||i;return t?r.createElement(d,s(s({ref:n},c),{},{components:t})):r.createElement(d,s({ref:n},c))}));function k(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=f;var a={};for(var u in n)hasOwnProperty.call(n,u)&&(a[u]=n[u]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var l=2;l{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const i={},s="Kusion Commands",a={unversionedId:"kusion/reference/cli/kusion/index",id:"version-v0.9/kusion/reference/cli/kusion/index",title:"Kusion Commands",description:"Kusion is the platform engineering engine of KusionStack",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/index.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/",permalink:"/docs/v0.9/kusion/reference/cli/kusion/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/index.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Command Line Tools",permalink:"/docs/v0.9/kusion/reference/cli/"},next:{title:"kusion apply",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply"}},u={},l=[{value:"Synopsis",id:"synopsis",level:2},{value:"Options",id:"options",level:2},{value:"SEE ALSO",id:"see-also",level:2},{value:"Auto generated by spf13/cobra on 15-Jul-2023",id:"auto-generated-by-spf13cobra-on-15-jul-2023",level:6}],c={toc:l};function p(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-commands"},"Kusion Commands"),(0,o.kt)("p",null,"Kusion is the platform engineering engine of KusionStack"),(0,o.kt)("h2",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Kusion is the platform engineering engine of KusionStack. It delivers intentions to Kubernetes, Clouds, and On-Premise resources."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion [flags]\n")),(0,o.kt)("h2",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for kusion\n")),(0,o.kt)("h2",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply"},"kusion apply"),"\t - Apply the operation intents of various resources to multiple runtimes"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile"},"kusion compile"),"\t - Compile KCL into YAML"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy"},"kusion destroy"),"\t - Delete the specified resources in runtime"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init"},"kusion init"),"\t - Initialize the scaffolding for a project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview"},"kusion preview"),"\t - Preview a series of resource changes within the stack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version"},"kusion version"),"\t - Print the Kusion version information for the current context")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-15-jul-2023"},"Auto generated by spf13/cobra on 15-Jul-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5b1b6e2c.2a2121dd.js b/assets/js/5b1b6e2c.2a2121dd.js new file mode 100644 index 00000000000..ce1743242b2 --- /dev/null +++ b/assets/js/5b1b6e2c.2a2121dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3752],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),f=p(n),m=i,d=f["".concat(l,".").concat(m)]||f[m]||u[m]||o;return n?r.createElement(d,a(a({ref:t},c),{},{components:n})):r.createElement(d,a({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion init",s={unversionedId:"kusion/reference/commands/kusion-init",id:"kusion/reference/commands/kusion-init",title:"kusion init",description:"Initialize the scaffolding for a project",source:"@site/docs/kusion/6-reference/1-commands/kusion-init.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-init",permalink:"/docs/next/kusion/reference/commands/kusion-init",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-init.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion destroy",permalink:"/docs/next/kusion/reference/commands/kusion-destroy"},next:{title:"kusion preview",permalink:"/docs/next/kusion/reference/commands/kusion-preview"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-init"},"kusion init"),(0,i.kt)("p",null,"Initialize the scaffolding for a project"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"This command initializes the scaffolding for a project, generating a project from an appointed template with correct structure."),(0,i.kt)("p",null," The scaffold templates can be retrieved from local or online. The built-in templates are used by default, self-defined templates are also supported by assigning the template repository path."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion init\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," # Initialize a project from internal templates\n kusion init\n \n # Initialize a project from default online templates\n kusion init --online=true\n \n # Initialize a project from a specific online template\n kusion init https://github.com// --online=true\n \n # Initialize a project from a specific local template\n kusion init /path/to/templates\n")),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," --custom-params string Custom params in JSON. If specified, it will be used as the template default value and skip prompts\n --force Force generating the scaffolding files, even if it would change the existing files\n -h, --help help for init\n --online Use templates from online repository to initialize project, or use locally cached templates\n --project-name string Initialize with specified project name. If not specified, a prompt will request it\n --template-name string Initialize with specified template. If not specified, a prompt will request it\n --yes Skip prompts and proceed with default values\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5b1b6e2c.b8eb5e1e.js b/assets/js/5b1b6e2c.b8eb5e1e.js deleted file mode 100644 index 3b01d4163fe..00000000000 --- a/assets/js/5b1b6e2c.b8eb5e1e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3752],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),f=p(n),m=i,d=f["".concat(l,".").concat(m)]||f[m]||u[m]||o;return n?r.createElement(d,a(a({ref:t},c),{},{components:n})):r.createElement(d,a({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion init",s={unversionedId:"kusion/reference/commands/kusion-init",id:"kusion/reference/commands/kusion-init",title:"kusion init",description:"Initialize the scaffolding for a project",source:"@site/docs/kusion/6-reference/1-commands/kusion-init.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-init",permalink:"/docs/next/kusion/reference/commands/kusion-init",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-init.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion destroy",permalink:"/docs/next/kusion/reference/commands/kusion-destroy"},next:{title:"kusion preview",permalink:"/docs/next/kusion/reference/commands/kusion-preview"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-init"},"kusion init"),(0,i.kt)("p",null,"Initialize the scaffolding for a project"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"This command initializes the scaffolding for a project, generating a project from an appointed template with correct structure."),(0,i.kt)("p",null," The scaffold templates can be retrieved from local or online. The built-in templates are used by default, self-defined templates are also supported by assigning the template repository path."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion init\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," # Initialize a project from internal templates\n kusion init\n \n # Initialize a project from default online templates\n kusion init --online=true\n \n # Initialize a project from a specific online template\n kusion init https://github.com// --online=true\n \n # Initialize a project from a specific local template\n kusion init /path/to/templates\n")),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," --custom-params string Custom params in JSON. If specified, it will be used as the template default value and skip prompts\n --force Force generating the scaffolding files, even if it would change the existing files\n -h, --help help for init\n --online Use templates from online repository to initialize project, or use locally cached templates\n --project-name string Initialize with specified project name. If not specified, a prompt will request it\n --template-name string Initialize with specified template. If not specified, a prompt will request it\n --yes Skip prompts and proceed with default values\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5ea39018.20823a8f.js b/assets/js/5ea39018.92e4ec51.js similarity index 50% rename from assets/js/5ea39018.20823a8f.js rename to assets/js/5ea39018.92e4ec51.js index ef2ccf938f8..a82fd61243e 100644 --- a/assets/js/5ea39018.20823a8f.js +++ b/assets/js/5ea39018.92e4ec51.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9605],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,b=m["".concat(s,".").concat(u)]||m[u]||d[u]||i;return r?n.createElement(b,a(a({ref:t},c),{},{components:r})):n.createElement(b,a({ref:t},c))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:1},a="Installation",l={unversionedId:"kusion/faq/install-error",id:"version-v0.10/kusion/faq/install-error",title:"Installation",description:"1. Could not find libintl.dylib",source:"@site/versioned_docs/version-v0.10/kusion/7-faq/1-install-error.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/install-error",permalink:"/docs/kusion/faq/install-error",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/7-faq/1-install-error.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Roadmap",permalink:"/docs/kusion/reference/roadmap"},next:{title:"KCL",permalink:"/docs/kusion/faq/kcl"}},s={},p=[{value:"1. Could not find libintl.dylib",id:"1-could-not-find-libintldylib",level:2},{value:"2. macOS system SSL related errors",id:"2-macos-system-ssl-related-errors",level:2}],c={toc:p};function d(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installation"},"Installation"),(0,o.kt)("h2",{id:"1-could-not-find-libintldylib"},"1. Could not find ",(0,o.kt)("inlineCode",{parentName:"h2"},"libintl.dylib")),(0,o.kt)("p",null,"This problem is that some tools depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"Gettext")," library, but macOS does not have this library by default. You can try to solve it in the following ways:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"brew install gettext")),(0,o.kt)("li",{parentName:"ol"},"Make sure ",(0,o.kt)("inlineCode",{parentName:"li"},"libintl.8.dylib")," exists in ",(0,o.kt)("inlineCode",{parentName:"li"},"/usr/local/opt/gettext/lib")," directory"),(0,o.kt)("li",{parentName:"ol"},"If brew is installed in another directory, the library can be created by copying it to the corresponding directory")),(0,o.kt)("h2",{id:"2-macos-system-ssl-related-errors"},"2. macOS system SSL related errors"),(0,o.kt)("p",null,"Openssl dylib library not found or SSL module is not available problem"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Install openssl (version 1.1) via brew")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"brew install openssl@1.1\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9605],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,b=m["".concat(s,".").concat(u)]||m[u]||d[u]||i;return r?n.createElement(b,a(a({ref:t},c),{},{components:r})):n.createElement(b,a({ref:t},c))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:1},a="Installation",l={unversionedId:"kusion/faq/install-error",id:"version-v0.10/kusion/faq/install-error",title:"Installation",description:"1. Could not find libintl.dylib",source:"@site/versioned_docs/version-v0.10/kusion/7-faq/1-install-error.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/install-error",permalink:"/docs/kusion/faq/install-error",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/7-faq/1-install-error.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Roadmap",permalink:"/docs/kusion/reference/roadmap"},next:{title:"KCL",permalink:"/docs/kusion/faq/kcl"}},s={},p=[{value:"1. Could not find libintl.dylib",id:"1-could-not-find-libintldylib",level:2},{value:"2. macOS system SSL related errors",id:"2-macos-system-ssl-related-errors",level:2}],c={toc:p};function d(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installation"},"Installation"),(0,o.kt)("h2",{id:"1-could-not-find-libintldylib"},"1. Could not find ",(0,o.kt)("inlineCode",{parentName:"h2"},"libintl.dylib")),(0,o.kt)("p",null,"This problem is that some tools depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"Gettext")," library, but macOS does not have this library by default. You can try to solve it in the following ways:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"brew install gettext")),(0,o.kt)("li",{parentName:"ol"},"Make sure ",(0,o.kt)("inlineCode",{parentName:"li"},"libintl.8.dylib")," exists in ",(0,o.kt)("inlineCode",{parentName:"li"},"/usr/local/opt/gettext/lib")," directory"),(0,o.kt)("li",{parentName:"ol"},"If brew is installed in another directory, the library can be created by copying it to the corresponding directory")),(0,o.kt)("h2",{id:"2-macos-system-ssl-related-errors"},"2. macOS system SSL related errors"),(0,o.kt)("p",null,"Openssl dylib library not found or SSL module is not available problem"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Install openssl (version 1.1) via brew")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"brew install openssl@1.1\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5ec8c180.a1e9f0a7.js b/assets/js/5ec8c180.a1e9f0a7.js new file mode 100644 index 00000000000..0220d8c9462 --- /dev/null +++ b/assets/js/5ec8c180.a1e9f0a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8828],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="Service",o={unversionedId:"kusion/reference/model/catalog_models/workload/doc_service",id:"version-v0.9/kusion/reference/model/catalog_models/workload/doc_service",title:"Service",description:"Schemas",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_service.md",sourceDirName:"kusion/reference/model/catalog_models/workload",slug:"/kusion/reference/model/catalog_models/workload/doc_service",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_service.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Job",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job"},next:{title:"database",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Service",id:"schema-service",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3},{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes-9",level:3},{value:"Examples",id:"examples-9",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"service"},"Service"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-service"},"Service"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-port"},"Port"))))),(0,r.kt)("h2",{id:"schema-service"},"Schema Service"),(0,r.kt)("p",null,"Service is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),'is typically used for long-running web applications that should "never" go down, and handle',(0,r.kt)("br",null),"short-lived latency-sensitive web requests, or events."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"ports"),(0,r.kt)("br",null),"The list of ports of the Service should get exposed."),(0,r.kt)("td",{parentName:"tr",align:null},"[",(0,r.kt)("a",{parentName:"td",href:"#schema-port"},"network.Port"),"]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,r.kt)("br",null),"types, including Deployment and CollaSet."),(0,r.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nsvc = wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9090\n }\n ]\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')),(0,r.kt)("h2",{id:"schema-port"},"Schema Port"),(0,r.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,r.kt)("br",null),"get accessed."),(0,r.kt)("h3",{id:"attributes-9"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"port"),(0,r.kt)("br",null),"The exposed port of the Service."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"80"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"protocol"),(0,r.kt)("br",null),"The protocol to access the port."),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"public"),(0,r.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"False"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"targetPort"),(0,r.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-9"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5ee164ec.4263c688.js b/assets/js/5ee164ec.4263c688.js new file mode 100644 index 00000000000..41007f60eee --- /dev/null +++ b/assets/js/5ee164ec.4263c688.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2152],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var i=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=p(n),m=o,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||r;return n?i.createElement(f,a(a({ref:t},u),{},{components:n})):i.createElement(f,a({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,a=new Array(r);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var i=n(87462),o=(n(67294),n(3905));const r={sidebar_position:3},a="How Kusion Works",s={unversionedId:"kusion/concepts/kusion",id:"version-v0.9/kusion/concepts/kusion",title:"How Kusion Works",description:"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Models defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/kusion.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/kusion",permalink:"/docs/v0.9/kusion/concepts/kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/kusion.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"kusion",previous:{title:"Glossary",permalink:"/docs/v0.9/kusion/concepts/glossary"},next:{title:"AppConfiguration",permalink:"/docs/v0.9/kusion/concepts/appconfiguration"}},l={},p=[{value:"Operation Engine",id:"operation-engine",level:2},{value:"Runtimes",id:"runtimes",level:2},{value:"State",id:"state",level:2},{value:"How Kusion works",id:"how-kusion-works-1",level:2}],u={toc:p};function c(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-kusion-works"},"How Kusion Works"),(0,o.kt)("p",null,"Kusion is the platform engineering engine of ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack"},"KusionStack"),". It delivers intentions described with Kusion Models defined in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," to Kubernetes, Clouds and On-Prem infrastructures."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/arch.png",width:"50%",height:"50%"})),(0,o.kt)("p",null," It consists of 3 parts: ",(0,o.kt)("inlineCode",{parentName:"p"},"Operation Engine"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Runtimes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"State"),", we will describe each of these components below."),(0,o.kt)("h2",{id:"operation-engine"},"Operation Engine"),(0,o.kt)("p",null,"Operation Engine is the entry point of the Kusion Engine and is responsible for Kusion basic operations like ",(0,o.kt)("inlineCode",{parentName:"p"},"preview"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"apply"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"destroy"),", etc. The main workflow of this part is to parse resources described in the operation intention (Spec), figure out which resource should be modified according to the specified operation, and execute this operation to the real infra resources. During this workflow, Runtimes and State will be involved."),(0,o.kt)("h2",{id:"runtimes"},"Runtimes"),(0,o.kt)("p",null,"Runtime is an interface between the actual infrastructure and Kusion. All operations attempting to manipulate an infra resource should be delegated to one Runtime to make this operation affect the actual infrastructure. On the other hand, any infrastructure that implements the Runtime interfaces can be managed by Kusion."),(0,o.kt)("h2",{id:"state"},"State"),(0,o.kt)("p",null,"State is a record of an operation's result. It is a mapping between resources managed by Kusion and the actual infra resources. State is often used as a data source for 3-way merge/diff in operations like ",(0,o.kt)("inlineCode",{parentName:"p"},"apply")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"preview"),"."),(0,o.kt)("p",null,"State can be stored in many storage mediums like filesystems, OSS, databases, HTTP servers, etc."),(0,o.kt)("h2",{id:"how-kusion-works-1"},"How Kusion works"),(0,o.kt)("p",null,"Let's get operation ",(0,o.kt)("inlineCode",{parentName:"p"},"Preview")," as an example to demonstrate how the three parts cooperate in an actual operation."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"Operation Engine")," parses resources in operation intentions(Spec) and converts them into a DAG"),(0,o.kt)("li",{parentName:"ol"},"Walk this DAG:",(0,o.kt)("ol",{parentName:"li"},(0,o.kt)("li",{parentName:"ol"},"Get the latest ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," from the actual infra by the ",(0,o.kt)("inlineCode",{parentName:"li"},"Runtime")),(0,o.kt)("li",{parentName:"ol"},"Get the last operation ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," from the ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," storage medium"))),(0,o.kt)("li",{parentName:"ol"},"Merge/Diff three states: desired state described in Spec, live state from ",(0,o.kt)("inlineCode",{parentName:"li"},"Runtime")," and prior state from ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," storage medium, and return the diff result to the console.")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5ee164ec.7fe6e530.js b/assets/js/5ee164ec.7fe6e530.js deleted file mode 100644 index e6197d63ac5..00000000000 --- a/assets/js/5ee164ec.7fe6e530.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2152],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var i=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=p(n),m=o,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||r;return n?i.createElement(f,a(a({ref:t},u),{},{components:n})):i.createElement(f,a({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,a=new Array(r);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var i=n(87462),o=(n(67294),n(3905));const r={sidebar_position:3},a="How Kusion Works",s={unversionedId:"kusion/concepts/kusion",id:"version-v0.9/kusion/concepts/kusion",title:"How Kusion Works",description:"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Models defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/kusion.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/kusion",permalink:"/docs/v0.9/kusion/concepts/kusion",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/kusion.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"kusion",previous:{title:"Glossary",permalink:"/docs/v0.9/kusion/concepts/glossary"},next:{title:"AppConfiguration",permalink:"/docs/v0.9/kusion/concepts/appconfiguration"}},l={},p=[{value:"Operation Engine",id:"operation-engine",level:2},{value:"Runtimes",id:"runtimes",level:2},{value:"State",id:"state",level:2},{value:"How Kusion works",id:"how-kusion-works-1",level:2}],u={toc:p};function c(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-kusion-works"},"How Kusion Works"),(0,o.kt)("p",null,"Kusion is the platform engineering engine of ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack"},"KusionStack"),". It delivers intentions described with Kusion Models defined in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," to Kubernetes, Clouds and On-Prem infrastructures."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/arch.png",width:"50%",height:"50%"})),(0,o.kt)("p",null," It consists of 3 parts: ",(0,o.kt)("inlineCode",{parentName:"p"},"Operation Engine"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Runtimes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"State"),", we will describe each of these components below."),(0,o.kt)("h2",{id:"operation-engine"},"Operation Engine"),(0,o.kt)("p",null,"Operation Engine is the entry point of the Kusion Engine and is responsible for Kusion basic operations like ",(0,o.kt)("inlineCode",{parentName:"p"},"preview"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"apply"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"destroy"),", etc. The main workflow of this part is to parse resources described in the operation intention (Spec), figure out which resource should be modified according to the specified operation, and execute this operation to the real infra resources. During this workflow, Runtimes and State will be involved."),(0,o.kt)("h2",{id:"runtimes"},"Runtimes"),(0,o.kt)("p",null,"Runtime is an interface between the actual infrastructure and Kusion. All operations attempting to manipulate an infra resource should be delegated to one Runtime to make this operation affect the actual infrastructure. On the other hand, any infrastructure that implements the Runtime interfaces can be managed by Kusion."),(0,o.kt)("h2",{id:"state"},"State"),(0,o.kt)("p",null,"State is a record of an operation's result. It is a mapping between resources managed by Kusion and the actual infra resources. State is often used as a data source for 3-way merge/diff in operations like ",(0,o.kt)("inlineCode",{parentName:"p"},"apply")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"preview"),"."),(0,o.kt)("p",null,"State can be stored in many storage mediums like filesystems, OSS, databases, HTTP servers, etc."),(0,o.kt)("h2",{id:"how-kusion-works-1"},"How Kusion works"),(0,o.kt)("p",null,"Let's get operation ",(0,o.kt)("inlineCode",{parentName:"p"},"Preview")," as an example to demonstrate how the three parts cooperate in an actual operation."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"Operation Engine")," parses resources in operation intentions(Spec) and converts them into a DAG"),(0,o.kt)("li",{parentName:"ol"},"Walk this DAG:",(0,o.kt)("ol",{parentName:"li"},(0,o.kt)("li",{parentName:"ol"},"Get the latest ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," from the actual infra by the ",(0,o.kt)("inlineCode",{parentName:"li"},"Runtime")),(0,o.kt)("li",{parentName:"ol"},"Get the last operation ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," from the ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," storage medium"))),(0,o.kt)("li",{parentName:"ol"},"Merge/Diff three states: desired state described in Spec, live state from ",(0,o.kt)("inlineCode",{parentName:"li"},"Runtime")," and prior state from ",(0,o.kt)("inlineCode",{parentName:"li"},"State")," storage medium, and return the diff result to the console.")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5f456afb.271ca9f7.js b/assets/js/5f456afb.271ca9f7.js new file mode 100644 index 00000000000..2fe3ff56083 --- /dev/null +++ b/assets/js/5f456afb.271ca9f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2653],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return n?a.createElement(k,i(i({ref:t},d),{},{components:n})):a.createElement(k,i({ref:t},d))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=n(87462),o=(n(67294),n(3905));const r={id:"deliver-wordpress"},i="Deliver the WordPress Application on Kubernetes",l={unversionedId:"kusion/getting-started/deliver-wordpress",id:"kusion/getting-started/deliver-wordpress",title:"Deliver the WordPress Application on Kubernetes",description:"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.",source:"@site/docs/kusion/2-getting-started/2-deliver-wordpress.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/deliver-wordpress",permalink:"/docs/next/kusion/getting-started/deliver-wordpress",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/2-getting-started/2-deliver-wordpress.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"deliver-wordpress"},sidebar:"kusion",previous:{title:"Install Kusion",permalink:"/docs/next/kusion/getting-started/install-kusion"},next:{title:"Overview",permalink:"/docs/next/kusion/concepts/project/overview"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"deliver-the-wordpress-application-on-kubernetes"},"Deliver the WordPress Application on Kubernetes"),(0,o.kt)("p",null,"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion. "),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Before we start to play with this example, we need to have the Kusion CLI installed and run a Kubernetes cluster. Here are some helpful documentations: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/getting-started/install-kusion"},"Kusion")," CLI"),(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," CLI and run a ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," cluster. Some light and convenient options for local deployment include ",(0,o.kt)("a",{parentName:"li",href:"https://docs.k3s.io/quick-start"},"k3s"),", ",(0,o.kt)("a",{parentName:"li",href:"https://k3d.io/v5.4.4/#installation"},"k3d"),", and ",(0,o.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"MiniKube"),". ")),(0,o.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,o.kt)("p",null,"To deploy the WordPress application, we need to first initiate a ",(0,o.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (we are using ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," here). Please copy the following example YAML file to your local ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# example workspace configs for local mysql database\nruntimes: \n kubernetes: \n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n\nmodules: \n mysql: \n default: \n suffix: "-mysql" # The suffix of the MySQL database name\n')),(0,o.kt)("p",null,"You can replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," and execute the following command line to initiate the workspace configuration for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,o.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,o.kt)("inlineCode",{parentName:"p"},"Kubernetes")," runtime config and ",(0,o.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,o.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,o.kt)("h2",{id:"init-project"},"Init Project"),(0,o.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,o.kt)("p",null,"All init templates are listed as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-local-db A sample wordpress project with local database\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-local-db\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-local-db'\n")),(0,o.kt)("p",null,"Please select ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db")," and press ",(0,o.kt)("inlineCode",{parentName:"p"},"Enter"),", after which we will see the hints below and use the default values to configure this project and stack. "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(63617).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"The directory structure looks like the following: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-local-db/dev && tree\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-local-db/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/project/overview"},"Project")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/stack/overview"},"Stack"),". ")),(0,o.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,o.kt)("p",null,"Now let's have a glance at the configuration file of ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),": "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stack.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n')),(0,o.kt)("p",null,"The configuration file ",(0,o.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,o.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,o.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a local ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,o.kt)("inlineCode",{parentName:"p"},"8.0")," for the application. The necessary Kubernetes resources for deploying and using the local database will be generated, and users can get the ",(0,o.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"paasword")," of the database through the ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,o.kt)("p",null,"This model hides the major complexity of Kubernetes resources such as ",(0,o.kt)("inlineCode",{parentName:"p"},"Namespace"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),", providing the concepts that are application-centric and infrastructure-agnostic. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the Models can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,o.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,o.kt)("p",null,"We will deliver the WordPress application in the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db/dev")," folder into the Kubernetes cluster with one command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion apply --watch"),". "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(41809).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"Check ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," status. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n wordpress-local-db get deployment\n")),(0,o.kt)("p",null,"The expected output is shown as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl -n wordpress-local-db get deployment\nNAME READY UP-TO-DATE AVAILABLE AGE\nwordpress-local-db-dev-wordpress 1/1 1 1 2m56s\nwordpress-mysql 1/1 1 1 2m56s\n")),(0,o.kt)("p",null,"In the above two resources, ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db-dev-wordpress")," corresponds to the Kubernetes ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the WordPress application, while ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-mysql")," corresponds to the ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the local MySQL database. "),(0,o.kt)("p",null,"Port-forward our WordPress with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\nForwarding from 127.0.0.1:12345 -> 80\nForwarding from [::1]:12345 -> 80\n\n")),(0,o.kt)("p",null,"Now we can visit ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:12345"},"http://localhost:12345")," in our browser and enjoy!"),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(85773).Z,width:"1500",height:"803"})),(0,o.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,o.kt)("p",null,"We can delete the WordPress application and related database resources using the following command line: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(21192).Z,width:"2560",height:"1440"})))}c.isMDXComponent=!0},41809:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/apply-wordpress-local-db-6a391cbf9576c88494710eb17f8c8396.gif"},21192:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/destroy-wordpress-local-db-93038beed84dadd31cbefdbbfb632ee1.gif"},63617:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/init-wordpress-local-db-34d0778e8b48028ad7a1394543a1dfb2.gif"},85773:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/5f456afb.d7c709c3.js b/assets/js/5f456afb.d7c709c3.js deleted file mode 100644 index ba1013a0791..00000000000 --- a/assets/js/5f456afb.d7c709c3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2653],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return n?a.createElement(k,i(i({ref:t},d),{},{components:n})):a.createElement(k,i({ref:t},d))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=n(87462),o=(n(67294),n(3905));const r={id:"deliver-wordpress"},i="Deliver the WordPress Application on Kubernetes",l={unversionedId:"kusion/getting-started/deliver-wordpress",id:"kusion/getting-started/deliver-wordpress",title:"Deliver the WordPress Application on Kubernetes",description:"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.",source:"@site/docs/kusion/2-getting-started/2-deliver-wordpress.md",sourceDirName:"kusion/2-getting-started",slug:"/kusion/getting-started/deliver-wordpress",permalink:"/docs/next/kusion/getting-started/deliver-wordpress",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/2-getting-started/2-deliver-wordpress.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"deliver-wordpress"},sidebar:"kusion",previous:{title:"Install Kusion",permalink:"/docs/next/kusion/getting-started/install-kusion"},next:{title:"Overview",permalink:"/docs/next/kusion/concepts/project/overview"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Init Workspace",id:"init-workspace",level:2},{value:"Init Project",id:"init-project",level:2},{value:"Review Configuration Files",id:"review-configuration-files",level:3},{value:"Application Delivery",id:"application-delivery",level:2},{value:"Delete WordPress Application",id:"delete-wordpress-application",level:2}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"deliver-the-wordpress-application-on-kubernetes"},"Deliver the WordPress Application on Kubernetes"),(0,o.kt)("p",null,"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion. "),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Before we start to play with this example, we need to have the Kusion CLI installed and run a Kubernetes cluster. Here are some helpful documentations: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/getting-started/install-kusion"},"Kusion")," CLI"),(0,o.kt)("li",{parentName:"ul"},"Install ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/tools/#kubectl"},"kubectl")," CLI and run a ",(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/"},"Kubernetes")," cluster. Some light and convenient options for local deployment include ",(0,o.kt)("a",{parentName:"li",href:"https://docs.k3s.io/quick-start"},"k3s"),", ",(0,o.kt)("a",{parentName:"li",href:"https://k3d.io/v5.4.4/#installation"},"k3d"),", and ",(0,o.kt)("a",{parentName:"li",href:"https://minikube.sigs.k8s.io/docs/tutorials/multi_node/"},"MiniKube"),". ")),(0,o.kt)("h2",{id:"init-workspace"},"Init Workspace"),(0,o.kt)("p",null,"To deploy the WordPress application, we need to first initiate a ",(0,o.kt)("inlineCode",{parentName:"p"},"Workspace")," for the targeted stack (we are using ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," here). Please copy the following example YAML file to your local ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),". "),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# example workspace configs for local mysql database\nruntimes: \n kubernetes: \n kubeConfig: /etc/kubeconfig.yaml # Please replace with your own kubeconfig file path\n\nmodules: \n mysql: \n default: \n suffix: "-mysql" # The suffix of the MySQL database name\n')),(0,o.kt)("p",null,"You can replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes.kubernetes.kubeConfig")," field with your own kubeconfig file path in ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," and execute the following command line to initiate the workspace configuration for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace create dev -f workspace.yaml\n")),(0,o.kt)("p",null,"You can use the following command lines to list and show the workspace configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion workspace list\n\nkusion workspace show dev\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," is a sample configuration file for workspace management, including ",(0,o.kt)("inlineCode",{parentName:"p"},"Kubernetes")," runtime config and ",(0,o.kt)("inlineCode",{parentName:"p"},"MySQL")," module config. Workspace configurations are usually declared by ",(0,o.kt)("strong",{parentName:"p"},"Platform Engineers")," and will take effect through the corresponding stack. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the configuration of Workspace can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/workspace_management/workspace_management.md"},"Workspace Management"),". ")),(0,o.kt)("h2",{id:"init-project"},"Init Project"),(0,o.kt)("p",null,"We can start by initializing this tutorial project with online templates: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion init --online\n")),(0,o.kt)("p",null,"All init templates are listed as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground kusion init --online\n? Please choose a template: wordpress-local-db A sample wordpress project with local database\nThis command will walk you through creating a new kusion project.\n\nEnter a value or leave blank to accept the (default), and press .\nPress ^C at any time to quit.\n\nProject Config:\n? ProjectName: wordpress-local-db\n? AppName: wordpress\nStack Config: dev\n? Image: wordpress:6.3\nCreated project 'wordpress-local-db'\n")),(0,o.kt)("p",null,"Please select ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db")," and press ",(0,o.kt)("inlineCode",{parentName:"p"},"Enter"),", after which we will see the hints below and use the default values to configure this project and stack. "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(63617).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"The directory structure looks like the following: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"cd wordpress-local-db/dev && tree\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c kusion_playground cd wordpress-local-db/dev && tree\n.\n\u251c\u2500\u2500 kcl.mod\n\u251c\u2500\u2500 main.k\n\u2514\u2500\u2500 stack.yaml\n\n1 directory, 3 files\n")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the directory structure can be found in ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/project/overview"},"Project")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/stack/overview"},"Stack"),". ")),(0,o.kt)("h3",{id:"review-configuration-files"},"Review Configuration Files"),(0,o.kt)("p",null,"Now let's have a glance at the configuration file of ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),": "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stack.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n database: {\n wordpress: mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n')),(0,o.kt)("p",null,"The configuration file ",(0,o.kt)("inlineCode",{parentName:"p"},"main.k"),", usually written by the ",(0,o.kt)("strong",{parentName:"p"},"App Developers"),", declares customized configurations for ",(0,o.kt)("inlineCode",{parentName:"p"},"dev")," stack, which includes an ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," with the name of ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress"),". And the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress")," application includes a workload of type ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.Service"),", which runs on 1 replica and exposes ",(0,o.kt)("inlineCode",{parentName:"p"},"80")," port to be accessed. Besides, it declares a local ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql.MySQL")," as the database accessory with the engine version of ",(0,o.kt)("inlineCode",{parentName:"p"},"8.0")," for the application. The necessary Kubernetes resources for deploying and using the local database will be generated, and users can get the ",(0,o.kt)("inlineCode",{parentName:"p"},"host"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"username")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"paasword")," of the database through the ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," of Kusion in application containers. "),(0,o.kt)("p",null,"This model hides the major complexity of Kubernetes resources such as ",(0,o.kt)("inlineCode",{parentName:"p"},"Namespace"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),", providing the concepts that are application-centric and infrastructure-agnostic. "),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the Models can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog"))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The collaboration paradigm between App Developers and Platform Engineers with Kusion can be found in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/design/collaboration/collaboration_paradigm.md"},"Collaboration Paradigm"))),(0,o.kt)("h2",{id:"application-delivery"},"Application Delivery"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --watch\n")),(0,o.kt)("p",null,"We will deliver the WordPress application in the ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db/dev")," folder into the Kubernetes cluster with one command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion apply --watch"),". "),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(41809).Z,width:"2560",height:"1440"})),(0,o.kt)("p",null,"Check ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," status. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n wordpress-local-db get deployment\n")),(0,o.kt)("p",null,"The expected output is shown as follows: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl -n wordpress-local-db get deployment\nNAME READY UP-TO-DATE AVAILABLE AGE\nwordpress-local-db-dev-wordpress 1/1 1 1 2m56s\nwordpress-mysql 1/1 1 1 2m56s\n")),(0,o.kt)("p",null,"In the above two resources, ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-local-db-dev-wordpress")," corresponds to the Kubernetes ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the WordPress application, while ",(0,o.kt)("inlineCode",{parentName:"p"},"wordpress-mysql")," corresponds to the ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," of the local MySQL database. "),(0,o.kt)("p",null,"Port-forward our WordPress with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Service"),". "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"\u279c dev kubectl port-forward -n wordpress-local-db service/wordpress-local-db-dev-wordpress-private 12345:80\nForwarding from 127.0.0.1:12345 -> 80\nForwarding from [::1]:12345 -> 80\n\n")),(0,o.kt)("p",null,"Now we can visit ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:12345"},"http://localhost:12345")," in our browser and enjoy!"),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(85773).Z,width:"1500",height:"803"})),(0,o.kt)("h2",{id:"delete-wordpress-application"},"Delete WordPress Application"),(0,o.kt)("p",null,"We can delete the WordPress application and related database resources using the following command line: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --yes\n")),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(21192).Z,width:"2560",height:"1440"})))}c.isMDXComponent=!0},41809:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/apply-wordpress-local-db-6a391cbf9576c88494710eb17f8c8396.gif"},21192:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/destroy-wordpress-local-db-93038beed84dadd31cbefdbbfb632ee1.gif"},63617:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/init-wordpress-local-db-34d0778e8b48028ad7a1394543a1dfb2.gif"},85773:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/wordpress-site-page-ef650e640399209d1eec5e6dfe88c454.png"}}]); \ No newline at end of file diff --git a/assets/js/5fff1932.63a9af64.js b/assets/js/5fff1932.63a9af64.js new file mode 100644 index 00000000000..df1f599e77e --- /dev/null +++ b/assets/js/5fff1932.63a9af64.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7206],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),d=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=d(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=r,k=u["".concat(p,".").concat(m)]||u[m]||c[m]||l;return n?a.createElement(k,o(o({ref:t},s),{},{components:n})):a.createElement(k,o({ref:t},s))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=u;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="probe",i={unversionedId:"kusion/reference/modules/catalog-models/internal/container/probe/probe",id:"kusion/reference/modules/catalog-models/internal/container/probe/probe",title:"probe",description:"Schema Probe",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/probe",slug:"/kusion/reference/modules/catalog-models/internal/container/probe/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"lifecycle",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/"},next:{title:"port",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/network/port"}},p={},d=[{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3}],s={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"probe"},"probe"),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5fff1932.64ded398.js b/assets/js/5fff1932.64ded398.js deleted file mode 100644 index 6f3233a7c9c..00000000000 --- a/assets/js/5fff1932.64ded398.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7206],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),d=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=d(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=r,k=u["".concat(p,".").concat(m)]||u[m]||c[m]||l;return n?a.createElement(k,o(o({ref:t},s),{},{components:n})):a.createElement(k,o({ref:t},s))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=u;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="probe",i={unversionedId:"kusion/reference/modules/catalog-models/internal/container/probe/probe",id:"kusion/reference/modules/catalog-models/internal/container/probe/probe",title:"probe",description:"Schema Probe",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/probe",slug:"/kusion/reference/modules/catalog-models/internal/container/probe/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"lifecycle",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/"},next:{title:"port",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/network/port"}},p={},d=[{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3}],s={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"probe"},"probe"),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/600a00a0.06d75661.js b/assets/js/600a00a0.06d75661.js deleted file mode 100644 index b7e90f7abbb..00000000000 --- a/assets/js/600a00a0.06d75661.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5780],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=i,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(k,r(r({ref:t},p),{},{components:n})):a.createElement(k,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var a=n(87462),i=(n(67294),n(3905));const o={id:"overview"},r="Configuration File Overview",l={unversionedId:"kusion/configuration-walkthrough/overview",id:"version-v0.10/kusion/configuration-walkthrough/overview",title:"Configuration File Overview",description:"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/1-overview.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/overview",permalink:"/docs/kusion/configuration-walkthrough/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview"},sidebar:"kusion",previous:{title:"How Kusion Works?",permalink:"/docs/kusion/concepts/how-kusion-works"},next:{title:"KCL Basics",permalink:"/docs/kusion/configuration-walkthrough/kcl-basics"}},s={},c=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Directory Structure",id:"directory-structure",level:2},{value:"AppConfiguration Model",id:"appconfiguration-model",level:2},{value:"Authoring Configuration Files",id:"authoring-configuration-files",level:2},{value:"Identifying KCL file",id:"identifying-kcl-file",level:3},{value:"KCL Packages and Import",id:"kcl-packages-and-import",level:3},{value:"Understanding kcl.mod",id:"understanding-kclmod",level:3},{value:"Building Blocks",id:"building-blocks",level:3},{value:"Instantiating an application",id:"instantiating-an-application",level:3},{value:"Using kusion init",id:"using-kusion-init",level:3},{value:"Using references",id:"using-references",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configuration-file-overview"},"Configuration File Overview"),(0,i.kt)("p",null,"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure."),(0,i.kt)("p",null,"This documentation series walks you through the odds and ends of managing such configuration files."),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#configuration-file-overview"},"Configuration File Overview"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#table-of-content"},"Table of Content")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#directory-structure"},"Directory Structure")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#appconfiguration-model"},"AppConfiguration Model")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#identifying-kcl-file"},"Identifying KCL file")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#kcl-packages-and-import"},"KCL Packages and Import")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#understanding-kclmod"},"Understanding kcl.mod")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#building-blocks"},"Building Blocks")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#instantiating-an-application"},"Instantiating an application")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-kusion-init"},"Using ",(0,i.kt)("inlineCode",{parentName:"a"},"kusion init"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-references"},"Using references"))))))),(0,i.kt)("h2",{id:"directory-structure"},"Directory Structure"),(0,i.kt)("p",null,"Kusion expects the configuration file to be placed in a certain directory structure because it might need some metadata (that is not stored in the application configuration itself) in order to proceed."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"See ",(0,i.kt)("a",{parentName:"p",href:"../concepts/project/overview"},"Project")," and ",(0,i.kt)("a",{parentName:"p",href:"../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,i.kt)("p",null,"A sample multi-stack directory structure looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"~/playground$ tree multi-stack-project/\nmulti-stack-project/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 base\n\u2502\xa0\xa0 \u2514\u2500\u2500 base.k\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u251c\u2500\u2500 prod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n")),(0,i.kt)("p",null,"In general, the directory structure follows a hierarchy where the top-level is the project configurations, and the sub-directories represent stack-level configurations."),(0,i.kt)("p",null,"You may notice there is a ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory besides all the stacks. The ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory is not mandatory, but rather a place to store common configurations between different stacks. A common pattern we observed is to use stacks to represent different stages (dev, stage, prod, etc.) in the software development lifecycle, and/or different deployment targets (azure-eastus, aws-us-east-1, etc). A project can have as many stacks as needed."),(0,i.kt)("p",null,"In practice, the applications deployed into dev and prod might very likely end up with a similar set of configurations except a few fields such as the application image (dev might be on newer versions), resource requirements (prod might require more resources), etc."),(0,i.kt)("p",null,"As a general best practice, we recommend managing the common configurations in ",(0,i.kt)("inlineCode",{parentName:"p"},"base.k")," as much as possible to minimize duplicate code. We will cover how override works in ",(0,i.kt)("a",{parentName:"p",href:"base-override"},"Base and Override"),"."),(0,i.kt)("h2",{id:"appconfiguration-model"},"AppConfiguration Model"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is the out-of-the-box model we build that describes an application. It serves as the declarative intent for a given application."),(0,i.kt)("p",null,"The schema for ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is defined in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," repository. It is designed as a unified, application-centric model that encapsulates the comprehensive configuration details and in the meantime, hides the complexity of the infrastructure as much as possible."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," consists of multiple sub-components that each represent either the application workload itself, its dependencies, relevant workflows or operational expectations. We will deep dive into the details on how to author each of these elements in this upcoming documentation series."),(0,i.kt)("p",null,"For more details on the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", please refer to the ",(0,i.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"design documentation"),"."),(0,i.kt)("h2",{id:"authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open-source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h3",{id:"identifying-kcl-file"},"Identifying KCL file"),(0,i.kt)("p",null,"KCL files are identified with ",(0,i.kt)("inlineCode",{parentName:"p"},".k")," suffix in the filename."),(0,i.kt)("h3",{id:"kcl-packages-and-import"},"KCL Packages and Import"),(0,i.kt)("p",null,"Similar to most modern General Programming Languages (GPLs), KCL packages are used to organize collections of related KCL source files into modular and re-usable units."),(0,i.kt)("p",null,"In the context of Kusion, we use KCL packages to define models that could best abstract the behavior of an application. Specifically, we provide an official out-of-the-box KCL package(will keep iterating) with the name ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog"),". When authoring an application configuration file, you can simply import the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package in the source code and use all the schemas (including AppConfiguration) defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("p",null,"Similarly, if the schemas in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package does not meet your needs, you can always fork it and make modifications, then import the modified package; or create a brand new package altogether and import it."),(0,i.kt)("p",null,"The Kusion ecosystem can be easily expanded in this manner."),(0,i.kt)("p",null,"An example of the import looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"### import from the official catalog package\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\n### import my own modified package\nimport my_own_catalog.models.schema.v1 as moc\nimport my_other_package.schema.v1.redis as myredis\n")),(0,i.kt)("p",null,"Take ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog.models.schema.v1.workload as wl")," as an example, the ",(0,i.kt)("inlineCode",{parentName:"p"},".models.schema.v1.workload")," part after ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog")," represents the relative path of a specific schema to import. In this case, the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas is defined under ",(0,i.kt)("inlineCode",{parentName:"p"},"models/schema/v1/workload")," directory in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("h3",{id:"understanding-kclmod"},"Understanding kcl.mod"),(0,i.kt)("p",null,"Much similar to the concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"go.mod"),", Kusion uses ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," as the source of truth to manage metadata (such as package name, dependencies, etc.) for the current package. Kusion will also auto-generate a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod.lock")," as the dependency lock file."),(0,i.kt)("p",null,"The most common usage for ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," is to manage the dependency of your application configurations. "),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Please note this ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," will be automatically generated if you are using ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," to initialize a project with a template. You will only need to modify this file if you are modifying the project metadata outside the initialization process, such as upgrading the dependency version or adding a new dependency altogether, etc.")),(0,i.kt)("p",null,"There are 3 sections in a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"package"),", representing the metadata for the current package."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"dependencies"),", describing the packages the current package depends on. Supports referencing either a git repository or an OCI artifact."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"profile"),", defining the behavior for Kusion. In the example below, it describes the list of files Kusion should look for when parsing the application configuration.")),(0,i.kt)("p",null,"An example of ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'[package]\nname = "multi-stack-project"\nedition = "0.5.0"\nversion = "0.1.0"\n\n[dependencies]\ncatalog = { git = "https://github.com/KusionStack/catalog.git", tag = "0.1.0" }\n# Uncomment the line below to use your own modified package\n# my-package = ghcr.io/kcl-lang/my-package\n\n[profile]\nentries = ["../base/base.k", "main.k"]\n')),(0,i.kt)("h3",{id:"building-blocks"},"Building Blocks"),(0,i.kt)("p",null,"Configuration files consist of building blocks that are made of instances of schemas. An ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance consists of several child schemas, most of which are optional. The only mandatory one is the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," instance. We will take a closer look in the ",(0,i.kt)("a",{parentName:"p",href:"workload"},"workload walkthrough"),". The order of the building blocks does NOT matter."),(0,i.kt)("p",null,"The major building blocks as of version ",(0,i.kt)("inlineCode",{parentName:"p"},"0.9.0"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n ...\n }\n ports: []\n secrets: {}\n }\n database: d.Database{}\n monitoring: m.Prometheus{}\n opsRule: t.OpsRule {}\n ...\n}\n')),(0,i.kt)("p",null,"We will deep dive into each one of the building blocks in this documentation series."),(0,i.kt)("h3",{id:"instantiating-an-application"},"Instantiating an application"),(0,i.kt)("p",null,"In Kusion's out-of-the-box experience, an application is identified with an instance of ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". You may have more than one application in the same project or stack."),(0,i.kt)("p",null,"Here's an example of a configuration that can be consumed by Kusion (assuming it is placed inside the proper directory structure that includes project and stack configurations, with a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," present):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\ngocity: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "gocity": c.Container {\n image = "howieyuen/gocity:latest"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 4000\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"Don't worry about what ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," stand for at the moment. We will deep dive into each one of them in this upcoming documentation series."),(0,i.kt)("h3",{id:"using-kusion-init"},"Using ",(0,i.kt)("inlineCode",{parentName:"h3"},"kusion init")),(0,i.kt)("p",null,"Kusion offers a ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," sub-command which initializes a new project using some pre-built templates, which saves you from the hassle of manually building the aforementioned directory structure that Kusion expects."),(0,i.kt)("p",null,"There is a built-in template ",(0,i.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," in the Kusion binary that can be used offline. "),(0,i.kt)("p",null,"We also maintain a ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion-templates"},"kusion-templates repository")," that hosts a list of more comprehensive project scaffolds. You can access them via ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init --online")," command which requires connectivity to ",(0,i.kt)("inlineCode",{parentName:"p"},"github.com"),"."),(0,i.kt)("p",null,"The pre-built templates are meant to help you get off the ground quickly with some simple out-of-the-box examples. You can refer to the ",(0,i.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"QuickStart documentation")," for some step-by-step tutorials."),(0,i.kt)("h3",{id:"using-references"},"Using references"),(0,i.kt)("p",null,"The reference documentation for the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package is located in ",(0,i.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/app-configuration"},"Reference"),"."),(0,i.kt)("p",null,"If you are using the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package out of the box, the reference documentation provides a comprehensive view for each schema involved, including all the attribute names and description, their types, default value if any, and whether a particular attribute is required or not. There will also be an example attached to each schema reference."),(0,i.kt)("p",null,"We will also deep dive into some common examples in the upcoming sections."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/600a00a0.19fc5231.js b/assets/js/600a00a0.19fc5231.js new file mode 100644 index 00000000000..639354de55b --- /dev/null +++ b/assets/js/600a00a0.19fc5231.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5780],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=i,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?a.createElement(k,r(r({ref:t},p),{},{components:n})):a.createElement(k,r({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var a=n(87462),i=(n(67294),n(3905));const o={id:"overview"},r="Configuration File Overview",l={unversionedId:"kusion/configuration-walkthrough/overview",id:"version-v0.10/kusion/configuration-walkthrough/overview",title:"Configuration File Overview",description:"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/1-overview.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/overview",permalink:"/docs/kusion/configuration-walkthrough/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview"},sidebar:"kusion",previous:{title:"How Kusion Works?",permalink:"/docs/kusion/concepts/how-kusion-works"},next:{title:"KCL Basics",permalink:"/docs/kusion/configuration-walkthrough/kcl-basics"}},s={},c=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Directory Structure",id:"directory-structure",level:2},{value:"AppConfiguration Model",id:"appconfiguration-model",level:2},{value:"Authoring Configuration Files",id:"authoring-configuration-files",level:2},{value:"Identifying KCL file",id:"identifying-kcl-file",level:3},{value:"KCL Packages and Import",id:"kcl-packages-and-import",level:3},{value:"Understanding kcl.mod",id:"understanding-kclmod",level:3},{value:"Building Blocks",id:"building-blocks",level:3},{value:"Instantiating an application",id:"instantiating-an-application",level:3},{value:"Using kusion init",id:"using-kusion-init",level:3},{value:"Using references",id:"using-references",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configuration-file-overview"},"Configuration File Overview"),(0,i.kt)("p",null,"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure."),(0,i.kt)("p",null,"This documentation series walks you through the odds and ends of managing such configuration files."),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#configuration-file-overview"},"Configuration File Overview"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#table-of-content"},"Table of Content")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#directory-structure"},"Directory Structure")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#appconfiguration-model"},"AppConfiguration Model")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#identifying-kcl-file"},"Identifying KCL file")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#kcl-packages-and-import"},"KCL Packages and Import")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#understanding-kclmod"},"Understanding kcl.mod")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#building-blocks"},"Building Blocks")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#instantiating-an-application"},"Instantiating an application")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-kusion-init"},"Using ",(0,i.kt)("inlineCode",{parentName:"a"},"kusion init"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#using-references"},"Using references"))))))),(0,i.kt)("h2",{id:"directory-structure"},"Directory Structure"),(0,i.kt)("p",null,"Kusion expects the configuration file to be placed in a certain directory structure because it might need some metadata (that is not stored in the application configuration itself) in order to proceed."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"See ",(0,i.kt)("a",{parentName:"p",href:"../concepts/project/overview"},"Project")," and ",(0,i.kt)("a",{parentName:"p",href:"../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,i.kt)("p",null,"A sample multi-stack directory structure looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"~/playground$ tree multi-stack-project/\nmulti-stack-project/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 base\n\u2502\xa0\xa0 \u2514\u2500\u2500 base.k\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u251c\u2500\u2500 prod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n")),(0,i.kt)("p",null,"In general, the directory structure follows a hierarchy where the top-level is the project configurations, and the sub-directories represent stack-level configurations."),(0,i.kt)("p",null,"You may notice there is a ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory besides all the stacks. The ",(0,i.kt)("inlineCode",{parentName:"p"},"base")," directory is not mandatory, but rather a place to store common configurations between different stacks. A common pattern we observed is to use stacks to represent different stages (dev, stage, prod, etc.) in the software development lifecycle, and/or different deployment targets (azure-eastus, aws-us-east-1, etc). A project can have as many stacks as needed."),(0,i.kt)("p",null,"In practice, the applications deployed into dev and prod might very likely end up with a similar set of configurations except a few fields such as the application image (dev might be on newer versions), resource requirements (prod might require more resources), etc."),(0,i.kt)("p",null,"As a general best practice, we recommend managing the common configurations in ",(0,i.kt)("inlineCode",{parentName:"p"},"base.k")," as much as possible to minimize duplicate code. We will cover how override works in ",(0,i.kt)("a",{parentName:"p",href:"base-override"},"Base and Override"),"."),(0,i.kt)("h2",{id:"appconfiguration-model"},"AppConfiguration Model"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is the out-of-the-box model we build that describes an application. It serves as the declarative intent for a given application."),(0,i.kt)("p",null,"The schema for ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is defined in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," repository. It is designed as a unified, application-centric model that encapsulates the comprehensive configuration details and in the meantime, hides the complexity of the infrastructure as much as possible."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," consists of multiple sub-components that each represent either the application workload itself, its dependencies, relevant workflows or operational expectations. We will deep dive into the details on how to author each of these elements in this upcoming documentation series."),(0,i.kt)("p",null,"For more details on the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", please refer to the ",(0,i.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"design documentation"),"."),(0,i.kt)("h2",{id:"authoring-configuration-files"},"Authoring Configuration Files"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open-source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h3",{id:"identifying-kcl-file"},"Identifying KCL file"),(0,i.kt)("p",null,"KCL files are identified with ",(0,i.kt)("inlineCode",{parentName:"p"},".k")," suffix in the filename."),(0,i.kt)("h3",{id:"kcl-packages-and-import"},"KCL Packages and Import"),(0,i.kt)("p",null,"Similar to most modern General Programming Languages (GPLs), KCL packages are used to organize collections of related KCL source files into modular and re-usable units."),(0,i.kt)("p",null,"In the context of Kusion, we use KCL packages to define models that could best abstract the behavior of an application. Specifically, we provide an official out-of-the-box KCL package(will keep iterating) with the name ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog"),". When authoring an application configuration file, you can simply import the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package in the source code and use all the schemas (including AppConfiguration) defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("p",null,"Similarly, if the schemas in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," package does not meet your needs, you can always fork it and make modifications, then import the modified package; or create a brand new package altogether and import it."),(0,i.kt)("p",null,"The Kusion ecosystem can be easily expanded in this manner."),(0,i.kt)("p",null,"An example of the import looks like the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"### import from the official catalog package\nimport catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\n### import my own modified package\nimport my_own_catalog.models.schema.v1 as moc\nimport my_other_package.schema.v1.redis as myredis\n")),(0,i.kt)("p",null,"Take ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog.models.schema.v1.workload as wl")," as an example, the ",(0,i.kt)("inlineCode",{parentName:"p"},".models.schema.v1.workload")," part after ",(0,i.kt)("inlineCode",{parentName:"p"},"import catalog")," represents the relative path of a specific schema to import. In this case, the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas is defined under ",(0,i.kt)("inlineCode",{parentName:"p"},"models/schema/v1/workload")," directory in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package."),(0,i.kt)("h3",{id:"understanding-kclmod"},"Understanding kcl.mod"),(0,i.kt)("p",null,"Much similar to the concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"go.mod"),", Kusion uses ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," as the source of truth to manage metadata (such as package name, dependencies, etc.) for the current package. Kusion will also auto-generate a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod.lock")," as the dependency lock file."),(0,i.kt)("p",null,"The most common usage for ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," is to manage the dependency of your application configurations. "),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Please note this ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," will be automatically generated if you are using ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," to initialize a project with a template. You will only need to modify this file if you are modifying the project metadata outside the initialization process, such as upgrading the dependency version or adding a new dependency altogether, etc.")),(0,i.kt)("p",null,"There are 3 sections in a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"package"),", representing the metadata for the current package."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"dependencies"),", describing the packages the current package depends on. Supports referencing either a git repository or an OCI artifact."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"profile"),", defining the behavior for Kusion. In the example below, it describes the list of files Kusion should look for when parsing the application configuration.")),(0,i.kt)("p",null,"An example of ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'[package]\nname = "multi-stack-project"\nedition = "0.5.0"\nversion = "0.1.0"\n\n[dependencies]\ncatalog = { git = "https://github.com/KusionStack/catalog.git", tag = "0.1.0" }\n# Uncomment the line below to use your own modified package\n# my-package = ghcr.io/kcl-lang/my-package\n\n[profile]\nentries = ["../base/base.k", "main.k"]\n')),(0,i.kt)("h3",{id:"building-blocks"},"Building Blocks"),(0,i.kt)("p",null,"Configuration files consist of building blocks that are made of instances of schemas. An ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance consists of several child schemas, most of which are optional. The only mandatory one is the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," instance. We will take a closer look in the ",(0,i.kt)("a",{parentName:"p",href:"workload"},"workload walkthrough"),". The order of the building blocks does NOT matter."),(0,i.kt)("p",null,"The major building blocks as of version ",(0,i.kt)("inlineCode",{parentName:"p"},"0.9.0"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n ...\n }\n ports: []\n secrets: {}\n }\n database: d.Database{}\n monitoring: m.Prometheus{}\n opsRule: t.OpsRule {}\n ...\n}\n')),(0,i.kt)("p",null,"We will deep dive into each one of the building blocks in this documentation series."),(0,i.kt)("h3",{id:"instantiating-an-application"},"Instantiating an application"),(0,i.kt)("p",null,"In Kusion's out-of-the-box experience, an application is identified with an instance of ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". You may have more than one application in the same project or stack."),(0,i.kt)("p",null,"Here's an example of a configuration that can be consumed by Kusion (assuming it is placed inside the proper directory structure that includes project and stack configurations, with a ",(0,i.kt)("inlineCode",{parentName:"p"},"kcl.mod")," present):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\ngocity: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "gocity": c.Container {\n image = "howieyuen/gocity:latest"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 4000\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"Don't worry about what ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," stand for at the moment. We will deep dive into each one of them in this upcoming documentation series."),(0,i.kt)("h3",{id:"using-kusion-init"},"Using ",(0,i.kt)("inlineCode",{parentName:"h3"},"kusion init")),(0,i.kt)("p",null,"Kusion offers a ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," sub-command which initializes a new project using some pre-built templates, which saves you from the hassle of manually building the aforementioned directory structure that Kusion expects."),(0,i.kt)("p",null,"There is a built-in template ",(0,i.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," in the Kusion binary that can be used offline. "),(0,i.kt)("p",null,"We also maintain a ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion-templates"},"kusion-templates repository")," that hosts a list of more comprehensive project scaffolds. You can access them via ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init --online")," command which requires connectivity to ",(0,i.kt)("inlineCode",{parentName:"p"},"github.com"),"."),(0,i.kt)("p",null,"The pre-built templates are meant to help you get off the ground quickly with some simple out-of-the-box examples. You can refer to the ",(0,i.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"QuickStart documentation")," for some step-by-step tutorials."),(0,i.kt)("h3",{id:"using-references"},"Using references"),(0,i.kt)("p",null,"The reference documentation for the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package is located in ",(0,i.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/app-configuration"},"Reference"),"."),(0,i.kt)("p",null,"If you are using the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," package out of the box, the reference documentation provides a comprehensive view for each schema involved, including all the attribute names and description, their types, default value if any, and whether a particular attribute is required or not. There will also be an example attached to each schema reference."),(0,i.kt)("p",null,"We will also deep dive into some common examples in the upcoming sections."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/60cc01db.51acc0e7.js b/assets/js/60cc01db.51acc0e7.js new file mode 100644 index 00000000000..868922789c7 --- /dev/null +++ b/assets/js/60cc01db.51acc0e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9198],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=r,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return t?a.createElement(m,i(i({ref:n},c),{},{components:t})):a.createElement(m,i({ref:n},c))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={},i="Using KusionStack Operating to operate Pods gracefully",l={unversionedId:"operating/started/demo-graceful-operation",id:"operating/started/demo-graceful-operation",title:"Using KusionStack Operating to operate Pods gracefully",description:"Applications always provide its service along with traffic routing.",source:"@site/docs/operating/started/demo-graceful-operation.md",sourceDirName:"operating/started",slug:"/operating/started/demo-graceful-operation",permalink:"/docs/next/operating/started/demo-graceful-operation",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/started/demo-graceful-operation.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",previous:{title:"Installation",permalink:"/docs/next/operating/started/install"},next:{title:"PodOpsLifecycle",permalink:"/docs/next/operating/concepts/podopslifecycle"}},s={},p=[{value:"Preparing",id:"preparing",level:2},{value:"Get started",id:"get-started",level:2},{value:"Create a new namespace",id:"create-a-new-namespace",level:3},{value:"Provision Pods and Services",id:"provision-pods-and-services",level:3},{value:"Provision a client",id:"provision-a-client",level:3},{value:"Update Pod revision",id:"update-pod-revision",level:3},{value:"Provision PodTransistionRule",id:"provision-podtransistionrule",level:3},{value:"Clean tutorial namespace",id:"clean-tutorial-namespace",level:3},{value:"Comparison with the Native Approach",id:"comparison-with-the-native-approach",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-kusionstack-operating-to-operate-pods-gracefully"},"Using KusionStack Operating to operate Pods gracefully"),(0,r.kt)("p",null,"Applications always provide its service along with traffic routing.\nOn Kubernetes, they should be a set of Pods and a corresponding Kubernetes Service resource to expose the service."),(0,r.kt)("p",null,"However, during operations such as updating Pod revisions,\nthere is a risk that client request traffic may be lost. This can lead to a poor user experience for developers."),(0,r.kt)("p",null,"This tutorial will demonstrate how to operate Pods gracefully in a KusionStack Operating way on Aliyun ACK\nwith SLB as a Service backend provider."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"You can also get the same point from ",(0,r.kt)("a",{parentName:"p",href:"https://www.bilibili.com/video/BV1n8411q7sP/?t=15.7"},"this video"),",\nwhich shows the same case using both KusionStack Kusion and Operating.\nThe sample used in this video can be found from ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/samples/wordpress"},"KusionStack Catalog"),".")),(0,r.kt)("h2",{id:"preparing"},"Preparing"),(0,r.kt)("p",null,"First, ensure that you have an Aliyun ACK Kubernetes cluster set up in order to provision an Aliyun SLB."),(0,r.kt)("p",null,"Next, install KusionStack Operating on this Kubernetes cluster\nfollowing ",(0,r.kt)("a",{parentName:"p",href:"https://kusionstack.io/docs/operating/started/install"},"installation doc"),"."),(0,r.kt)("h2",{id:"get-started"},"Get started"),(0,r.kt)("h3",{id:"create-a-new-namespace"},"Create a new namespace"),(0,r.kt)("p",null,"To begin, create a new namespace for this tutorial:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl create ns operating-tutorial\n")),(0,r.kt)("h3",{id:"provision-pods-and-services"},"Provision Pods and Services"),(0,r.kt)("p",null,"You can create a set of Pods to run up a demo application service\nby creating CollaSet resource using following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: server\n command:\n - /server\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"There should be 3 Pods created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nserver-c5lsr 1/1 Running 0 2m23s\nserver-p6wrx 1/1 Running 0 2m23s\nserver-zn62c 1/1 Running 0 2m23s\n")),(0,r.kt)("p",null,"Then create a Kubernetes Service by running following command,\nwhich will provision Aliyun SLB to expose service."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: v1\nkind: Service\nmetadata:\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n service.beta.kubernetes.io/backend-type: eni\n labels:\n kusionstack.io/control: \"true\" # this label is required\n name: server\nspec:\n ports:\n - port: 80\n protocol: TCP\n targetPort: 8080\n selector:\n app: server\n type: LoadBalancer\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"A service with external IP should be provisioned."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get svc server\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nserver LoadBalancer 192.168.225.55 47.101.49.182 80:30146/TCP 51s\n")),(0,r.kt)("p",null,"The label ",(0,r.kt)("inlineCode",{parentName:"p"},'kusionstack.io/control: "true"')," on Service is very important.\nIt means this service resource will be recognized by ResourceConsist framework, and then participate in PodOpsLifecycle\nto control the Aliyun SLB to switch off traffic before updating each Pod and switch on traffic after it finished,\nin order to protect the service."),(0,r.kt)("h3",{id:"provision-a-client"},"Provision a client"),(0,r.kt)("p",null,"Then we will provision a client to access the service we created before.\nPlease replace ",(0,r.kt)("inlineCode",{parentName:"p"},"")," in the following CollaSet yaml with the external IP from Kubernetes Service created above, and apply again."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: client\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: client\n template:\n metadata:\n labels:\n app: client\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: nginx\n command:\n - /client\n args:\n - -url\n - http:///echo # EXTERNAL_IP should be replaced\n - -m\n - POST\n - d\n - operating-tutorial\n - -qps\n - "10"\n - -worker\n - "10"\n - -timeout\n - "10000"\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"A client Pod should be created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-nc426 1/1 Running 0 30s\nserver-c5lsr 1/1 Running 0 19m\nserver-p6wrx 1/1 Running 0 19m\nserver-zn62c 1/1 Running 0 19m\n")),(0,r.kt)("p",null,"This client will continuously access the service using the configuration provided in the command.\nYou can monitor the response codes from its logs:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial logs -f client-nc426\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\n")),(0,r.kt)("p",null,"The accesses are all successful."),(0,r.kt)("h3",{id:"update-pod-revision"},"Update Pod revision"),(0,r.kt)("p",null,"To trigger a Pod revision update, run the following command\nto edit the container image and command in the PodTemplate of CollaSet:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.2\n name: server\n command:\n - /app/echo\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"It will trigger all Pods updated simultaneously. So the application ",(0,r.kt)("inlineCode",{parentName:"p"},"server")," has no Pod to serve.\nWe can observe the error from client logs."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'worker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:54040->47.101.49.182:80: read: connection reset by peer\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:34438->47.101.49.182:80: read: connection reset by peer\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 another loop, request: 20, failed: 3\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 another loop, request: 20, failed: 3\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n')),(0,r.kt)("h3",{id:"provision-podtransistionrule"},"Provision PodTransistionRule"),(0,r.kt)("p",null,"To avoid this problem, provision a PodTransitionRule with a maxUnavailable 50% rule by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n labels:\n name: server\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n selector:\n matchLabels:\n app: server\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"After updating the CollaSet of the server to trigger an update, you will see the Pods rolling update one by one,\nensuring that at least one Pod is always available to serve."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-rrfbj 1/1 Running 0 25s\nserver-457sn 0/1 Running 0 5s\nserver-bd5sz 0/1 Running 0 5s\nserver-l842s 1/1 Running 0 2m4s\n")),(0,r.kt)("p",null,"You can see from the client logs that no access requests fail during this update."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"worker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\n")),(0,r.kt)("h3",{id:"clean-tutorial-namespace"},"Clean tutorial namespace"),(0,r.kt)("p",null,"At the end of this tutorial, you can clean up the resources by deleting the namespace:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl delete ns operating-tutorial\n")),(0,r.kt)("h2",{id:"comparison-with-the-native-approach"},"Comparison with the Native Approach"),(0,r.kt)("p",null,"Kubernetes provides ",(0,r.kt)("inlineCode",{parentName:"p"},"preStop")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postStart")," hook in each container, by which users can also interact with service outside\nKubernetes like Aliyun SLB service. However, KusionStack Operating offers several advantages:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Pod level vs Container level")),(0,r.kt)("p",null,"Operating offers a Pod level hooks which have more complete information than one container,\nespecially there are several containers in one Pod."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Plugin-able")),(0,r.kt)("p",null,"Through KusionStack Operating, you can decouple operations executed before or after Pods actually change.\nFor example, traffic control can be added or removed without modifying the Pod's preStop configuration."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Rollback option")),(0,r.kt)("p",null,"In case of issues, rollback becomes a viable option when using the Operating approach to update Pods.\nSince Operating does not modify the Pods or their containers during the update,\nif the traffic service experiences problems, there is an opportunity to cancel the update."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/60cc01db.bd18c39c.js b/assets/js/60cc01db.bd18c39c.js deleted file mode 100644 index 2407be41677..00000000000 --- a/assets/js/60cc01db.bd18c39c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9198],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=r,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return t?a.createElement(m,i(i({ref:n},c),{},{components:t})):a.createElement(m,i({ref:n},c))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={},i="Using KusionStack Operating to operate Pods gracefully",l={unversionedId:"operating/started/demo-graceful-operation",id:"operating/started/demo-graceful-operation",title:"Using KusionStack Operating to operate Pods gracefully",description:"Applications always provide its service along with traffic routing.",source:"@site/docs/operating/started/demo-graceful-operation.md",sourceDirName:"operating/started",slug:"/operating/started/demo-graceful-operation",permalink:"/docs/next/operating/started/demo-graceful-operation",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/started/demo-graceful-operation.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",previous:{title:"Installation",permalink:"/docs/next/operating/started/install"},next:{title:"PodOpsLifecycle",permalink:"/docs/next/operating/concepts/podopslifecycle"}},s={},p=[{value:"Preparing",id:"preparing",level:2},{value:"Get started",id:"get-started",level:2},{value:"Create a new namespace",id:"create-a-new-namespace",level:3},{value:"Provision Pods and Services",id:"provision-pods-and-services",level:3},{value:"Provision a client",id:"provision-a-client",level:3},{value:"Update Pod revision",id:"update-pod-revision",level:3},{value:"Provision PodTransistionRule",id:"provision-podtransistionrule",level:3},{value:"Clean tutorial namespace",id:"clean-tutorial-namespace",level:3},{value:"Comparison with the Native Approach",id:"comparison-with-the-native-approach",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-kusionstack-operating-to-operate-pods-gracefully"},"Using KusionStack Operating to operate Pods gracefully"),(0,r.kt)("p",null,"Applications always provide its service along with traffic routing.\nOn Kubernetes, they should be a set of Pods and a corresponding Kubernetes Service resource to expose the service."),(0,r.kt)("p",null,"However, during operations such as updating Pod revisions,\nthere is a risk that client request traffic may be lost. This can lead to a poor user experience for developers."),(0,r.kt)("p",null,"This tutorial will demonstrate how to operate Pods gracefully in a KusionStack Operating way on Aliyun ACK\nwith SLB as a Service backend provider."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"You can also get the same point from ",(0,r.kt)("a",{parentName:"p",href:"https://www.bilibili.com/video/BV1n8411q7sP/?t=15.7"},"this video"),",\nwhich shows the same case using both KusionStack Kusion and Operating.\nThe sample used in this video can be found from ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/samples/wordpress"},"KusionStack Catalog"),".")),(0,r.kt)("h2",{id:"preparing"},"Preparing"),(0,r.kt)("p",null,"First, ensure that you have an Aliyun ACK Kubernetes cluster set up in order to provision an Aliyun SLB."),(0,r.kt)("p",null,"Next, install KusionStack Operating on this Kubernetes cluster\nfollowing ",(0,r.kt)("a",{parentName:"p",href:"https://kusionstack.io/docs/operating/started/install"},"installation doc"),"."),(0,r.kt)("h2",{id:"get-started"},"Get started"),(0,r.kt)("h3",{id:"create-a-new-namespace"},"Create a new namespace"),(0,r.kt)("p",null,"To begin, create a new namespace for this tutorial:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl create ns operating-tutorial\n")),(0,r.kt)("h3",{id:"provision-pods-and-services"},"Provision Pods and Services"),(0,r.kt)("p",null,"You can create a set of Pods to run up a demo application service\nby creating CollaSet resource using following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: server\n command:\n - /server\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"There should be 3 Pods created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nserver-c5lsr 1/1 Running 0 2m23s\nserver-p6wrx 1/1 Running 0 2m23s\nserver-zn62c 1/1 Running 0 2m23s\n")),(0,r.kt)("p",null,"Then create a Kubernetes Service by running following command,\nwhich will provision Aliyun SLB to expose service."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: v1\nkind: Service\nmetadata:\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n service.beta.kubernetes.io/backend-type: eni\n labels:\n kusionstack.io/control: \"true\" # this label is required\n name: server\nspec:\n ports:\n - port: 80\n protocol: TCP\n targetPort: 8080\n selector:\n app: server\n type: LoadBalancer\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"A service with external IP should be provisioned."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get svc server\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nserver LoadBalancer 192.168.225.55 47.101.49.182 80:30146/TCP 51s\n")),(0,r.kt)("p",null,"The label ",(0,r.kt)("inlineCode",{parentName:"p"},'kusionstack.io/control: "true"')," on Service is very important.\nIt means this service resource will be recognized by ResourceConsist framework, and then participate in PodOpsLifecycle\nto control the Aliyun SLB to switch off traffic before updating each Pod and switch on traffic after it finished,\nin order to protect the service."),(0,r.kt)("h3",{id:"provision-a-client"},"Provision a client"),(0,r.kt)("p",null,"Then we will provision a client to access the service we created before.\nPlease replace ",(0,r.kt)("inlineCode",{parentName:"p"},"")," in the following CollaSet yaml with the external IP from Kubernetes Service created above, and apply again."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: client\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: client\n template:\n metadata:\n labels:\n app: client\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: nginx\n command:\n - /client\n args:\n - -url\n - http:///echo # EXTERNAL_IP should be replaced\n - -m\n - POST\n - d\n - operating-tutorial\n - -qps\n - "10"\n - -worker\n - "10"\n - -timeout\n - "10000"\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"A client Pod should be created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-nc426 1/1 Running 0 30s\nserver-c5lsr 1/1 Running 0 19m\nserver-p6wrx 1/1 Running 0 19m\nserver-zn62c 1/1 Running 0 19m\n")),(0,r.kt)("p",null,"This client will continuously access the service using the configuration provided in the command.\nYou can monitor the response codes from its logs:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial logs -f client-nc426\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\n")),(0,r.kt)("p",null,"The accesses are all successful."),(0,r.kt)("h3",{id:"update-pod-revision"},"Update Pod revision"),(0,r.kt)("p",null,"To trigger a Pod revision update, run the following command\nto edit the container image and command in the PodTemplate of CollaSet:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.2\n name: server\n command:\n - /app/echo\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"It will trigger all Pods updated simultaneously. So the application ",(0,r.kt)("inlineCode",{parentName:"p"},"server")," has no Pod to serve.\nWe can observe the error from client logs."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'worker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:54040->47.101.49.182:80: read: connection reset by peer\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:34438->47.101.49.182:80: read: connection reset by peer\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 another loop, request: 20, failed: 3\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 another loop, request: 20, failed: 3\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n')),(0,r.kt)("h3",{id:"provision-podtransistionrule"},"Provision PodTransistionRule"),(0,r.kt)("p",null,"To avoid this problem, provision a PodTransitionRule with a maxUnavailable 50% rule by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n labels:\n name: server\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n selector:\n matchLabels:\n app: server\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"After updating the CollaSet of the server to trigger an update, you will see the Pods rolling update one by one,\nensuring that at least one Pod is always available to serve."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-rrfbj 1/1 Running 0 25s\nserver-457sn 0/1 Running 0 5s\nserver-bd5sz 0/1 Running 0 5s\nserver-l842s 1/1 Running 0 2m4s\n")),(0,r.kt)("p",null,"You can see from the client logs that no access requests fail during this update."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"worker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\n")),(0,r.kt)("h3",{id:"clean-tutorial-namespace"},"Clean tutorial namespace"),(0,r.kt)("p",null,"At the end of this tutorial, you can clean up the resources by deleting the namespace:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl delete ns operating-tutorial\n")),(0,r.kt)("h2",{id:"comparison-with-the-native-approach"},"Comparison with the Native Approach"),(0,r.kt)("p",null,"Kubernetes provides ",(0,r.kt)("inlineCode",{parentName:"p"},"preStop")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postStart")," hook in each container, by which users can also interact with service outside\nKubernetes like Aliyun SLB service. However, KusionStack Operating offers several advantages:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Pod level vs Container level")),(0,r.kt)("p",null,"Operating offers a Pod level hooks which have more complete information than one container,\nespecially there are several containers in one Pod."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Plugin-able")),(0,r.kt)("p",null,"Through KusionStack Operating, you can decouple operations executed before or after Pods actually change.\nFor example, traffic control can be added or removed without modifying the Pod's preStop configuration."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Rollback option")),(0,r.kt)("p",null,"In case of issues, rollback becomes a viable option when using the Operating approach to update Pods.\nSince Operating does not modify the Pods or their containers during the update,\nif the traffic service experiences problems, there is an opportunity to cancel the update."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/61f95e53.0e8b8130.js b/assets/js/61f95e53.0e8b8130.js new file mode 100644 index 00000000000..3b1519f609c --- /dev/null +++ b/assets/js/61f95e53.0e8b8130.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[995],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),d=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var r=n(87462),a=(n(67294),n(3905));const o={id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},l="Resource Naming Conventions",i={unversionedId:"kusion/reference/modules/naming-conventions",id:"kusion/reference/modules/naming-conventions",title:"Resource Naming Conventions",description:"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources.",source:"@site/docs/kusion/6-reference/2-modules/3-naming-conventions.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/naming-conventions",permalink:"/docs/next/kusion/reference/modules/naming-conventions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/3-naming-conventions.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},sidebar:"kusion",previous:{title:"service",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/service"},next:{title:"Roadmap",permalink:"/docs/next/kusion/reference/roadmap"}},s={},d=[{value:"Kubernetes Resources",id:"kubernetes-resources",level:2},{value:"Terraform Resources",id:"terraform-resources",level:2}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"resource-naming-conventions"},"Resource Naming Conventions"),(0,a.kt)("p",null,"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources. "),(0,a.kt)("h2",{id:"kubernetes-resources"},"Kubernetes Resources"),(0,a.kt)("p",null,"Kusion adheres to specific rules when generating the Kubernetes resources for users' applications. The table below lists some common Kubernetes resource naming conventions. Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"Namespace")," can now be specified by users. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Namespace"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Namespace:wordpress-local-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"apps/v1:Deployment:wordpress-local-db:wordpress-local-db-dev-wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"CronJob"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"batch/v1:CronJob:helloworld:helloworld-dev-helloworld")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Service"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"}," or ")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Service:helloworld:helloworld-dev-helloworld-public")))),(0,a.kt)("h2",{id:"terraform-resources"},"Terraform Resources"),(0,a.kt)("p",null,"Similarly, Kusion also adheres to specific naming conventions when generating the Terraform Resources. Some common resources are listed below. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"random_password"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:random:random_password:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_security_group"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_security_group:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_connection"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_connection:wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_rds_account"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_rds_account:wordpress")))),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,a.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,a.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,a.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,a.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/61f95e53.13d744d9.js b/assets/js/61f95e53.13d744d9.js deleted file mode 100644 index c5d3d9f8901..00000000000 --- a/assets/js/61f95e53.13d744d9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[995],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),d=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var r=n(87462),a=(n(67294),n(3905));const o={id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},l="Resource Naming Conventions",i={unversionedId:"kusion/reference/modules/naming-conventions",id:"kusion/reference/modules/naming-conventions",title:"Resource Naming Conventions",description:"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources.",source:"@site/docs/kusion/6-reference/2-modules/3-naming-conventions.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/naming-conventions",permalink:"/docs/next/kusion/reference/modules/naming-conventions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/3-naming-conventions.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},sidebar:"kusion",previous:{title:"service",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/service"},next:{title:"Roadmap",permalink:"/docs/next/kusion/reference/roadmap"}},s={},d=[{value:"Kubernetes Resources",id:"kubernetes-resources",level:2},{value:"Terraform Resources",id:"terraform-resources",level:2}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"resource-naming-conventions"},"Resource Naming Conventions"),(0,a.kt)("p",null,"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources. "),(0,a.kt)("h2",{id:"kubernetes-resources"},"Kubernetes Resources"),(0,a.kt)("p",null,"Kusion adheres to specific rules when generating the Kubernetes resources for users' applications. The table below lists some common Kubernetes resource naming conventions. Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"Namespace")," can now be specified by users. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Namespace"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Namespace:wordpress-local-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"apps/v1:Deployment:wordpress-local-db:wordpress-local-db-dev-wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"CronJob"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"batch/v1:CronJob:helloworld:helloworld-dev-helloworld")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Service"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"}," or ")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Service:helloworld:helloworld-dev-helloworld-public")))),(0,a.kt)("h2",{id:"terraform-resources"},"Terraform Resources"),(0,a.kt)("p",null,"Similarly, Kusion also adheres to specific naming conventions when generating the Terraform Resources. Some common resources are listed below. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"random_password"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:random:random_password:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_security_group"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_security_group:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_connection"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_connection:wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_rds_account"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_rds_account:wordpress")))),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,a.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,a.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,a.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,a.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/630accb9.4a58b7ec.js b/assets/js/630accb9.4c8f8a7e.js similarity index 80% rename from assets/js/630accb9.4a58b7ec.js rename to assets/js/630accb9.4c8f8a7e.js index 6cd7b129a9d..49afa3003ba 100644 --- a/assets/js/630accb9.4a58b7ec.js +++ b/assets/js/630accb9.4c8f8a7e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2235],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),f=l(n),d=o,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||i;return n?r.createElement(m,c(c({ref:t},u),{},{components:n})):r.createElement(m,c({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,c=new Array(i);c[0]=f;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a.mdxType="string"==typeof e?e:o,c[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},c="Command Line Tools",a={unversionedId:"kusion/reference/cli/index",id:"version-v0.9/kusion/reference/cli/index",title:"Command Line Tools",description:"",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/index.md",sourceDirName:"kusion/reference/cli",slug:"/kusion/reference/cli/",permalink:"/docs/v0.9/kusion/reference/cli/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/index.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions"},next:{title:"Kusion Commands",permalink:"/docs/v0.9/kusion/reference/cli/kusion/"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"command-line-tools"},"Command Line Tools"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2235],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),f=l(n),d=o,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||i;return n?r.createElement(m,c(c({ref:t},u),{},{components:n})):r.createElement(m,c({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,c=new Array(i);c[0]=f;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a.mdxType="string"==typeof e?e:o,c[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},c="Command Line Tools",a={unversionedId:"kusion/reference/cli/index",id:"version-v0.9/kusion/reference/cli/index",title:"Command Line Tools",description:"",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/index.md",sourceDirName:"kusion/reference/cli",slug:"/kusion/reference/cli/",permalink:"/docs/v0.9/kusion/reference/cli/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/index.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions"},next:{title:"Kusion Commands",permalink:"/docs/v0.9/kusion/reference/cli/kusion/"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"command-line-tools"},"Command Line Tools"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/640c7392.757dc55f.js b/assets/js/640c7392.5fc45ad2.js similarity index 69% rename from assets/js/640c7392.757dc55f.js rename to assets/js/640c7392.5fc45ad2.js index d6bb13244d2..a7ed75f3e47 100644 --- a/assets/js/640c7392.757dc55f.js +++ b/assets/js/640c7392.5fc45ad2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6566],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,m=d["".concat(s,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(m,a(a({ref:t},u),{},{components:n})):r.createElement(m,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={sidebar_position:1},a="Architecture",c={unversionedId:"kusion/concepts/arch",id:"version-v0.9/kusion/concepts/arch",title:"Architecture",description:"KusionStack includes two core components:",source:"@site/versioned_docs/version-v0.9/kusion/concepts/arch.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/arch",permalink:"/docs/v0.9/kusion/concepts/arch",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/arch.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Concepts",permalink:"/docs/v0.9/kusion/concepts/"},next:{title:"Glossary",permalink:"/docs/v0.9/kusion/concepts/glossary"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"architecture"},"Architecture"),(0,o.kt)("p",null,(0,o.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:null})),(0,o.kt)("p",null,"KusionStack includes two core components:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion"},"Kusion"),": The engine to deliver intentions to Kubernetes and Clouds"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/catalog"},"Catalog"),": Catalog of shared Kusion Models and Generators.")),(0,o.kt)("p",null,"The image above illustrates the workflow of KusionStack and how it works. In the next section, we will describe each of these components in detail."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6566],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,m=d["".concat(s,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(m,a(a({ref:t},u),{},{components:n})):r.createElement(m,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={sidebar_position:1},a="Architecture",c={unversionedId:"kusion/concepts/arch",id:"version-v0.9/kusion/concepts/arch",title:"Architecture",description:"KusionStack includes two core components:",source:"@site/versioned_docs/version-v0.9/kusion/concepts/arch.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/arch",permalink:"/docs/v0.9/kusion/concepts/arch",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/arch.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Concepts",permalink:"/docs/v0.9/kusion/concepts/"},next:{title:"Glossary",permalink:"/docs/v0.9/kusion/concepts/glossary"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"architecture"},"Architecture"),(0,o.kt)("p",null,(0,o.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:null})),(0,o.kt)("p",null,"KusionStack includes two core components:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion"},"Kusion"),": The engine to deliver intentions to Kubernetes and Clouds"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/catalog"},"Catalog"),": Catalog of shared Kusion Models and Generators.")),(0,o.kt)("p",null,"The image above illustrates the workflow of KusionStack and how it works. In the next section, we will describe each of these components in detail."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/69e6dfa6.2a081405.js b/assets/js/69e6dfa6.2a081405.js new file mode 100644 index 00000000000..e07ff00bffc --- /dev/null +++ b/assets/js/69e6dfa6.2a081405.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4790],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>h});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=l(o),h=r,d=m["".concat(p,".").concat(h)]||m[h]||c[h]||i;return o?n.createElement(d,a(a({ref:t},u),{},{components:o})):n.createElement(d,a({ref:t},u))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=o(87462),r=(o(67294),o(3905));const i={},a="Configure Monitoring Behavior With Prometheus",s={unversionedId:"kusion/guides/observability/prometheus",id:"version-v0.9/kusion/guides/observability/prometheus",title:"Configure Monitoring Behavior With Prometheus",description:"This document provides the step-by-step instruction to set up monitoring for your application.",source:"@site/versioned_docs/version-v0.9/kusion/guides/observability/prometheus.md",sourceDirName:"kusion/guides/observability",slug:"/kusion/guides/observability/prometheus",permalink:"/docs/v0.9/kusion/guides/observability/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/observability/prometheus.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Configure Resource Specification",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec"},next:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions"}},p={},l=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Setting up your own Prometheus",id:"setting-up-your-own-prometheus",level:2},{value:"Installing Prometheus operator3.",id:"installing-prometheus-operator3",level:3},{value:"Make sure RBAC is properly set up",id:"make-sure-rbac-is-properly-set-up",level:3},{value:"Configure Prometheus instance via the operator",id:"configure-prometheus-instance-via-the-operator",level:3},{value:"Exposing the Prometheus portal (optional)",id:"exposing-the-prometheus-portal-optional",level:3},{value:"Using kusion to deploy your application with monitoring requirements",id:"using-kusion-to-deploy-your-application-with-monitoring-requirements",level:2},{value:"References",id:"references",level:2}],u={toc:l};function c(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-monitoring-behavior-with-prometheus"},"Configure Monitoring Behavior With Prometheus"),(0,r.kt)("p",null,"This document provides the step-by-step instruction to set up monitoring for your application. "),(0,r.kt)("p",null,"As of today, kusion supports the configuration of Prometheus scraping behaviors for the target application. In the future, we will add more cloud-provider-native solutions, such as AWS CloudWatch, Azure Monitor, etc."),(0,r.kt)("p",null,"The demo sample is mainly composed of the following components:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Namespace"),(0,r.kt)("li",{parentName:"ul"},"Deployment"),(0,r.kt)("li",{parentName:"ul"},"Service"),(0,r.kt)("li",{parentName:"ul"},"ServiceMonitor")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes and Prometheus.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"Prometheus Introduction")))),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"setting-up-your-own-prometheus"},"Setting up your own Prometheus"),(0,r.kt)("p",null,"There a quite a few ways to set up Prometheus in your cluster:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus operator"),(0,r.kt)("li",{parentName:"ol"},"Installing a standalone Prometheus server"),(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus agent and connect to a remote Prometheus server")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-401092041"},"The advice from the Prometheus team")," is to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"PodMonitor")," CRs via the Prometheus operator to manage scrape configs going forward",(0,r.kt)("sup",null,"[2]"),"."),(0,r.kt)("p",null,"In either case, you only have to do this setup once per cluster. This doc will use a minikube cluster and Prometheus operator as an example."),(0,r.kt)("h3",{id:"installing-prometheus-operator3"},"Installing Prometheus operator",(0,r.kt)("sup",null,"[3]"),"."),(0,r.kt)("p",null,"To get the example in this user guide working, all you need is a running Prometheus operator. You can have that installed by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)\ncurl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f -\n")),(0,r.kt)("p",null,"This will install all the necessary CRDs and the Prometheus operator itself in the default namespace. Wait a few minutes, you can confirm the operator is up by running: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl wait --for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n default\n")),(0,r.kt)("h3",{id:"make-sure-rbac-is-properly-set-up"},"Make sure RBAC is properly set up"),(0,r.kt)("p",null,"If you have RBAC enabled on the cluster, the following must be created for Prometheus to work properly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: prometheus\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: prometheus\nrules:\n- apiGroups: [""]\n resources:\n - nodes\n - nodes/metrics\n - services\n - endpoints\n - pods\n verbs: ["get", "list", "watch"]\n- apiGroups: [""]\n resources:\n - configmaps\n verbs: ["get"]\n- apiGroups:\n - networking.k8s.io\n resources:\n - ingresses\n verbs: ["get", "list", "watch"]\n- nonResourceURLs: ["/metrics"]\n verbs: ["get"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n name: prometheus\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus\nsubjects:\n- kind: ServiceAccount\n name: prometheus\n namespace: default\n')),(0,r.kt)("h3",{id:"configure-prometheus-instance-via-the-operator"},"Configure Prometheus instance via the operator"),(0,r.kt)("p",null,"Once all of the above is set up, you can then configure the Prometheus instance via the operator:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n name: prometheus\nspec:\n serviceAccountName: prometheus\n serviceMonitorNamespaceSelector: {}\n serviceMonitorSelector: {}\n podMonitorNamespaceSelector: {}\n podMonitorSelector: {}\n resources:\n requests:\n memory: 400Mi\n")),(0,r.kt)("p",null,"This Prometheus instance above will be cluster-wide, picking up ALL the service monitors and pod monitors across ALL the namespaces.\nYou can adjust the requests and limits accordingly if you have a larger cluster."),(0,r.kt)("h3",{id:"exposing-the-prometheus-portal-optional"},"Exposing the Prometheus portal (optional)"),(0,r.kt)("p",null,"Once you have the managed Prometheus instance created via the Prometheus CR above, you should be able to see a service created called ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus-operated"),":"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-operated",src:o(91512).Z,width:"631",height:"52"})),(0,r.kt)("p",null,"If you are also running on minikube, you can expose it onto your localhost via kubectl:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/prometheus-operated 9099:9090\n")),(0,r.kt)("p",null,"You should then be able to see the Prometheus portal via ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost:9099")," in your browser:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-portal",src:o(35443).Z,width:"2878",height:"1096"})),(0,r.kt)("p",null,"If you are running a non-local cluster, you can try to expose it via another way, through an ingress controller for example."),(0,r.kt)("h2",{id:"using-kusion-to-deploy-your-application-with-monitoring-requirements"},"Using kusion to deploy your application with monitoring requirements"),(0,r.kt)("p",null,"At this point we are set up for good! Any new applications you deploy via kusion will now automatically have the monitoring-related resources created, should you declare you want it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model."),(0,r.kt)("p",null,"The monitoring in an AppConfiguration is declared in the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field. See the example below for a full, deployable AppConfiguration."),(0,r.kt)("p",null,"Please note we are using a new image ",(0,r.kt)("inlineCode",{parentName:"p"},"quay.io/brancz/prometheus-example-app")," since the app itself need to expose metrics for Prometheus to scrape:"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "monitoring-sample-app": c.Container {\n image: "quay.io/brancz/prometheus-example-app:v0.3.0"\n }\n }\n ports: [\n n.Port {\n port: 8080\n }\n ]\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n scheme: "http"\n }\n}\n')),(0,r.kt)("p",null,"The KCL file above represents an application with a service type workload, exposing the port 8080, and would like Prometheus to scrape the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint every 30 seconds."),(0,r.kt)("p",null,"Running ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply")," would show that kusion will create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," and a ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor"),":\n",(0,r.kt)("img",{alt:"kusion-apply-with-monitor",src:o(448).Z,width:"705",height:"224"})),(0,r.kt)("p",null,"Continue applying all resources:\n",(0,r.kt)("img",{alt:"kusion-apply-success",src:o(56816).Z,width:"1047",height:"564"})),(0,r.kt)("p",null,"If we want to, we can verify the service monitor has been created successfully:\n",(0,r.kt)("img",{alt:"service-monitor",src:o(58232).Z,width:"693",height:"463"})),(0,r.kt)("p",null,"In a few seconds, you should be able to see in the Prometheus portal that the service we just deployed has now been discovered and monitored by Prometheus:\n",(0,r.kt)("img",{alt:"prometheus-targets",src:o(81187).Z,width:"2880",height:"1636"})),(0,r.kt)("p",null,"You can run a few simply queries for the data that Prometheus scraped from your application:\n",(0,r.kt)("img",{alt:"prometheus-simple-query",src:o(87695).Z,width:"2880",height:"1634"})),(0,r.kt)("p",null,"For more info about PromQL, you can find them ",(0,r.kt)("a",{parentName:"p",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"here"),(0,r.kt)("sup",null,"[4]"),"."),(0,r.kt)("h2",{id:"references"},"References"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Prometheus: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"https://prometheus.io/docs/introduction/overview/")),(0,r.kt)("li",{parentName:"ol"},"Prometheus team advise: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500"},"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500")),(0,r.kt)("li",{parentName:"ol"},"Prometheus operator getting started doc: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md"},"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md")),(0,r.kt)("li",{parentName:"ol"},"PromQL basics: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"https://prometheus.io/docs/prometheus/latest/querying/basics/"))))}c.isMDXComponent=!0},56816:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-success-52d04db670fd184959c3ea5c9e54f69d.png"},448:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-with-monitor-d27cd1443e1a324d514983d52c055b15.png"},91512:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-operated-4cf8308703e4ec9d06a5078bbceb8d5d.png"},35443:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-portal-b60d8654c309e675fc04f1e74c5c127a.png"},87695:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-simple-query-60205589e762105ebc850e70d8ea7b56.png"},81187:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-targets-05964bad58af16f2e02c57cafa8565e7.png"},58232:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/service-monitor-2374625bfd1180a978a2be50ad4648ce.png"}}]); \ No newline at end of file diff --git a/assets/js/69e6dfa6.2fc299cc.js b/assets/js/69e6dfa6.2fc299cc.js deleted file mode 100644 index ee8676158de..00000000000 --- a/assets/js/69e6dfa6.2fc299cc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4790],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>h});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=l(o),h=r,d=m["".concat(p,".").concat(h)]||m[h]||c[h]||i;return o?n.createElement(d,a(a({ref:t},u),{},{components:o})):n.createElement(d,a({ref:t},u))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=o(87462),r=(o(67294),o(3905));const i={},a="Configure Monitoring Behavior With Prometheus",s={unversionedId:"kusion/guides/observability/prometheus",id:"version-v0.9/kusion/guides/observability/prometheus",title:"Configure Monitoring Behavior With Prometheus",description:"This document provides the step-by-step instruction to set up monitoring for your application.",source:"@site/versioned_docs/version-v0.9/kusion/guides/observability/prometheus.md",sourceDirName:"kusion/guides/observability",slug:"/kusion/guides/observability/prometheus",permalink:"/docs/v0.9/kusion/guides/observability/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/observability/prometheus.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Configure Resource Specification",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec"},next:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions"}},p={},l=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Setting up your own Prometheus",id:"setting-up-your-own-prometheus",level:2},{value:"Installing Prometheus operator3.",id:"installing-prometheus-operator3",level:3},{value:"Make sure RBAC is properly set up",id:"make-sure-rbac-is-properly-set-up",level:3},{value:"Configure Prometheus instance via the operator",id:"configure-prometheus-instance-via-the-operator",level:3},{value:"Exposing the Prometheus portal (optional)",id:"exposing-the-prometheus-portal-optional",level:3},{value:"Using kusion to deploy your application with monitoring requirements",id:"using-kusion-to-deploy-your-application-with-monitoring-requirements",level:2},{value:"References",id:"references",level:2}],u={toc:l};function c(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-monitoring-behavior-with-prometheus"},"Configure Monitoring Behavior With Prometheus"),(0,r.kt)("p",null,"This document provides the step-by-step instruction to set up monitoring for your application. "),(0,r.kt)("p",null,"As of today, kusion supports the configuration of Prometheus scraping behaviors for the target application. In the future, we will add more cloud-provider-native solutions, such as AWS CloudWatch, Azure Monitor, etc."),(0,r.kt)("p",null,"The demo sample is mainly composed of the following components:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Namespace"),(0,r.kt)("li",{parentName:"ul"},"Deployment"),(0,r.kt)("li",{parentName:"ul"},"Service"),(0,r.kt)("li",{parentName:"ul"},"ServiceMonitor")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes and Prometheus.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"Prometheus Introduction")))),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"setting-up-your-own-prometheus"},"Setting up your own Prometheus"),(0,r.kt)("p",null,"There a quite a few ways to set up Prometheus in your cluster:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus operator"),(0,r.kt)("li",{parentName:"ol"},"Installing a standalone Prometheus server"),(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus agent and connect to a remote Prometheus server")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-401092041"},"The advice from the Prometheus team")," is to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"PodMonitor")," CRs via the Prometheus operator to manage scrape configs going forward",(0,r.kt)("sup",null,"[2]"),"."),(0,r.kt)("p",null,"In either case, you only have to do this setup once per cluster. This doc will use a minikube cluster and Prometheus operator as an example."),(0,r.kt)("h3",{id:"installing-prometheus-operator3"},"Installing Prometheus operator",(0,r.kt)("sup",null,"[3]"),"."),(0,r.kt)("p",null,"To get the example in this user guide working, all you need is a running Prometheus operator. You can have that installed by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)\ncurl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f -\n")),(0,r.kt)("p",null,"This will install all the necessary CRDs and the Prometheus operator itself in the default namespace. Wait a few minutes, you can confirm the operator is up by running: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl wait --for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n default\n")),(0,r.kt)("h3",{id:"make-sure-rbac-is-properly-set-up"},"Make sure RBAC is properly set up"),(0,r.kt)("p",null,"If you have RBAC enabled on the cluster, the following must be created for Prometheus to work properly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: prometheus\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: prometheus\nrules:\n- apiGroups: [""]\n resources:\n - nodes\n - nodes/metrics\n - services\n - endpoints\n - pods\n verbs: ["get", "list", "watch"]\n- apiGroups: [""]\n resources:\n - configmaps\n verbs: ["get"]\n- apiGroups:\n - networking.k8s.io\n resources:\n - ingresses\n verbs: ["get", "list", "watch"]\n- nonResourceURLs: ["/metrics"]\n verbs: ["get"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n name: prometheus\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus\nsubjects:\n- kind: ServiceAccount\n name: prometheus\n namespace: default\n')),(0,r.kt)("h3",{id:"configure-prometheus-instance-via-the-operator"},"Configure Prometheus instance via the operator"),(0,r.kt)("p",null,"Once all of the above is set up, you can then configure the Prometheus instance via the operator:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n name: prometheus\nspec:\n serviceAccountName: prometheus\n serviceMonitorNamespaceSelector: {}\n serviceMonitorSelector: {}\n podMonitorNamespaceSelector: {}\n podMonitorSelector: {}\n resources:\n requests:\n memory: 400Mi\n")),(0,r.kt)("p",null,"This Prometheus instance above will be cluster-wide, picking up ALL the service monitors and pod monitors across ALL the namespaces.\nYou can adjust the requests and limits accordingly if you have a larger cluster."),(0,r.kt)("h3",{id:"exposing-the-prometheus-portal-optional"},"Exposing the Prometheus portal (optional)"),(0,r.kt)("p",null,"Once you have the managed Prometheus instance created via the Prometheus CR above, you should be able to see a service created called ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus-operated"),":"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-operated",src:o(91512).Z,width:"631",height:"52"})),(0,r.kt)("p",null,"If you are also running on minikube, you can expose it onto your localhost via kubectl:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/prometheus-operated 9099:9090\n")),(0,r.kt)("p",null,"You should then be able to see the Prometheus portal via ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost:9099")," in your browser:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-portal",src:o(35443).Z,width:"2878",height:"1096"})),(0,r.kt)("p",null,"If you are running a non-local cluster, you can try to expose it via another way, through an ingress controller for example."),(0,r.kt)("h2",{id:"using-kusion-to-deploy-your-application-with-monitoring-requirements"},"Using kusion to deploy your application with monitoring requirements"),(0,r.kt)("p",null,"At this point we are set up for good! Any new applications you deploy via kusion will now automatically have the monitoring-related resources created, should you declare you want it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model."),(0,r.kt)("p",null,"The monitoring in an AppConfiguration is declared in the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field. See the example below for a full, deployable AppConfiguration."),(0,r.kt)("p",null,"Please note we are using a new image ",(0,r.kt)("inlineCode",{parentName:"p"},"quay.io/brancz/prometheus-example-app")," since the app itself need to expose metrics for Prometheus to scrape:"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "monitoring-sample-app": c.Container {\n image: "quay.io/brancz/prometheus-example-app:v0.3.0"\n }\n }\n ports: [\n n.Port {\n port: 8080\n }\n ]\n }\n monitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n scheme: "http"\n }\n}\n')),(0,r.kt)("p",null,"The KCL file above represents an application with a service type workload, exposing the port 8080, and would like Prometheus to scrape the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint every 30 seconds."),(0,r.kt)("p",null,"Running ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply")," would show that kusion will create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," and a ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor"),":\n",(0,r.kt)("img",{alt:"kusion-apply-with-monitor",src:o(448).Z,width:"705",height:"224"})),(0,r.kt)("p",null,"Continue applying all resources:\n",(0,r.kt)("img",{alt:"kusion-apply-success",src:o(56816).Z,width:"1047",height:"564"})),(0,r.kt)("p",null,"If we want to, we can verify the service monitor has been created successfully:\n",(0,r.kt)("img",{alt:"service-monitor",src:o(58232).Z,width:"693",height:"463"})),(0,r.kt)("p",null,"In a few seconds, you should be able to see in the Prometheus portal that the service we just deployed has now been discovered and monitored by Prometheus:\n",(0,r.kt)("img",{alt:"prometheus-targets",src:o(81187).Z,width:"2880",height:"1636"})),(0,r.kt)("p",null,"You can run a few simply queries for the data that Prometheus scraped from your application:\n",(0,r.kt)("img",{alt:"prometheus-simple-query",src:o(87695).Z,width:"2880",height:"1634"})),(0,r.kt)("p",null,"For more info about PromQL, you can find them ",(0,r.kt)("a",{parentName:"p",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"here"),(0,r.kt)("sup",null,"[4]"),"."),(0,r.kt)("h2",{id:"references"},"References"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Prometheus: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"https://prometheus.io/docs/introduction/overview/")),(0,r.kt)("li",{parentName:"ol"},"Prometheus team advise: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500"},"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500")),(0,r.kt)("li",{parentName:"ol"},"Prometheus operator getting started doc: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md"},"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md")),(0,r.kt)("li",{parentName:"ol"},"PromQL basics: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"https://prometheus.io/docs/prometheus/latest/querying/basics/"))))}c.isMDXComponent=!0},56816:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-success-52d04db670fd184959c3ea5c9e54f69d.png"},448:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-with-monitor-d27cd1443e1a324d514983d52c055b15.png"},91512:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-operated-4cf8308703e4ec9d06a5078bbceb8d5d.png"},35443:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-portal-b60d8654c309e675fc04f1e74c5c127a.png"},87695:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-simple-query-60205589e762105ebc850e70d8ea7b56.png"},81187:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-targets-05964bad58af16f2e02c57cafa8565e7.png"},58232:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/service-monitor-2374625bfd1180a978a2be50ad4648ce.png"}}]); \ No newline at end of file diff --git a/assets/js/6a034c6e.25cb7092.js b/assets/js/6a034c6e.25cb7092.js deleted file mode 100644 index a3cfc5d8317..00000000000 --- a/assets/js/6a034c6e.25cb7092.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5634],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>g});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),s=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(t),g=r,k=d["".concat(l,".").concat(g)]||d[g]||u[g]||i;return t?o.createElement(k,a(a({ref:n},c),{},{components:t})):o.createElement(k,a({ref:n},c))}));function g(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=d;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,a[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>s});var o=t(87462),r=(t(67294),t(3905));const i={id:"networking"},a="Application Networking",p={unversionedId:"kusion/configuration-walkthrough/networking",id:"version-v0.10/kusion/configuration-walkthrough/networking",title:"Application Networking",description:"In addition to configuring application's container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/5-networking.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/networking",permalink:"/docs/kusion/configuration-walkthrough/networking",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/5-networking.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"networking"},sidebar:"kusion",previous:{title:"Workload",permalink:"/docs/kusion/configuration-walkthrough/workload"},next:{title:"Managed Databases",permalink:"/docs/kusion/configuration-walkthrough/databse"}},l={},s=[{value:"Import",id:"import",level:2},{value:"Private vs Public Access",id:"private-vs-public-access",level:2},{value:"Mapping ports",id:"mapping-ports",level:2},{value:"Exposing multiple ports",id:"exposing-multiple-ports",level:2},{value:"Choosing protocol",id:"choosing-protocol",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-networking"},"Application Networking"),(0,r.kt)("p",null,"In addition to configuring application's ",(0,r.kt)("a",{parentName:"p",href:"workload#configure-containers"},"container specifications"),", you can also configure its networking behaviors, including how to expose the application and how it can be accessed."),(0,r.kt)("p",null,"In future versions, this will also include ingress-based routing strategy and DNS configurations."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n")),(0,r.kt)("h2",{id:"private-vs-public-access"},"Private vs Public Access"),(0,r.kt)("p",null,"Private network access means the service can only be access from within the target cluster."),(0,r.kt)("p",null,"Public access is implemented using public load balancers on the cloud. This generally requires a Kubernetes cluster that is running on the cloud with a vendor-specific service controller."),(0,r.kt)("p",null,"Any ports defined default to private access unless explicitly specified."),(0,r.kt)("p",null,"To expose port 80 to be accessed privately:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n")),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n}\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The CSP (Cloud Service Provider) used to provide load balancers is defined by platform engineers in workspace.")),(0,r.kt)("h2",{id:"mapping-ports"},"Mapping ports"),(0,r.kt)("p",null,"To expose a port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," that maps to a different port ",(0,r.kt)("inlineCode",{parentName:"p"},"8088")," on the container:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n }\n ]\n }\n}\n")),(0,r.kt)("h2",{id:"exposing-multiple-ports"},"Exposing multiple ports"),(0,r.kt)("p",null,"You can also expose multiple ports and configure them separately. "),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly, and port 9099 for private access (to be scraped by Prometheus, for example):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9099\n }\n ]\n }\n}\n")),(0,r.kt)("h2",{id:"choosing-protocol"},"Choosing protocol"),(0,r.kt)("p",null,"To expose a port using the ",(0,r.kt)("inlineCode",{parentName:"p"},"UDP")," protocol:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n protocol: "UDP"\n }\n ]\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6a034c6e.4dc0c5ac.js b/assets/js/6a034c6e.4dc0c5ac.js new file mode 100644 index 00000000000..469344081a3 --- /dev/null +++ b/assets/js/6a034c6e.4dc0c5ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5634],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>g});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),s=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(t),g=r,k=d["".concat(l,".").concat(g)]||d[g]||u[g]||i;return t?o.createElement(k,a(a({ref:n},c),{},{components:t})):o.createElement(k,a({ref:n},c))}));function g(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=d;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,a[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>s});var o=t(87462),r=(t(67294),t(3905));const i={id:"networking"},a="Application Networking",p={unversionedId:"kusion/configuration-walkthrough/networking",id:"version-v0.10/kusion/configuration-walkthrough/networking",title:"Application Networking",description:"In addition to configuring application's container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/5-networking.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/networking",permalink:"/docs/kusion/configuration-walkthrough/networking",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/5-networking.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"networking"},sidebar:"kusion",previous:{title:"Workload",permalink:"/docs/kusion/configuration-walkthrough/workload"},next:{title:"Managed Databases",permalink:"/docs/kusion/configuration-walkthrough/databse"}},l={},s=[{value:"Import",id:"import",level:2},{value:"Private vs Public Access",id:"private-vs-public-access",level:2},{value:"Mapping ports",id:"mapping-ports",level:2},{value:"Exposing multiple ports",id:"exposing-multiple-ports",level:2},{value:"Choosing protocol",id:"choosing-protocol",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-networking"},"Application Networking"),(0,r.kt)("p",null,"In addition to configuring application's ",(0,r.kt)("a",{parentName:"p",href:"workload#configure-containers"},"container specifications"),", you can also configure its networking behaviors, including how to expose the application and how it can be accessed."),(0,r.kt)("p",null,"In future versions, this will also include ingress-based routing strategy and DNS configurations."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n")),(0,r.kt)("h2",{id:"private-vs-public-access"},"Private vs Public Access"),(0,r.kt)("p",null,"Private network access means the service can only be access from within the target cluster."),(0,r.kt)("p",null,"Public access is implemented using public load balancers on the cloud. This generally requires a Kubernetes cluster that is running on the cloud with a vendor-specific service controller."),(0,r.kt)("p",null,"Any ports defined default to private access unless explicitly specified."),(0,r.kt)("p",null,"To expose port 80 to be accessed privately:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n")),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n}\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The CSP (Cloud Service Provider) used to provide load balancers is defined by platform engineers in workspace.")),(0,r.kt)("h2",{id:"mapping-ports"},"Mapping ports"),(0,r.kt)("p",null,"To expose a port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," that maps to a different port ",(0,r.kt)("inlineCode",{parentName:"p"},"8088")," on the container:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n }\n ]\n }\n}\n")),(0,r.kt)("h2",{id:"exposing-multiple-ports"},"Exposing multiple ports"),(0,r.kt)("p",null,"You can also expose multiple ports and configure them separately. "),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly, and port 9099 for private access (to be scraped by Prometheus, for example):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9099\n }\n ]\n }\n}\n")),(0,r.kt)("h2",{id:"choosing-protocol"},"Choosing protocol"),(0,r.kt)("p",null,"To expose a port using the ",(0,r.kt)("inlineCode",{parentName:"p"},"UDP")," protocol:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n protocol: "UDP"\n }\n ]\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6b830420.2351029d.js b/assets/js/6b830420.2351029d.js new file mode 100644 index 00000000000..c9be773ec47 --- /dev/null +++ b/assets/js/6b830420.2351029d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[992],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>h});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function i(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=l(o),h=r,d=c["".concat(p,".").concat(h)]||c[h]||m[h]||a;return o?n.createElement(d,i(i({ref:t},u),{},{components:o})):n.createElement(d,i({ref:t},u))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=o.length,i=new Array(a);i[0]=c;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=o(87462),r=(o(67294),o(3905));const a={},i="Configure Monitoring Behavior With Prometheus",s={unversionedId:"kusion/user-guides/observability/prometheus",id:"kusion/user-guides/observability/prometheus",title:"Configure Monitoring Behavior With Prometheus",description:"This document provides the step-by-step instruction to set up monitoring for your application.",source:"@site/docs/kusion/5-user-guides/3-observability/1-prometheus.md",sourceDirName:"kusion/5-user-guides/3-observability",slug:"/kusion/user-guides/observability/prometheus",permalink:"/docs/next/kusion/user-guides/observability/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/3-observability/1-prometheus.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Schedule a Job",permalink:"/docs/next/kusion/user-guides/working-with-k8s/job"},next:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions"}},p={},l=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Setting up your own Prometheus",id:"setting-up-your-own-prometheus",level:2},{value:"Installing Prometheus operator3.",id:"installing-prometheus-operator3",level:3},{value:"Make sure RBAC is properly set up",id:"make-sure-rbac-is-properly-set-up",level:3},{value:"Configure Prometheus instance via the operator",id:"configure-prometheus-instance-via-the-operator",level:3},{value:"Exposing the Prometheus portal (optional)",id:"exposing-the-prometheus-portal-optional",level:3},{value:"Setting up workspace configs",id:"setting-up-workspace-configs",level:2},{value:"Operator mode",id:"operator-mode",level:3},{value:"Monitor types",id:"monitor-types",level:3},{value:"Overriding with projectSelector",id:"overriding-with-projectselector",level:3},{value:"Updating the workspace config",id:"updating-the-workspace-config",level:2},{value:"Using kusion to deploy your application with monitoring requirements",id:"using-kusion-to-deploy-your-application-with-monitoring-requirements",level:2},{value:"References",id:"references",level:2}],u={toc:l};function m(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-monitoring-behavior-with-prometheus"},"Configure Monitoring Behavior With Prometheus"),(0,r.kt)("p",null,"This document provides the step-by-step instruction to set up monitoring for your application. "),(0,r.kt)("p",null,"As of today, Kusion supports the configuration of Prometheus scraping behaviors for the target application. In the future, we will add more cloud-provider-native solutions, such as AWS CloudWatch, Azure Monitor, etc."),(0,r.kt)("p",null,"The user guide below is composed of the following components:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Namespace"),(0,r.kt)("li",{parentName:"ul"},"Deployment"),(0,r.kt)("li",{parentName:"ul"},"Service"),(0,r.kt)("li",{parentName:"ul"},"ServiceMonitor")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes and Prometheus.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"Prometheus Introduction")))),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"setting-up-your-own-prometheus"},"Setting up your own Prometheus"),(0,r.kt)("p",null,"There a quite a few ways to set up Prometheus in your cluster:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus operator"),(0,r.kt)("li",{parentName:"ol"},"Installing a standalone Prometheus server"),(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus agent and connect to a remote Prometheus server")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-401092041"},"The advice from the Prometheus team")," is to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"PodMonitor")," CRs via the Prometheus operator to manage scrape configs going forward",(0,r.kt)("sup",null,"[2]"),"."),(0,r.kt)("p",null,"In either case, you only have to do this setup once per cluster. This doc will use a minikube cluster and Prometheus operator as an example."),(0,r.kt)("h3",{id:"installing-prometheus-operator3"},"Installing Prometheus operator",(0,r.kt)("sup",null,"[3]"),"."),(0,r.kt)("p",null,"To get the example in this user guide working, all you need is a running Prometheus operator. You can have that installed by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)\ncurl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f -\n")),(0,r.kt)("p",null,"This will install all the necessary CRDs and the Prometheus operator itself in the default namespace. Wait a few minutes, you can confirm the operator is up by running: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl wait --for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n default\n")),(0,r.kt)("h3",{id:"make-sure-rbac-is-properly-set-up"},"Make sure RBAC is properly set up"),(0,r.kt)("p",null,"If you have RBAC enabled on the cluster, the following must be created for Prometheus to work properly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: prometheus\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: prometheus\nrules:\n- apiGroups: [""]\n resources:\n - nodes\n - nodes/metrics\n - services\n - endpoints\n - pods\n verbs: ["get", "list", "watch"]\n- apiGroups: [""]\n resources:\n - configmaps\n verbs: ["get"]\n- apiGroups:\n - networking.k8s.io\n resources:\n - ingresses\n verbs: ["get", "list", "watch"]\n- nonResourceURLs: ["/metrics"]\n verbs: ["get"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n name: prometheus\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus\nsubjects:\n- kind: ServiceAccount\n name: prometheus\n namespace: default\n')),(0,r.kt)("h3",{id:"configure-prometheus-instance-via-the-operator"},"Configure Prometheus instance via the operator"),(0,r.kt)("p",null,"Once all of the above is set up, you can then configure the Prometheus instance via the operator:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n name: prometheus\nspec:\n serviceAccountName: prometheus\n serviceMonitorNamespaceSelector: {}\n serviceMonitorSelector: {}\n podMonitorNamespaceSelector: {}\n podMonitorSelector: {}\n resources:\n requests:\n memory: 400Mi\n")),(0,r.kt)("p",null,"This Prometheus instance above will be cluster-wide, picking up ALL the service monitors and pod monitors across ALL the namespaces.\nYou can adjust the requests and limits accordingly if you have a larger cluster."),(0,r.kt)("h3",{id:"exposing-the-prometheus-portal-optional"},"Exposing the Prometheus portal (optional)"),(0,r.kt)("p",null,"Once you have the managed Prometheus instance created via the Prometheus CR above, you should be able to see a service created called ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus-operated"),":"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-operated",src:o(91512).Z,width:"631",height:"52"})),(0,r.kt)("p",null,"If you are also running on minikube, you can expose it onto your localhost via kubectl:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/prometheus-operated 9099:9090\n")),(0,r.kt)("p",null,"You should then be able to see the Prometheus portal via ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost:9099")," in your browser:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-portal",src:o(35443).Z,width:"2878",height:"1096"})),(0,r.kt)("p",null,"If you are running a non-local cluster, you can try to expose it via another way, through an ingress controller for example."),(0,r.kt)("h2",{id:"setting-up-workspace-configs"},"Setting up workspace configs"),(0,r.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,r.kt)("p",null,"In the case of setting up Prometheus, there are a few things to set up on the workspace level:"),(0,r.kt)("h3",{id:"operator-mode"},"Operator mode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," flag indicates to Kusion whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,r.kt)("p",null,"To see more about different ways to run Prometheus in the Kubernetes cluster, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md#prometheus-installation"},"design documentation"),"."),(0,r.kt)("p",null,"Most cloud vendors provide an out-of-the-box monitoring solutions for workloads running in a managed-Kubernetes cluster (EKS, AKS, etc), such as AWS CloudWatch, Azure Monitor, etc. These solutions mostly involve installing an agent (CloudWatch Agent, OMS Agent, etc) in the cluster and collecting the metrics to a centralized monitoring server. In those cases, you don't need to set ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". It only needs to be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when you have an installation of the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator")," running inside the Kubernetes cluster."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For differences between ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/kube-prometheus"},"kube-prometheus")," and the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack"},"community kube-prometheus-stack helm chart"),", the details are documented ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator#prometheus-operator-vs-kube-prometheus-vs-community-helm-chart"},"here"),".")),(0,r.kt)("h3",{id:"monitor-types"},"Monitor types"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitorType")," flag indicates the kind of monitor Kusion will create. It only applies when ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". As of version 0.10.0, Kusion provides options to scrape metrics from either the application pods or its corresponding Kubernetes services. This determines the different kinds of resources Kusion manages when Prometheus runs as an operator in the target cluster."),(0,r.kt)("p",null,"A sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with Prometheus settings:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n ...\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"To instruct Prometheus to scrape from pod targets instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n ...\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is omitted from the ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", Kusion defaults ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to false."),(0,r.kt)("h3",{id:"overriding-with-projectselector"},"Overriding with projectSelector"),(0,r.kt)("p",null,"Workspace configurations contain a set of default setting group for all projects in the workspace, with means to override them by Projects using a ",(0,r.kt)("inlineCode",{parentName:"p"},"projectSelector")," keyword."),(0,r.kt)("p",null,"Projects with the name matching those in projectSelector will use the values defined in that override group instead of the default. If a key is not present in the override group, the default value will be used."),(0,r.kt)("p",null,"Take a look at the sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n ...\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n projectSelector:\n - foobar\n high_frequency:\n monitorType: Service\n projectSelector:\n - helloworld\n...\n")),(0,r.kt)("p",null,"In the example above, a project with the name ",(0,r.kt)("inlineCode",{parentName:"p"},"helloworld")," will have the monitoring settings where ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"False"),", a 2 minute scraping interval, 15 seconds timeout (coming from default) and http scheme (coming from default)."),(0,r.kt)("p",null,"You cannot have the same project appear in two projectSelectors."),(0,r.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,r.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/monitoring/prometheus"},"workspace reference"),"."),(0,r.kt)("h2",{id:"updating-the-workspace-config"},"Updating the workspace config"),(0,r.kt)("p",null,"Assuming you now have a ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," that looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"Update the workspace configuration by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"Verify the workspace config is properly updated by running the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace show dev\n")),(0,r.kt)("h2",{id:"using-kusion-to-deploy-your-application-with-monitoring-requirements"},"Using kusion to deploy your application with monitoring requirements"),(0,r.kt)("p",null,"At this point we are set up for good! Any new applications you deploy via kusion will now automatically have the monitoring-related resources created, should you declare you want it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model."),(0,r.kt)("p",null,"The monitoring in an AppConfiguration is declared in the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field. See the example below for a full, deployable AppConfiguration."),(0,r.kt)("p",null,"Please note we are using a new image ",(0,r.kt)("inlineCode",{parentName:"p"},"quay.io/brancz/prometheus-example-app")," since the app itself need to expose metrics for Prometheus to scrape:"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/kcl.mod"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'[package]\nname = "helloworld"\n\n[dependencies]\nmonitoring = { oci = "oci://ghcr.io/kusionstack/monitoring", tag = "0.1.0" }\nkam = { git = "https://github.com/KusionStack/kam.git", tag = "0.1.0" }\n\n[profile]\nentries = ["main.k"]\n')),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport monitoring as m\nimport network.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "monitoring-sample-app": c.Container {\n image: "quay.io/brancz/prometheus-example-app:v0.3.0"\n }\n }\n }\n # Add the monitoring configuration backed by Prometheus\n accessories: {\n "monitoring": m.Prometheus {\n path: "/metrics"\n }\n "network": n.Network {\n ports: [\n n.Port {\n port: 8080\n }\n ]\n }\n }\n}\n')),(0,r.kt)("p",null,"The KCL file above represents an application with a service type workload, exposing the port 8080, and would like Prometheus to scrape the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint every 2 minutes."),(0,r.kt)("p",null,"Running ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply")," would show that kusion will create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," and a ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor"),":\n",(0,r.kt)("img",{alt:"kusion-apply-with-monitor",src:o(448).Z,width:"705",height:"224"})),(0,r.kt)("p",null,"Continue applying all resources:\n",(0,r.kt)("img",{alt:"kusion-apply-success",src:o(56816).Z,width:"1047",height:"564"})),(0,r.kt)("p",null,"If we want to, we can verify the service monitor has been created successfully:\n",(0,r.kt)("img",{alt:"service-monitor",src:o(58232).Z,width:"693",height:"463"})),(0,r.kt)("p",null,"In a few seconds, you should be able to see in the Prometheus portal that the service we just deployed has now been discovered and monitored by Prometheus:\n",(0,r.kt)("img",{alt:"prometheus-targets",src:o(81187).Z,width:"2880",height:"1636"})),(0,r.kt)("p",null,"You can run a few simply queries for the data that Prometheus scraped from your application:\n",(0,r.kt)("img",{alt:"prometheus-simple-query",src:o(87695).Z,width:"2880",height:"1634"})),(0,r.kt)("p",null,"For more info about PromQL, you can find them ",(0,r.kt)("a",{parentName:"p",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"here"),(0,r.kt)("sup",null,"[4]"),"."),(0,r.kt)("h2",{id:"references"},"References"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Prometheus: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"https://prometheus.io/docs/introduction/overview/")),(0,r.kt)("li",{parentName:"ol"},"Prometheus team advise: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500"},"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500")),(0,r.kt)("li",{parentName:"ol"},"Prometheus operator getting started doc: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md"},"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md")),(0,r.kt)("li",{parentName:"ol"},"PromQL basics: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"https://prometheus.io/docs/prometheus/latest/querying/basics/"))))}m.isMDXComponent=!0},56816:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-success-52d04db670fd184959c3ea5c9e54f69d.png"},448:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-with-monitor-d27cd1443e1a324d514983d52c055b15.png"},91512:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-operated-4cf8308703e4ec9d06a5078bbceb8d5d.png"},35443:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-portal-b60d8654c309e675fc04f1e74c5c127a.png"},87695:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-simple-query-60205589e762105ebc850e70d8ea7b56.png"},81187:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-targets-05964bad58af16f2e02c57cafa8565e7.png"},58232:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/service-monitor-2374625bfd1180a978a2be50ad4648ce.png"}}]); \ No newline at end of file diff --git a/assets/js/6b830420.b5fd3075.js b/assets/js/6b830420.b5fd3075.js deleted file mode 100644 index 8043c93b753..00000000000 --- a/assets/js/6b830420.b5fd3075.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[992],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>h});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function i(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=l(o),h=r,d=c["".concat(p,".").concat(h)]||c[h]||m[h]||a;return o?n.createElement(d,i(i({ref:t},u),{},{components:o})):n.createElement(d,i({ref:t},u))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=o.length,i=new Array(a);i[0]=c;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=o(87462),r=(o(67294),o(3905));const a={},i="Configure Monitoring Behavior With Prometheus",s={unversionedId:"kusion/user-guides/observability/prometheus",id:"kusion/user-guides/observability/prometheus",title:"Configure Monitoring Behavior With Prometheus",description:"This document provides the step-by-step instruction to set up monitoring for your application.",source:"@site/docs/kusion/5-user-guides/3-observability/1-prometheus.md",sourceDirName:"kusion/5-user-guides/3-observability",slug:"/kusion/user-guides/observability/prometheus",permalink:"/docs/next/kusion/user-guides/observability/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/3-observability/1-prometheus.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Schedule a Job",permalink:"/docs/next/kusion/user-guides/working-with-k8s/job"},next:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions"}},p={},l=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Setting up your own Prometheus",id:"setting-up-your-own-prometheus",level:2},{value:"Installing Prometheus operator3.",id:"installing-prometheus-operator3",level:3},{value:"Make sure RBAC is properly set up",id:"make-sure-rbac-is-properly-set-up",level:3},{value:"Configure Prometheus instance via the operator",id:"configure-prometheus-instance-via-the-operator",level:3},{value:"Exposing the Prometheus portal (optional)",id:"exposing-the-prometheus-portal-optional",level:3},{value:"Setting up workspace configs",id:"setting-up-workspace-configs",level:2},{value:"Operator mode",id:"operator-mode",level:3},{value:"Monitor types",id:"monitor-types",level:3},{value:"Overriding with projectSelector",id:"overriding-with-projectselector",level:3},{value:"Updating the workspace config",id:"updating-the-workspace-config",level:2},{value:"Using kusion to deploy your application with monitoring requirements",id:"using-kusion-to-deploy-your-application-with-monitoring-requirements",level:2},{value:"References",id:"references",level:2}],u={toc:l};function m(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-monitoring-behavior-with-prometheus"},"Configure Monitoring Behavior With Prometheus"),(0,r.kt)("p",null,"This document provides the step-by-step instruction to set up monitoring for your application. "),(0,r.kt)("p",null,"As of today, Kusion supports the configuration of Prometheus scraping behaviors for the target application. In the future, we will add more cloud-provider-native solutions, such as AWS CloudWatch, Azure Monitor, etc."),(0,r.kt)("p",null,"The user guide below is composed of the following components:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Namespace"),(0,r.kt)("li",{parentName:"ul"},"Deployment"),(0,r.kt)("li",{parentName:"ul"},"Service"),(0,r.kt)("li",{parentName:"ul"},"ServiceMonitor")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes and Prometheus.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"Prometheus Introduction")))),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"setting-up-your-own-prometheus"},"Setting up your own Prometheus"),(0,r.kt)("p",null,"There a quite a few ways to set up Prometheus in your cluster:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus operator"),(0,r.kt)("li",{parentName:"ol"},"Installing a standalone Prometheus server"),(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus agent and connect to a remote Prometheus server")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-401092041"},"The advice from the Prometheus team")," is to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"PodMonitor")," CRs via the Prometheus operator to manage scrape configs going forward",(0,r.kt)("sup",null,"[2]"),"."),(0,r.kt)("p",null,"In either case, you only have to do this setup once per cluster. This doc will use a minikube cluster and Prometheus operator as an example."),(0,r.kt)("h3",{id:"installing-prometheus-operator3"},"Installing Prometheus operator",(0,r.kt)("sup",null,"[3]"),"."),(0,r.kt)("p",null,"To get the example in this user guide working, all you need is a running Prometheus operator. You can have that installed by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)\ncurl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f -\n")),(0,r.kt)("p",null,"This will install all the necessary CRDs and the Prometheus operator itself in the default namespace. Wait a few minutes, you can confirm the operator is up by running: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl wait --for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n default\n")),(0,r.kt)("h3",{id:"make-sure-rbac-is-properly-set-up"},"Make sure RBAC is properly set up"),(0,r.kt)("p",null,"If you have RBAC enabled on the cluster, the following must be created for Prometheus to work properly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: prometheus\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: prometheus\nrules:\n- apiGroups: [""]\n resources:\n - nodes\n - nodes/metrics\n - services\n - endpoints\n - pods\n verbs: ["get", "list", "watch"]\n- apiGroups: [""]\n resources:\n - configmaps\n verbs: ["get"]\n- apiGroups:\n - networking.k8s.io\n resources:\n - ingresses\n verbs: ["get", "list", "watch"]\n- nonResourceURLs: ["/metrics"]\n verbs: ["get"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n name: prometheus\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus\nsubjects:\n- kind: ServiceAccount\n name: prometheus\n namespace: default\n')),(0,r.kt)("h3",{id:"configure-prometheus-instance-via-the-operator"},"Configure Prometheus instance via the operator"),(0,r.kt)("p",null,"Once all of the above is set up, you can then configure the Prometheus instance via the operator:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n name: prometheus\nspec:\n serviceAccountName: prometheus\n serviceMonitorNamespaceSelector: {}\n serviceMonitorSelector: {}\n podMonitorNamespaceSelector: {}\n podMonitorSelector: {}\n resources:\n requests:\n memory: 400Mi\n")),(0,r.kt)("p",null,"This Prometheus instance above will be cluster-wide, picking up ALL the service monitors and pod monitors across ALL the namespaces.\nYou can adjust the requests and limits accordingly if you have a larger cluster."),(0,r.kt)("h3",{id:"exposing-the-prometheus-portal-optional"},"Exposing the Prometheus portal (optional)"),(0,r.kt)("p",null,"Once you have the managed Prometheus instance created via the Prometheus CR above, you should be able to see a service created called ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus-operated"),":"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-operated",src:o(91512).Z,width:"631",height:"52"})),(0,r.kt)("p",null,"If you are also running on minikube, you can expose it onto your localhost via kubectl:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/prometheus-operated 9099:9090\n")),(0,r.kt)("p",null,"You should then be able to see the Prometheus portal via ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost:9099")," in your browser:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-portal",src:o(35443).Z,width:"2878",height:"1096"})),(0,r.kt)("p",null,"If you are running a non-local cluster, you can try to expose it via another way, through an ingress controller for example."),(0,r.kt)("h2",{id:"setting-up-workspace-configs"},"Setting up workspace configs"),(0,r.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,r.kt)("p",null,"In the case of setting up Prometheus, there are a few things to set up on the workspace level:"),(0,r.kt)("h3",{id:"operator-mode"},"Operator mode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," flag indicates to Kusion whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,r.kt)("p",null,"To see more about different ways to run Prometheus in the Kubernetes cluster, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md#prometheus-installation"},"design documentation"),"."),(0,r.kt)("p",null,"Most cloud vendors provide an out-of-the-box monitoring solutions for workloads running in a managed-Kubernetes cluster (EKS, AKS, etc), such as AWS CloudWatch, Azure Monitor, etc. These solutions mostly involve installing an agent (CloudWatch Agent, OMS Agent, etc) in the cluster and collecting the metrics to a centralized monitoring server. In those cases, you don't need to set ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". It only needs to be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when you have an installation of the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator")," running inside the Kubernetes cluster."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For differences between ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/kube-prometheus"},"kube-prometheus")," and the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack"},"community kube-prometheus-stack helm chart"),", the details are documented ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator#prometheus-operator-vs-kube-prometheus-vs-community-helm-chart"},"here"),".")),(0,r.kt)("h3",{id:"monitor-types"},"Monitor types"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitorType")," flag indicates the kind of monitor Kusion will create. It only applies when ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". As of version 0.10.0, Kusion provides options to scrape metrics from either the application pods or its corresponding Kubernetes services. This determines the different kinds of resources Kusion manages when Prometheus runs as an operator in the target cluster."),(0,r.kt)("p",null,"A sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with Prometheus settings:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n ...\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"To instruct Prometheus to scrape from pod targets instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n ...\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is omitted from the ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", Kusion defaults ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to false."),(0,r.kt)("h3",{id:"overriding-with-projectselector"},"Overriding with projectSelector"),(0,r.kt)("p",null,"Workspace configurations contain a set of default setting group for all projects in the workspace, with means to override them by Projects using a ",(0,r.kt)("inlineCode",{parentName:"p"},"projectSelector")," keyword."),(0,r.kt)("p",null,"Projects with the name matching those in projectSelector will use the values defined in that override group instead of the default. If a key is not present in the override group, the default value will be used."),(0,r.kt)("p",null,"Take a look at the sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n ...\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n projectSelector:\n - foobar\n high_frequency:\n monitorType: Service\n projectSelector:\n - helloworld\n...\n")),(0,r.kt)("p",null,"In the example above, a project with the name ",(0,r.kt)("inlineCode",{parentName:"p"},"helloworld")," will have the monitoring settings where ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"False"),", a 2 minute scraping interval, 15 seconds timeout (coming from default) and http scheme (coming from default)."),(0,r.kt)("p",null,"You cannot have the same project appear in two projectSelectors."),(0,r.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,r.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/monitoring/prometheus"},"workspace reference"),"."),(0,r.kt)("h2",{id:"updating-the-workspace-config"},"Updating the workspace config"),(0,r.kt)("p",null,"Assuming you now have a ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," that looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n kusionstack/monitoring@0.1.0:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"Update the workspace configuration by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"Verify the workspace config is properly updated by running the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace show dev\n")),(0,r.kt)("h2",{id:"using-kusion-to-deploy-your-application-with-monitoring-requirements"},"Using kusion to deploy your application with monitoring requirements"),(0,r.kt)("p",null,"At this point we are set up for good! Any new applications you deploy via kusion will now automatically have the monitoring-related resources created, should you declare you want it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model."),(0,r.kt)("p",null,"The monitoring in an AppConfiguration is declared in the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field. See the example below for a full, deployable AppConfiguration."),(0,r.kt)("p",null,"Please note we are using a new image ",(0,r.kt)("inlineCode",{parentName:"p"},"quay.io/brancz/prometheus-example-app")," since the app itself need to expose metrics for Prometheus to scrape:"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/kcl.mod"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'[package]\nname = "helloworld"\n\n[dependencies]\nmonitoring = { oci = "oci://ghcr.io/kusionstack/monitoring", tag = "0.1.0" }\nkam = { git = "https://github.com/KusionStack/kam.git", tag = "0.1.0" }\n\n[profile]\nentries = ["main.k"]\n')),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport monitoring as m\nimport network.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "monitoring-sample-app": c.Container {\n image: "quay.io/brancz/prometheus-example-app:v0.3.0"\n }\n }\n }\n # Add the monitoring configuration backed by Prometheus\n accessories: {\n "monitoring": m.Prometheus {\n path: "/metrics"\n }\n "network": n.Network {\n ports: [\n n.Port {\n port: 8080\n }\n ]\n }\n }\n}\n')),(0,r.kt)("p",null,"The KCL file above represents an application with a service type workload, exposing the port 8080, and would like Prometheus to scrape the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint every 2 minutes."),(0,r.kt)("p",null,"Running ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply")," would show that kusion will create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," and a ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor"),":\n",(0,r.kt)("img",{alt:"kusion-apply-with-monitor",src:o(448).Z,width:"705",height:"224"})),(0,r.kt)("p",null,"Continue applying all resources:\n",(0,r.kt)("img",{alt:"kusion-apply-success",src:o(56816).Z,width:"1047",height:"564"})),(0,r.kt)("p",null,"If we want to, we can verify the service monitor has been created successfully:\n",(0,r.kt)("img",{alt:"service-monitor",src:o(58232).Z,width:"693",height:"463"})),(0,r.kt)("p",null,"In a few seconds, you should be able to see in the Prometheus portal that the service we just deployed has now been discovered and monitored by Prometheus:\n",(0,r.kt)("img",{alt:"prometheus-targets",src:o(81187).Z,width:"2880",height:"1636"})),(0,r.kt)("p",null,"You can run a few simply queries for the data that Prometheus scraped from your application:\n",(0,r.kt)("img",{alt:"prometheus-simple-query",src:o(87695).Z,width:"2880",height:"1634"})),(0,r.kt)("p",null,"For more info about PromQL, you can find them ",(0,r.kt)("a",{parentName:"p",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"here"),(0,r.kt)("sup",null,"[4]"),"."),(0,r.kt)("h2",{id:"references"},"References"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Prometheus: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"https://prometheus.io/docs/introduction/overview/")),(0,r.kt)("li",{parentName:"ol"},"Prometheus team advise: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500"},"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500")),(0,r.kt)("li",{parentName:"ol"},"Prometheus operator getting started doc: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md"},"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md")),(0,r.kt)("li",{parentName:"ol"},"PromQL basics: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"https://prometheus.io/docs/prometheus/latest/querying/basics/"))))}m.isMDXComponent=!0},56816:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-success-52d04db670fd184959c3ea5c9e54f69d.png"},448:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-with-monitor-d27cd1443e1a324d514983d52c055b15.png"},91512:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-operated-4cf8308703e4ec9d06a5078bbceb8d5d.png"},35443:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-portal-b60d8654c309e675fc04f1e74c5c127a.png"},87695:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-simple-query-60205589e762105ebc850e70d8ea7b56.png"},81187:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-targets-05964bad58af16f2e02c57cafa8565e7.png"},58232:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/service-monitor-2374625bfd1180a978a2be50ad4648ce.png"}}]); \ No newline at end of file diff --git a/assets/js/6eb5e412.5292b49c.js b/assets/js/6eb5e412.5292b49c.js new file mode 100644 index 00000000000..617e666d6d1 --- /dev/null +++ b/assets/js/6eb5e412.5292b49c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7573],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>f});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=o.createContext({}),l=function(e){var n=o.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},u=function(e){var n=l(e.components);return o.createElement(c.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(t),f=i,h=d["".concat(c,".").concat(f)]||d[f]||p[f]||r;return t?o.createElement(h,a(a({ref:n},u),{},{components:t})):o.createElement(h,a({ref:n},u))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,a=new Array(r);a[0]=d;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=t(87462),i=(t(67294),t(3905));const r={id:"intent",sidebar_label:"Intent"},a="Intent",s={unversionedId:"kusion/concepts/intent",id:"version-v0.10/kusion/concepts/intent",title:"Intent",description:"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/6-intent.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/intent",permalink:"/docs/kusion/concepts/intent",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/6-intent.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"intent",sidebar_label:"Intent"},sidebar:"kusion",previous:{title:"AppConfiguration",permalink:"/docs/kusion/concepts/app-configuration"},next:{title:"Backend Configuration",permalink:"/docs/kusion/concepts/backend-configuration"}},c={},l=[{value:"Purpose",id:"purpose",level:2},{value:"Single Source of Truth",id:"single-source-of-truth",level:3},{value:"Consistency",id:"consistency",level:3},{value:"Rollback and Disaster Recovery",id:"rollback-and-disaster-recovery",level:3}],u={toc:l};function p(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"intent"},"Intent"),(0,i.kt)("p",null,"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent."),(0,i.kt)("h2",{id:"purpose"},"Purpose"),(0,i.kt)("h3",{id:"single-source-of-truth"},"Single Source of Truth"),(0,i.kt)("p",null,"In Kusion's workflow, the platform engineer builds Kusion modules and provides environment configurations, application developers choose Kusion modules they need and deploy operational intentions to an environment with related environment configurations. They can also input dynamic parameters like the container image when executing the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," command. So the final operational intentions include configurations written by application developers, environment configurations and dynamic inputs. Due to this reason, we introduce ",(0,i.kt)("strong",{parentName:"p"},"Intent")," to represent the SSoT(Single Source of Truth) of Kusion. It is the result of ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," which contains all operational intentions from different sources."),(0,i.kt)("h3",{id:"consistency"},"Consistency"),(0,i.kt)("p",null,"Delivering an application to different environments with identical configurations is a common practice, especially for applications that require scalable distribution. In such cases, an immutable configuration package is helpful. By utilizing the Intent, all configurations and changes are stored in a single file. As the Intent is the input of Kusion, it ensures consistency across different environments whenever you execute Kusion with the same Intent file."),(0,i.kt)("h3",{id:"rollback-and-disaster-recovery"},"Rollback and Disaster Recovery"),(0,i.kt)("p",null,"The ability to roll back is crucial in reducing incident duration. Rolling back the system to a previously validated version is much faster compared to attempting to fix it during an outage. We regard a validated Intent as a snapshot of the system and recommend storing the Intent in a version control system like Git. This enables better change management practices and makes it simpler to roll back to previous versions if needed. In case of a failure or outage, having a validated Intent simplifies the rollback process, ensuring that the system can be quickly recovered."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6eb5e412.84c97c04.js b/assets/js/6eb5e412.84c97c04.js deleted file mode 100644 index 117301f6dc0..00000000000 --- a/assets/js/6eb5e412.84c97c04.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7573],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>f});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=o.createContext({}),l=function(e){var n=o.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},u=function(e){var n=l(e.components);return o.createElement(c.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(t),f=i,h=d["".concat(c,".").concat(f)]||d[f]||p[f]||r;return t?o.createElement(h,a(a({ref:n},u),{},{components:t})):o.createElement(h,a({ref:n},u))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,a=new Array(r);a[0]=d;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=t(87462),i=(t(67294),t(3905));const r={id:"intent",sidebar_label:"Intent"},a="Intent",s={unversionedId:"kusion/concepts/intent",id:"version-v0.10/kusion/concepts/intent",title:"Intent",description:"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/6-intent.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/intent",permalink:"/docs/kusion/concepts/intent",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/6-intent.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"intent",sidebar_label:"Intent"},sidebar:"kusion",previous:{title:"AppConfiguration",permalink:"/docs/kusion/concepts/app-configuration"},next:{title:"Backend Configuration",permalink:"/docs/kusion/concepts/backend-configuration"}},c={},l=[{value:"Purpose",id:"purpose",level:2},{value:"Single Source of Truth",id:"single-source-of-truth",level:3},{value:"Consistency",id:"consistency",level:3},{value:"Rollback and Disaster Recovery",id:"rollback-and-disaster-recovery",level:3}],u={toc:l};function p(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"intent"},"Intent"),(0,i.kt)("p",null,"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent."),(0,i.kt)("h2",{id:"purpose"},"Purpose"),(0,i.kt)("h3",{id:"single-source-of-truth"},"Single Source of Truth"),(0,i.kt)("p",null,"In Kusion's workflow, the platform engineer builds Kusion modules and provides environment configurations, application developers choose Kusion modules they need and deploy operational intentions to an environment with related environment configurations. They can also input dynamic parameters like the container image when executing the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," command. So the final operational intentions include configurations written by application developers, environment configurations and dynamic inputs. Due to this reason, we introduce ",(0,i.kt)("strong",{parentName:"p"},"Intent")," to represent the SSoT(Single Source of Truth) of Kusion. It is the result of ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," which contains all operational intentions from different sources."),(0,i.kt)("h3",{id:"consistency"},"Consistency"),(0,i.kt)("p",null,"Delivering an application to different environments with identical configurations is a common practice, especially for applications that require scalable distribution. In such cases, an immutable configuration package is helpful. By utilizing the Intent, all configurations and changes are stored in a single file. As the Intent is the input of Kusion, it ensures consistency across different environments whenever you execute Kusion with the same Intent file."),(0,i.kt)("h3",{id:"rollback-and-disaster-recovery"},"Rollback and Disaster Recovery"),(0,i.kt)("p",null,"The ability to roll back is crucial in reducing incident duration. Rolling back the system to a previously validated version is much faster compared to attempting to fix it during an outage. We regard a validated Intent as a snapshot of the system and recommend storing the Intent in a version control system like Git. This enables better change management practices and makes it simpler to roll back to previous versions if needed. In case of a failure or outage, having a validated Intent simplifies the rollback process, ensuring that the system can be quickly recovered."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6ece4ae7.c4c6fb3f.js b/assets/js/6ece4ae7.c4c6fb3f.js new file mode 100644 index 00000000000..1ca845cb27c --- /dev/null +++ b/assets/js/6ece4ae7.c4c6fb3f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8873],{3905:(e,r,n)=>{n.d(r,{Zo:()=>u,kt:()=>f});var t=n(67294);function o(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function i(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function a(e){for(var r=1;r=0||(o[n]=e[n]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=t.createContext({}),l=function(e){var r=t.useContext(s),n=r;return e&&(n="function"==typeof e?e(r):a(a({},r),e)),n},u=function(e){var r=l(e.components);return t.createElement(s.Provider,{value:r},e.children)},d={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},p=t.forwardRef((function(e,r){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(n),f=o,m=p["".concat(s,".").concat(f)]||p[f]||d[f]||i;return n?t.createElement(m,a(a({ref:r},u),{},{components:n})):t.createElement(m,a({ref:r},u))}));function f(e,r){var n=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=p;var c={};for(var s in r)hasOwnProperty.call(r,s)&&(c[s]=r[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(r),n.d(r,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=n(87462),o=(n(67294),n(3905));const i={},a="Kusion Model Library",c={unversionedId:"kusion/reference/model/index",id:"version-v0.9/kusion/reference/model/index",title:"Kusion Model Library",description:"",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/index.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/",permalink:"/docs/v0.9/kusion/reference/model/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/index.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Backend Configuration",permalink:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration"},next:{title:"Overview",permalink:"/docs/v0.9/kusion/reference/model/overview"}},s={},l=[],u={toc:l};function d(e){let{components:r,...n}=e;return(0,o.kt)("wrapper",(0,t.Z)({},u,n,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-model-library"},"Kusion Model Library"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6ece4ae7.ea904ef8.js b/assets/js/6ece4ae7.ea904ef8.js deleted file mode 100644 index 82a72ea1a73..00000000000 --- a/assets/js/6ece4ae7.ea904ef8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8873],{3905:(e,r,t)=>{t.d(r,{Zo:()=>u,kt:()=>f});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=n.createContext({}),l=function(e){var r=n.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},u=function(e){var r=l(e.components);return n.createElement(s.Provider,{value:r},e.children)},d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},p=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(t),f=o,m=p["".concat(s,".").concat(f)]||p[f]||d[f]||i;return t?n.createElement(m,a(a({ref:r},u),{},{components:t})):n.createElement(m,a({ref:r},u))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=p;var c={};for(var s in r)hasOwnProperty.call(r,s)&&(c[s]=r[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,a[1]=c;for(var l=2;l{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=t(87462),o=(t(67294),t(3905));const i={},a="Kusion Model Library",c={unversionedId:"kusion/reference/model/index",id:"version-v0.9/kusion/reference/model/index",title:"Kusion Model Library",description:"",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/index.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/",permalink:"/docs/v0.9/kusion/reference/model/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/index.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Backend Configuration",permalink:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration"},next:{title:"Overview",permalink:"/docs/v0.9/kusion/reference/model/overview"}},s={},l=[],u={toc:l};function d(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-model-library"},"Kusion Model Library"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6fb6dfc9.71c1905c.js b/assets/js/6fb6dfc9.71c1905c.js new file mode 100644 index 00000000000..e3ef0e03709 --- /dev/null +++ b/assets/js/6fb6dfc9.71c1905c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9440],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion apply",s={unversionedId:"kusion/reference/commands/kusion-apply",id:"kusion/reference/commands/kusion-apply",title:"kusion apply",description:"Apply the operational intent of various resources to multiple runtimes",source:"@site/docs/kusion/6-reference/1-commands/kusion-apply.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-apply",permalink:"/docs/next/kusion/reference/commands/kusion-apply",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-apply.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Commands",permalink:"/docs/next/kusion/reference/commands/"},next:{title:"kusion build",permalink:"/docs/next/kusion/reference/commands/kusion-build"}},p={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-apply"},"kusion apply"),(0,o.kt)("p",null,"Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Apply a series of resource changes within the stack."),(0,o.kt)("p",null," Create, update or delete resources according to the operational intent within a stack. By default, Kusion will generate an execution plan and prompt for your approval before performing any actions. You can review the plan details and make a decision to proceed with the actions or abort them."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion apply [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Apply with specified work directory\n kusion apply -w /path/to/workdir\n \n # Apply with specified arguments\n kusion apply -D name=test -D age=18\n \n # Apply with specified intent file\n kusion apply --intent-file intent.yaml\n \n # Apply with specifying intent file\n kusion apply --intent-file intent.yaml\n \n # Skip interactive approval of plan details before applying\n kusion apply --yes\n \n # Apply without output style and color\n kusion apply --no-style=true\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n --dry-run Preview the execution effect (always successful) without actually applying the changes\n -h, --help help for apply\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n --watch After creating/updating/deleting the requested object, watch for changes\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6fb6dfc9.e8920cf5.js b/assets/js/6fb6dfc9.e8920cf5.js deleted file mode 100644 index 8d5a8b30150..00000000000 --- a/assets/js/6fb6dfc9.e8920cf5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9440],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),l=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion apply",s={unversionedId:"kusion/reference/commands/kusion-apply",id:"kusion/reference/commands/kusion-apply",title:"kusion apply",description:"Apply the operational intent of various resources to multiple runtimes",source:"@site/docs/kusion/6-reference/1-commands/kusion-apply.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-apply",permalink:"/docs/next/kusion/reference/commands/kusion-apply",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-apply.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Commands",permalink:"/docs/next/kusion/reference/commands/"},next:{title:"kusion build",permalink:"/docs/next/kusion/reference/commands/kusion-build"}},p={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-apply"},"kusion apply"),(0,o.kt)("p",null,"Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Apply a series of resource changes within the stack."),(0,o.kt)("p",null," Create, update or delete resources according to the operational intent within a stack. By default, Kusion will generate an execution plan and prompt for your approval before performing any actions. You can review the plan details and make a decision to proceed with the actions or abort them."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion apply [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Apply with specified work directory\n kusion apply -w /path/to/workdir\n \n # Apply with specified arguments\n kusion apply -D name=test -D age=18\n \n # Apply with specified intent file\n kusion apply --intent-file intent.yaml\n \n # Apply with specifying intent file\n kusion apply --intent-file intent.yaml\n \n # Skip interactive approval of plan details before applying\n kusion apply --yes\n \n # Apply without output style and color\n kusion apply --no-style=true\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n --dry-run Preview the execution effect (always successful) without actually applying the changes\n -h, --help help for apply\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n --watch After creating/updating/deleting the requested object, watch for changes\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7062af80.1c782dc5.js b/assets/js/7062af80.0f6b4260.js similarity index 68% rename from assets/js/7062af80.1c782dc5.js rename to assets/js/7062af80.0f6b4260.js index fa4169369d4..bf9ffe0a837 100644 --- a/assets/js/7062af80.1c782dc5.js +++ b/assets/js/7062af80.0f6b4260.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3332],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var a=r.createContext({}),l=function(e){var t=r.useContext(a),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(a.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,c=e.originalType,a=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(a,".").concat(m)]||d[m]||p[m]||c;return n?r.createElement(f,i(i({ref:t},u),{},{components:n})):r.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var c=n.length,i=new Array(c);i[0]=d;var s={};for(var a in t)hasOwnProperty.call(t,a)&&(s[a]=t[a]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>x,contentTitle:()=>O,default:()=>N,frontMatter:()=>w,metadata:()=>E,toc:()=>j});var r=n(87462),o=n(67294),c=n(3905),i=n(86010),s=n(53438),a=n(39960),l=n(13919),u=n(95999);const p="cardContainer_fWXF",d="cardTitle_rnsV",m="cardDescription_PWke";function f(e){let{href:t,children:n}=e;return o.createElement(a.Z,{href:t,className:(0,i.Z)("card padding--lg",p)},n)}function y(e){let{href:t,icon:n,title:r,description:c}=e;return o.createElement(f,{href:t},o.createElement("h2",{className:(0,i.Z)("text--truncate",d),title:r},n," ",r),c&&o.createElement("p",{className:(0,i.Z)("text--truncate",m),title:c},c))}function h(e){let{item:t}=e;const n=(0,s.Wl)(t);return n?o.createElement(y,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??(0,u.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function v(e){let{item:t}=e;const n=(0,l.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,s.xz)(t.docId??void 0);return o.createElement(y,{href:t.href,icon:n,title:t.label,description:t.description??(null==r?void 0:r.description)})}function b(e){let{item:t}=e;switch(t.type){case"link":return o.createElement(v,{item:t});case"category":return o.createElement(h,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function g(e){let{className:t}=e;const n=(0,s.jA)();return o.createElement(k,{items:n.items,className:t})}function k(e){const{items:t,className:n}=e;if(!t)return o.createElement(g,e);const r=(0,s.MN)(t);return o.createElement("section",{className:(0,i.Z)("row",n)},r.map(((e,t)=>o.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},o.createElement(b,{item:e})))))}const w={},O="Concepts",E={unversionedId:"kusion/concepts/index",id:"version-v0.9/kusion/concepts/index",title:"Concepts",description:"In this section, we will introduce the architecture of KusionStack and some core concepts.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/index.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/",permalink:"/docs/v0.9/kusion/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/index.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/v0.9/kusion/getting-started/deliver-wordpress"},next:{title:"Architecture",permalink:"/docs/v0.9/kusion/concepts/arch"}},x={},j=[],P={toc:j};function N(e){let{components:t,...n}=e;return(0,c.kt)("wrapper",(0,r.Z)({},P,n,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"concepts"},"Concepts"),(0,c.kt)("p",null,"In this section, we will introduce the architecture of KusionStack and some core concepts."),(0,c.kt)(k,{mdxType:"DocCardList"}))}N.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3332],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,c=e.originalType,s=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(s,".").concat(m)]||d[m]||p[m]||c;return n?r.createElement(f,i(i({ref:t},u),{},{components:n})):r.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var c=n.length,i=new Array(c);i[0]=d;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a.mdxType="string"==typeof e?e:o,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>x,contentTitle:()=>O,default:()=>N,frontMatter:()=>w,metadata:()=>E,toc:()=>j});var r=n(87462),o=n(67294),c=n(3905),i=n(86010),a=n(53438),s=n(39960),l=n(13919),u=n(95999);const p="cardContainer_fWXF",d="cardTitle_rnsV",m="cardDescription_PWke";function f(e){let{href:t,children:n}=e;return o.createElement(s.Z,{href:t,className:(0,i.Z)("card padding--lg",p)},n)}function y(e){let{href:t,icon:n,title:r,description:c}=e;return o.createElement(f,{href:t},o.createElement("h2",{className:(0,i.Z)("text--truncate",d),title:r},n," ",r),c&&o.createElement("p",{className:(0,i.Z)("text--truncate",m),title:c},c))}function h(e){let{item:t}=e;const n=(0,a.Wl)(t);return n?o.createElement(y,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??(0,u.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function v(e){let{item:t}=e;const n=(0,l.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,a.xz)(t.docId??void 0);return o.createElement(y,{href:t.href,icon:n,title:t.label,description:t.description??(null==r?void 0:r.description)})}function b(e){let{item:t}=e;switch(t.type){case"link":return o.createElement(v,{item:t});case"category":return o.createElement(h,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function g(e){let{className:t}=e;const n=(0,a.jA)();return o.createElement(k,{items:n.items,className:t})}function k(e){const{items:t,className:n}=e;if(!t)return o.createElement(g,e);const r=(0,a.MN)(t);return o.createElement("section",{className:(0,i.Z)("row",n)},r.map(((e,t)=>o.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},o.createElement(b,{item:e})))))}const w={},O="Concepts",E={unversionedId:"kusion/concepts/index",id:"version-v0.9/kusion/concepts/index",title:"Concepts",description:"In this section, we will introduce the architecture of KusionStack and some core concepts.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/index.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/",permalink:"/docs/v0.9/kusion/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/index.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application on Kubernetes",permalink:"/docs/v0.9/kusion/getting-started/deliver-wordpress"},next:{title:"Architecture",permalink:"/docs/v0.9/kusion/concepts/arch"}},x={},j=[],P={toc:j};function N(e){let{components:t,...n}=e;return(0,c.kt)("wrapper",(0,r.Z)({},P,n,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"concepts"},"Concepts"),(0,c.kt)("p",null,"In this section, we will introduce the architecture of KusionStack and some core concepts."),(0,c.kt)(k,{mdxType:"DocCardList"}))}N.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/70dfc3b7.490b71e4.js b/assets/js/70dfc3b7.490b71e4.js deleted file mode 100644 index 06f8a03cfd9..00000000000 --- a/assets/js/70dfc3b7.490b71e4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2481],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),f=i,m=d["".concat(l,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion preview",s={unversionedId:"kusion/reference/commands/kusion-preview",id:"version-v0.10/kusion/reference/commands/kusion-preview",title:"kusion preview",description:"Preview a series of resource changes within the stack",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-preview.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-preview",permalink:"/docs/kusion/reference/commands/kusion-preview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-preview.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion init",permalink:"/docs/kusion/reference/commands/kusion-init"},next:{title:"kusion version",permalink:"/docs/kusion/reference/commands/kusion-version"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-preview"},"kusion preview"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack."),(0,i.kt)("p",null," Create, update or delete resources according to the intent described in the a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion preview [flags]\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' # Preview with specified work directory\n kusion preview -w /path/to/workdir\n \n # Preview with specified arguments\n kusion preview -D name=test -D age=18\n \n # Preview with specified intent file\n kusion preview --intent-file intent.yaml\n \n # Preview with ignored fields\n kusion preview --ignore-fields="metadata.generation,metadata.managedFields\n \n # Preview with json format result\n kusion preview -o json\n \n # Preview without output style and color\n kusion preview --no-style=true\n')),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n -h, --help help for preview\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/70dfc3b7.97f702cd.js b/assets/js/70dfc3b7.97f702cd.js new file mode 100644 index 00000000000..5e6b7896e38 --- /dev/null +++ b/assets/js/70dfc3b7.97f702cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2481],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),f=i,m=d["".concat(l,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(m,a(a({ref:t},c),{},{components:n})):r.createElement(m,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion preview",s={unversionedId:"kusion/reference/commands/kusion-preview",id:"version-v0.10/kusion/reference/commands/kusion-preview",title:"kusion preview",description:"Preview a series of resource changes within the stack",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-preview.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-preview",permalink:"/docs/kusion/reference/commands/kusion-preview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-preview.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion init",permalink:"/docs/kusion/reference/commands/kusion-init"},next:{title:"kusion version",permalink:"/docs/kusion/reference/commands/kusion-version"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-preview"},"kusion preview"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"Preview a series of resource changes within the stack."),(0,i.kt)("p",null," Create, update or delete resources according to the intent described in the a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion preview [flags]\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' # Preview with specified work directory\n kusion preview -w /path/to/workdir\n \n # Preview with specified arguments\n kusion preview -D name=test -D age=18\n \n # Preview with specified intent file\n kusion preview --intent-file intent.yaml\n \n # Preview with ignored fields\n kusion preview --ignore-fields="metadata.generation,metadata.managedFields\n \n # Preview with json format result\n kusion preview -o json\n \n # Preview without output style and color\n kusion preview --no-style=true\n')),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n -h, --help help for preview\n --ignore-fields strings Ignore differences of target fields\n --intent-file string Specify the intent file path as input, and the intent file must be located in the working directory or its subdirectories\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,i.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/70fd01e9.8b775c16.js b/assets/js/70fd01e9.af28bc51.js similarity index 69% rename from assets/js/70fd01e9.8b775c16.js rename to assets/js/70fd01e9.af28bc51.js index b3dbab6bfec..979d971eb89 100644 --- a/assets/js/70fd01e9.8b775c16.js +++ b/assets/js/70fd01e9.af28bc51.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2291],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),f=o,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||a;return n?r.createElement(m,i(i({ref:t},p),{},{components:n})):r.createElement(m,i({ref:t},p))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const a={sidebar_label:"Overview",id:"overview"},i="Overview",c={unversionedId:"kusion/concepts/stack/overview",id:"kusion/concepts/stack/overview",title:"Overview",description:"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production.",source:"@site/docs/kusion/3-concepts/2-stack/1-overview.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/overview",permalink:"/docs/next/kusion/concepts/stack/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/2-stack/1-overview.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Project Configuration",permalink:"/docs/next/kusion/concepts/project/configuration"},next:{title:"Stack Configuration",permalink:"/docs/next/kusion/concepts/stack/configuration"}},s={},l=[{value:"High Level Schema",id:"high-level-schema",level:2}],p={toc:l};function d(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"overview"},"Overview"),(0,o.kt)("p",null,"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production."),(0,o.kt)("h2",{id:"high-level-schema"},"High Level Schema"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"High_Level_Schema",src:n(4994).Z,width:"2390",height:"1487"})))}d.isMDXComponent=!0},4994:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/high-level-schema-ba34668ea6879003a582f15496c3ab6e.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2291],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),f=o,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||a;return n?r.createElement(m,i(i({ref:t},p),{},{components:n})):r.createElement(m,i({ref:t},p))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const a={sidebar_label:"Overview",id:"overview"},i="Overview",c={unversionedId:"kusion/concepts/stack/overview",id:"kusion/concepts/stack/overview",title:"Overview",description:"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production.",source:"@site/docs/kusion/3-concepts/2-stack/1-overview.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/overview",permalink:"/docs/next/kusion/concepts/stack/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/2-stack/1-overview.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_label:"Overview",id:"overview"},sidebar:"kusion",previous:{title:"Project Configuration",permalink:"/docs/next/kusion/concepts/project/configuration"},next:{title:"Stack Configuration",permalink:"/docs/next/kusion/concepts/stack/configuration"}},s={},l=[{value:"High Level Schema",id:"high-level-schema",level:2}],p={toc:l};function d(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"overview"},"Overview"),(0,o.kt)("p",null,"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production."),(0,o.kt)("h2",{id:"high-level-schema"},"High Level Schema"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"High_Level_Schema",src:n(4994).Z,width:"2390",height:"1487"})))}d.isMDXComponent=!0},4994:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/high-level-schema-ba34668ea6879003a582f15496c3ab6e.png"}}]); \ No newline at end of file diff --git a/assets/js/72ae1949.1864e971.js b/assets/js/72ae1949.1864e971.js new file mode 100644 index 00000000000..cc3fa7ee604 --- /dev/null +++ b/assets/js/72ae1949.1864e971.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4215],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=o.createContext({}),l=function(e){var t=o.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(u.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(u,".").concat(m)]||d[m]||c[m]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={},a="kusion build",s={unversionedId:"kusion/reference/commands/kusion-build",id:"version-v0.10/kusion/reference/commands/kusion-build",title:"kusion build",description:"Build Kusion modules in a Stack to the Intent",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-build.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-build",permalink:"/docs/kusion/reference/commands/kusion-build",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-build.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion apply",permalink:"/docs/kusion/reference/commands/kusion-apply"},next:{title:"kusion compile",permalink:"/docs/kusion/reference/commands/kusion-compile"}},u={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-build"},"kusion build"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("p",null," The command must be executed in a Stack or by specifying a Stack directory with the -w flag. You can provide a list of arguments to replace the placeholders defined in KCL, and use the --output flag to output the built results to a file"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion build [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Build main.k with arguments\n kusion build -D name=test -D age=18\n \n # Build main.k with work directory\n kusion build -w appops/demo/dev\n \n # Build configurations and write result into an output.yaml\n kusion build -o output.yaml\n \n # Build configurations with arguments from settings.yaml\n kusion build -Y settings.yaml\n \n # Build without output style and color\n kusion build --no-style=true\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -h, --help help for build\n --no-style Disable the output style and color\n -o, --output string Specify the output file\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/72ae1949.3f745ef1.js b/assets/js/72ae1949.3f745ef1.js deleted file mode 100644 index 201c124a5b3..00000000000 --- a/assets/js/72ae1949.3f745ef1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4215],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=o.createContext({}),l=function(e){var t=o.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(u.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(u,".").concat(m)]||d[m]||c[m]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={},a="kusion build",s={unversionedId:"kusion/reference/commands/kusion-build",id:"version-v0.10/kusion/reference/commands/kusion-build",title:"kusion build",description:"Build Kusion modules in a Stack to the Intent",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-build.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-build",permalink:"/docs/kusion/reference/commands/kusion-build",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-build.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion apply",permalink:"/docs/kusion/reference/commands/kusion-apply"},next:{title:"kusion compile",permalink:"/docs/kusion/reference/commands/kusion-compile"}},u={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-build"},"kusion build"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("p",null," The command must be executed in a Stack or by specifying a Stack directory with the -w flag. You can provide a list of arguments to replace the placeholders defined in KCL, and use the --output flag to output the built results to a file"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion build [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Build main.k with arguments\n kusion build -D name=test -D age=18\n \n # Build main.k with work directory\n kusion build -w appops/demo/dev\n \n # Build configurations and write result into an output.yaml\n kusion build -o output.yaml\n \n # Build configurations with arguments from settings.yaml\n kusion build -Y settings.yaml\n \n # Build without output style and color\n kusion build --no-style=true\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -h, --help help for build\n --no-style Disable the output style and color\n -o, --output string Specify the output file\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/72c158da.6b232634.js b/assets/js/72c158da.6b232634.js new file mode 100644 index 00000000000..d3d2bc8e1dd --- /dev/null +++ b/assets/js/72c158da.6b232634.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1824],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,g=d["".concat(l,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},u),{},{components:n})):r.createElement(g,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const i={},a="What is KusionStack Operating?",s={unversionedId:"operating/introduction/introduction",id:"operating/introduction/introduction",title:"What is KusionStack Operating?",description:"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,",source:"@site/docs/operating/introduction/introduction.md",sourceDirName:"operating/introduction",slug:"/operating/introduction/",permalink:"/docs/next/operating/introduction/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/introduction/introduction.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",next:{title:"Installation",permalink:"/docs/next/operating/started/install"}},l={},c=[{value:"Key features",id:"key-features",level:2},{value:"Fine-grained operation",id:"fine-grained-operation",level:3},{value:"Advanced workloads",id:"advanced-workloads",level:3},{value:"Streamlined Pod Operation",id:"streamlined-pod-operation",level:3},{value:"Risk management",id:"risk-management",level:3},{value:"Future works",id:"future-works",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"what-is-kusionstack-operating"},"What is KusionStack Operating?"),(0,o.kt)("p",null,"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,\nwith a primary aim of bridging the gap between platform development and Kubernetes."),(0,o.kt)("p",null,"By keeping more operation works finished in Kubernetes layer,\nKusionStack Operating reduces complexity when interacting with Kubernetes\nand enhances convenience for platform developers."),(0,o.kt)("h2",{id:"key-features"},"Key features"),(0,o.kt)("p",null,"KusionStack Operating currently provides the following features,\nstreamlining application operations when developing platforms based on Kubernetes:"),(0,o.kt)("h3",{id:"fine-grained-operation"},"Fine-grained operation"),(0,o.kt)("p",null,"KusionStack Operating introduces PodOpsLifecycle to extend native Pod lifecycle with additional phases such as PreCheck, Preparing, etc.\nAll operators within KusionStack Operating will respect PodOpsLifecycle,\nso that PodOpsLifecycle is able to orchestrate all of these operators to operate each Pod coordinately. "),(0,o.kt)("h3",{id:"advanced-workloads"},"Advanced workloads"),(0,o.kt)("p",null,"KusionStack Operating offers several workloads to ensure it is convenient and effective to delivery and operate application resources."),(0,o.kt)("p",null,"Recently, Operating provides the workload CollaSet.\nBesides the basic ability of scaling and updating Pods like Deployment and StatefulSet of Kubernetes,\nCollaSet also provides a range of scale and update strategies,\nlike in-place update with container image and pod revision consistency."),(0,o.kt)("h3",{id:"streamlined-pod-operation"},"Streamlined Pod Operation"),(0,o.kt)("p",null,"KusionStack Operating introduces resource consist framework that offers a graceful way\nto integrate resource management around Pods, including traffic control, into the PodOpsLifecycle.\nThis simplifies the works for platform developers dealing with Pod operation details.\nKusionStack also integrates some resources by default, such as Aliyun SLB."),(0,o.kt)("h3",{id:"risk-management"},"Risk management"),(0,o.kt)("p",null,"Building upon the PodOpsLifecycle, KusionStack Operating introduces the workload named PodTransitionRule\nwhich will keep risks of pod operation under control.\nBy providing a MaxUnavailable rule similar to Kubernetes' PodDisruptionBudget (PDB),\nit ensures there are always enough Pods available for service.\nFurthermore, it allows for custom rules through extension via webhooks and label hooks."),(0,o.kt)("h2",{id:"future-works"},"Future works"),(0,o.kt)("p",null,"KusionStack Operating project is currently in its early stages.\nOur goal is to simplify platform development. We will continue building in areas such as application operations,\nobservability, and insight. We hope the Operating will make it easier for you to build platforms."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/72c158da.eccd5906.js b/assets/js/72c158da.eccd5906.js deleted file mode 100644 index 8d2bf476633..00000000000 --- a/assets/js/72c158da.eccd5906.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1824],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,g=d["".concat(l,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},u),{},{components:n})):r.createElement(g,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const i={},a="What is KusionStack Operating?",s={unversionedId:"operating/introduction/introduction",id:"operating/introduction/introduction",title:"What is KusionStack Operating?",description:"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,",source:"@site/docs/operating/introduction/introduction.md",sourceDirName:"operating/introduction",slug:"/operating/introduction/",permalink:"/docs/next/operating/introduction/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/introduction/introduction.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",next:{title:"Installation",permalink:"/docs/next/operating/started/install"}},l={},c=[{value:"Key features",id:"key-features",level:2},{value:"Fine-grained operation",id:"fine-grained-operation",level:3},{value:"Advanced workloads",id:"advanced-workloads",level:3},{value:"Streamlined Pod Operation",id:"streamlined-pod-operation",level:3},{value:"Risk management",id:"risk-management",level:3},{value:"Future works",id:"future-works",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"what-is-kusionstack-operating"},"What is KusionStack Operating?"),(0,o.kt)("p",null,"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,\nwith a primary aim of bridging the gap between platform development and Kubernetes."),(0,o.kt)("p",null,"By keeping more operation works finished in Kubernetes layer,\nKusionStack Operating reduces complexity when interacting with Kubernetes\nand enhances convenience for platform developers."),(0,o.kt)("h2",{id:"key-features"},"Key features"),(0,o.kt)("p",null,"KusionStack Operating currently provides the following features,\nstreamlining application operations when developing platforms based on Kubernetes:"),(0,o.kt)("h3",{id:"fine-grained-operation"},"Fine-grained operation"),(0,o.kt)("p",null,"KusionStack Operating introduces PodOpsLifecycle to extend native Pod lifecycle with additional phases such as PreCheck, Preparing, etc.\nAll operators within KusionStack Operating will respect PodOpsLifecycle,\nso that PodOpsLifecycle is able to orchestrate all of these operators to operate each Pod coordinately. "),(0,o.kt)("h3",{id:"advanced-workloads"},"Advanced workloads"),(0,o.kt)("p",null,"KusionStack Operating offers several workloads to ensure it is convenient and effective to delivery and operate application resources."),(0,o.kt)("p",null,"Recently, Operating provides the workload CollaSet.\nBesides the basic ability of scaling and updating Pods like Deployment and StatefulSet of Kubernetes,\nCollaSet also provides a range of scale and update strategies,\nlike in-place update with container image and pod revision consistency."),(0,o.kt)("h3",{id:"streamlined-pod-operation"},"Streamlined Pod Operation"),(0,o.kt)("p",null,"KusionStack Operating introduces resource consist framework that offers a graceful way\nto integrate resource management around Pods, including traffic control, into the PodOpsLifecycle.\nThis simplifies the works for platform developers dealing with Pod operation details.\nKusionStack also integrates some resources by default, such as Aliyun SLB."),(0,o.kt)("h3",{id:"risk-management"},"Risk management"),(0,o.kt)("p",null,"Building upon the PodOpsLifecycle, KusionStack Operating introduces the workload named PodTransitionRule\nwhich will keep risks of pod operation under control.\nBy providing a MaxUnavailable rule similar to Kubernetes' PodDisruptionBudget (PDB),\nit ensures there are always enough Pods available for service.\nFurthermore, it allows for custom rules through extension via webhooks and label hooks."),(0,o.kt)("h2",{id:"future-works"},"Future works"),(0,o.kt)("p",null,"KusionStack Operating project is currently in its early stages.\nOur goal is to simplify platform development. We will continue building in areas such as application operations,\nobservability, and insight. We hope the Operating will make it easier for you to build platforms."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/735b5664.b44170e2.js b/assets/js/735b5664.3f93833d.js similarity index 57% rename from assets/js/735b5664.b44170e2.js rename to assets/js/735b5664.3f93833d.js index f0540145c42..c05cbaca71f 100644 --- a/assets/js/735b5664.b44170e2.js +++ b/assets/js/735b5664.3f93833d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2789],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},l={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=u(t),m=o,d=f["".concat(c,".").concat(m)]||f[m]||l[m]||i;return t?r.createElement(d,s(s({ref:n},p),{},{components:t})):r.createElement(d,s({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=f;var a={};for(var c in n)hasOwnProperty.call(n,c)&&(a[c]=n[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var r=t(87462),o=(t(67294),t(3905));const i={},s="kusion version",a={unversionedId:"kusion/reference/commands/kusion-version",id:"version-v0.10/kusion/reference/commands/kusion-version",title:"kusion version",description:"Print the Kusion version information for the current context",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-version.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-version",permalink:"/docs/kusion/reference/commands/kusion-version",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-version.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion preview",permalink:"/docs/kusion/reference/commands/kusion-preview"},next:{title:"kusion workspace create",permalink:"/docs/kusion/reference/commands/kusion-workspace-create"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:u};function l(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-version"},"kusion version"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion version [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Print the Kusion version\n kusion version\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for version\n -o, --output string Output format. Only json format is supported for now\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2789],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},l={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=u(t),m=o,d=f["".concat(c,".").concat(m)]||f[m]||l[m]||i;return t?r.createElement(d,s(s({ref:n},p),{},{components:t})):r.createElement(d,s({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=f;var a={};for(var c in n)hasOwnProperty.call(n,c)&&(a[c]=n[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var r=t(87462),o=(t(67294),t(3905));const i={},s="kusion version",a={unversionedId:"kusion/reference/commands/kusion-version",id:"version-v0.10/kusion/reference/commands/kusion-version",title:"kusion version",description:"Print the Kusion version information for the current context",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-version.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-version",permalink:"/docs/kusion/reference/commands/kusion-version",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-version.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion preview",permalink:"/docs/kusion/reference/commands/kusion-preview"},next:{title:"kusion workspace create",permalink:"/docs/kusion/reference/commands/kusion-workspace-create"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:u};function l(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-version"},"kusion version"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion version [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Print the Kusion version\n kusion version\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for version\n -o, --output string Output format. Only json format is supported for now\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/75071e09.91cf8ea0.js b/assets/js/75071e09.91cf8ea0.js deleted file mode 100644 index 952a35eebed..00000000000 --- a/assets/js/75071e09.91cf8ea0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3485],{3905:(e,n,t)=>{t.d(n,{Zo:()=>s,kt:()=>k});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),c=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},s=function(e){var n=c(e.components);return o.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),d=c(t),k=r,g=d["".concat(l,".").concat(k)]||d[k]||u[k]||i;return t?o.createElement(g,a(a({ref:n},s),{},{components:t})):o.createElement(g,a({ref:n},s))}));function k(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=d;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,a[1]=p;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var o=t(87462),r=(t(67294),t(3905));const i={id:"networking"},a="Application Networking",p={unversionedId:"kusion/configuration-walkthrough/networking",id:"kusion/configuration-walkthrough/networking",title:"Application Networking",description:"In addition to configuring application's container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed. You can specify a network module in the accessories field in AppConfiguration to achieve that.",source:"@site/docs/kusion/4-configuration-walkthrough/5-networking.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/networking",permalink:"/docs/next/kusion/configuration-walkthrough/networking",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/5-networking.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"networking"},sidebar:"kusion",previous:{title:"Workload",permalink:"/docs/next/kusion/configuration-walkthrough/workload"},next:{title:"Managed Databases",permalink:"/docs/next/kusion/configuration-walkthrough/databse"}},l={},c=[{value:"Import",id:"import",level:2},{value:"Private vs Public Access",id:"private-vs-public-access",level:2},{value:"Mapping ports",id:"mapping-ports",level:2},{value:"Exposing multiple ports",id:"exposing-multiple-ports",level:2},{value:"Choosing protocol",id:"choosing-protocol",level:2}],s={toc:c};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},s,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-networking"},"Application Networking"),(0,r.kt)("p",null,"In addition to configuring application's ",(0,r.kt)("a",{parentName:"p",href:"workload#configure-containers"},"container specifications"),", you can also configure its networking behaviors, including how to expose the application and how it can be accessed. You can specify a ",(0,r.kt)("inlineCode",{parentName:"p"},"network")," module in the ",(0,r.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that."),(0,r.kt)("p",null,"In future versions, this will also include ingress-based routing strategy and DNS configurations."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,r.kt)("inlineCode",{parentName:"p"},"network")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport network.network as n\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"kcl.mod")," must contain reference to the network module:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'#...\n\n[dependencies]\nnetwork = { oci = "oci://ghcr.io/kusionstack/network", tag = "0.1.0" }\n\n#...\n')),(0,r.kt)("h2",{id:"private-vs-public-access"},"Private vs Public Access"),(0,r.kt)("p",null,"Private network access means the service can only be access from within the target cluster."),(0,r.kt)("p",null,"Public access is implemented using public load balancers on the cloud. This generally requires a Kubernetes cluster that is running on the cloud with a vendor-specific service controller."),(0,r.kt)("p",null,"Any ports defined default to private access unless explicitly specified."),(0,r.kt)("p",null,"To expose port 80 to be accessed privately:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n }\n}\n')),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n }\n}\n')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The CSP (Cloud Service Provider) used to provide load balancers is defined by platform engineers in workspace.")),(0,r.kt)("h2",{id:"mapping-ports"},"Mapping ports"),(0,r.kt)("p",null,"To expose a port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," that maps to a different port ",(0,r.kt)("inlineCode",{parentName:"p"},"8088")," on the container:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n }\n ]\n }\n }\n}\n')),(0,r.kt)("h2",{id:"exposing-multiple-ports"},"Exposing multiple ports"),(0,r.kt)("p",null,"You can also expose multiple ports and configure them separately. "),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly, and port 9099 for private access (to be scraped by Prometheus, for example):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9099\n }\n ]\n }\n }\n}\n')),(0,r.kt)("h2",{id:"choosing-protocol"},"Choosing protocol"),(0,r.kt)("p",null,"To expose a port using the ",(0,r.kt)("inlineCode",{parentName:"p"},"UDP")," protocol:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n protocol: "UDP"\n }\n ]\n }\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/75071e09.bf149714.js b/assets/js/75071e09.bf149714.js new file mode 100644 index 00000000000..b013dfe66fe --- /dev/null +++ b/assets/js/75071e09.bf149714.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3485],{3905:(e,n,t)=>{t.d(n,{Zo:()=>s,kt:()=>k});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),c=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},s=function(e){var n=c(e.components);return o.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),d=c(t),k=r,g=d["".concat(l,".").concat(k)]||d[k]||u[k]||i;return t?o.createElement(g,a(a({ref:n},s),{},{components:t})):o.createElement(g,a({ref:n},s))}));function k(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=d;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,a[1]=p;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var o=t(87462),r=(t(67294),t(3905));const i={id:"networking"},a="Application Networking",p={unversionedId:"kusion/configuration-walkthrough/networking",id:"kusion/configuration-walkthrough/networking",title:"Application Networking",description:"In addition to configuring application's container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed. You can specify a network module in the accessories field in AppConfiguration to achieve that.",source:"@site/docs/kusion/4-configuration-walkthrough/5-networking.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/networking",permalink:"/docs/next/kusion/configuration-walkthrough/networking",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/5-networking.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"networking"},sidebar:"kusion",previous:{title:"Workload",permalink:"/docs/next/kusion/configuration-walkthrough/workload"},next:{title:"Managed Databases",permalink:"/docs/next/kusion/configuration-walkthrough/databse"}},l={},c=[{value:"Import",id:"import",level:2},{value:"Private vs Public Access",id:"private-vs-public-access",level:2},{value:"Mapping ports",id:"mapping-ports",level:2},{value:"Exposing multiple ports",id:"exposing-multiple-ports",level:2},{value:"Choosing protocol",id:"choosing-protocol",level:2}],s={toc:c};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},s,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-networking"},"Application Networking"),(0,r.kt)("p",null,"In addition to configuring application's ",(0,r.kt)("a",{parentName:"p",href:"workload#configure-containers"},"container specifications"),", you can also configure its networking behaviors, including how to expose the application and how it can be accessed. You can specify a ",(0,r.kt)("inlineCode",{parentName:"p"},"network")," module in the ",(0,r.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that."),(0,r.kt)("p",null,"In future versions, this will also include ingress-based routing strategy and DNS configurations."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,r.kt)("inlineCode",{parentName:"p"},"network")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport network.network as n\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"kcl.mod")," must contain reference to the network module:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'#...\n\n[dependencies]\nnetwork = { oci = "oci://ghcr.io/kusionstack/network", tag = "0.1.0" }\n\n#...\n')),(0,r.kt)("h2",{id:"private-vs-public-access"},"Private vs Public Access"),(0,r.kt)("p",null,"Private network access means the service can only be access from within the target cluster."),(0,r.kt)("p",null,"Public access is implemented using public load balancers on the cloud. This generally requires a Kubernetes cluster that is running on the cloud with a vendor-specific service controller."),(0,r.kt)("p",null,"Any ports defined default to private access unless explicitly specified."),(0,r.kt)("p",null,"To expose port 80 to be accessed privately:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n }\n}\n')),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n }\n}\n')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The CSP (Cloud Service Provider) used to provide load balancers is defined by platform engineers in workspace.")),(0,r.kt)("h2",{id:"mapping-ports"},"Mapping ports"),(0,r.kt)("p",null,"To expose a port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," that maps to a different port ",(0,r.kt)("inlineCode",{parentName:"p"},"8088")," on the container:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n }\n ]\n }\n }\n}\n')),(0,r.kt)("h2",{id:"exposing-multiple-ports"},"Exposing multiple ports"),(0,r.kt)("p",null,"You can also expose multiple ports and configure them separately. "),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly, and port 9099 for private access (to be scraped by Prometheus, for example):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9099\n }\n ]\n }\n }\n}\n')),(0,r.kt)("h2",{id:"choosing-protocol"},"Choosing protocol"),(0,r.kt)("p",null,"To expose a port using the ",(0,r.kt)("inlineCode",{parentName:"p"},"UDP")," protocol:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n protocol: "UDP"\n }\n ]\n }\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7590d161.45961935.js b/assets/js/7590d161.67c28f14.js similarity index 54% rename from assets/js/7590d161.45961935.js rename to assets/js/7590d161.67c28f14.js index 270d12f1cfd..81411ca7c80 100644 --- a/assets/js/7590d161.45961935.js +++ b/assets/js/7590d161.67c28f14.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7550],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>k});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function u(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),a=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):u(u({},t),e)),n},c=function(e){var t=a(e.components);return o.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=a(n),k=r,f=d["".concat(s,".").concat(k)]||d[k]||p[k]||i;return n?o.createElement(f,u(u({ref:t},c),{},{components:n})):o.createElement(f,u({ref:t},c))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,u=new Array(i);u[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,u[1]=l;for(var a=2;a{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>a});var o=n(87462),r=(n(67294),n(3905));const i={},u="kusion build",l={unversionedId:"kusion/reference/cli/kusion/kusion_build",id:"version-v0.9/kusion/reference/cli/kusion/kusion_build",title:"kusion build",description:"Build Kusion modules in a Stack to the Intent.",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_build.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_build",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_build",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_build.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion apply",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply"},next:{title:"kusion compile",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile"}},s={},a=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 30-Nov-2023",id:"auto-generated-by-spf13cobra-on-30-nov-2023",level:6}],c={toc:a};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-build"},"kusion build"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent."),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent."),(0,r.kt)("p",null," The command must be executed in a Stack or by specifying a Stack directory with the -w flag. You can provide a list of arguments to replace the placeholders defined in KCL, and use the --output flag to output the built results to a file."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion build [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Build main.k with arguments\n kusion build -D name=test -D age=18\n \n # Build main.k with work directory\n kusion build -w appops/demo/dev\n \n # Build main.k and write result into output.yaml\n kusion build -o output.yaml\n \n # Build without output style and color\n kusion build --no-style=true\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -h, --help help for build\n --no-style Disable the output style and color\n -o, --output string Specify the output file\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-30-nov-2023"},"Auto generated by spf13/cobra on 30-Nov-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7550],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>k});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function u(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),a=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):u(u({},t),e)),n},c=function(e){var t=a(e.components);return o.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=a(n),k=r,f=d["".concat(s,".").concat(k)]||d[k]||p[k]||i;return n?o.createElement(f,u(u({ref:t},c),{},{components:n})):o.createElement(f,u({ref:t},c))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,u=new Array(i);u[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,u[1]=l;for(var a=2;a{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>a});var o=n(87462),r=(n(67294),n(3905));const i={},u="kusion build",l={unversionedId:"kusion/reference/cli/kusion/kusion_build",id:"version-v0.9/kusion/reference/cli/kusion/kusion_build",title:"kusion build",description:"Build Kusion modules in a Stack to the Intent.",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_build.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_build",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_build",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_build.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion apply",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply"},next:{title:"kusion compile",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile"}},s={},a=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 30-Nov-2023",id:"auto-generated-by-spf13cobra-on-30-nov-2023",level:6}],c={toc:a};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-build"},"kusion build"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent."),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent."),(0,r.kt)("p",null," The command must be executed in a Stack or by specifying a Stack directory with the -w flag. You can provide a list of arguments to replace the placeholders defined in KCL, and use the --output flag to output the built results to a file."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion build [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Build main.k with arguments\n kusion build -D name=test -D age=18\n \n # Build main.k with work directory\n kusion build -w appops/demo/dev\n \n # Build main.k and write result into output.yaml\n kusion build -o output.yaml\n \n # Build without output style and color\n kusion build --no-style=true\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -h, --help help for build\n --no-style Disable the output style and color\n -o, --output string Specify the output file\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-30-nov-2023"},"Auto generated by spf13/cobra on 30-Nov-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/76b33887.1ab6b263.js b/assets/js/76b33887.1ab6b263.js deleted file mode 100644 index 0bf83badfd5..00000000000 --- a/assets/js/76b33887.1ab6b263.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[883],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,f=m["".concat(i,".").concat(u)]||m[u]||c[u]||a;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},l="ResourceConsist",s={unversionedId:"operating/manuals/resourceconsist",id:"version-v0.10/operating/manuals/resourceconsist",title:"ResourceConsist",description:"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following",source:"@site/versioned_docs/version-v0.10/operating/manuals/resourceconsist.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/resourceconsist",permalink:"/docs/operating/manuals/resourceconsist",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/resourceconsist.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"CollaSet",permalink:"/docs/operating/manuals/collaset"},next:{title:"PodTransitionRule",permalink:"/docs/operating/manuals/podtransitionrule"}},i={},p=[{value:"Tutorials",id:"tutorials",level:2},{value:"adapters",id:"adapters",level:3},{value:"alibabacloudslb adapter",id:"alibabacloudslb-adapter",level:4},{value:"experimental/adapters",id:"experimentaladapters",level:3},{value:"demo adapter",id:"demo-adapter",level:3}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resourceconsist"},"ResourceConsist"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist/blob/main/README.md"},(0,o.kt)("strong",{parentName:"a"},"ResourceConsist"))," aims to make a customized controller can be realized easily, and offering the ability of following\n",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," for controllers."),(0,o.kt)("h2",{id:"tutorials"},"Tutorials"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"kusionstack.io/resourceconsit")," mainly consists of frame, experimental/adapters and adapters."),(0,o.kt)("p",null,"The frame, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame"),", is used for adapters starting a controller, which handles\nReconcile and Employer/Employees' spec&status. If you wrote an adapter in your own repo, you can import\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/webhook"),",\n]and call AddToMgr to start a controller."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"webhookAdapter is only necessary to be implemented for controllers following PodOpsLifecycle.")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n controllerframe "kusionstack.io/resourceconsist/pkg/frame/controller"\n webhookframe "kusionstack.io/resourceconsist/pkg/frame/webhook"\n)\n\nfunc main() {\n controllerframe.AddToMgr(manager, yourOwnControllerAdapter)\n webhookframe.AddToMgr(manager, yourOwnWebhookAdapter)\n}\n')),(0,o.kt)("h3",{id:"adapters"},"adapters"),(0,o.kt)("p",null,"The adapters, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters"),", consists of built-in adapters. You can start a\ncontroller with built-in adapters just calling AddBuiltinControllerAdaptersToMgr and AddBuiltinWebhookAdaptersToMgr,\npassing built-in adapters' names. Currently, an aliababacloudslb adapter has released. You can use it as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "kusionstack.io/resourceconsist/pkg/adapters"\n)\n\nfunc main() {\n adapters.AddBuiltinControllerAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n adapters.AddBuiltinWebhookAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n}\n')),(0,o.kt)("p",null,"Built-in adapters can also be used like how frame used. You can call NewAdapter from a certain built-in adapter pkg\nand the call frame.AddToMgr to start a controller/webhook"),(0,o.kt)("p",null,"More built-in adapters will be implemented in the future. To make this repo stable, all new built-in adapters will\nbe added to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/experimental/adapters")," first, and then moved to\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters")," until ready to be released."),(0,o.kt)("h4",{id:"alibabacloudslb-adapter"},"alibabacloudslb adapter"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb")," is an adapter that implements ReconcileAdapter. It follows ",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," to\nhandle various scenarios during pod operations, such as creating a new pod, deleting an existing pod, or handling\nchanges to pod configurations. This adapter ensures minimal traffic loss and provides a seamless experience for users\naccessing services load balanced by Alibaba Cloud SLB."),(0,o.kt)("p",null,"In ",(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb"),", the real server is removed from SLB before pod operation in ACK. The LB\nmanagement and real server management are handled by CCM in ACK. Since alibabacloudslb adapter follows PodOpsLifecycle\nand real servers are managed by CCM, ReconcileLifecycleOptions should be implemented. If the cluster is not in ACK or\nCCM is not working in the cluster, the alibabacloudslb controller should implement additional methods of ReconcileAdapter."),(0,o.kt)("h3",{id:"experimentaladapters"},"experimental/adapters"),(0,o.kt)("p",null,"The experimental/adapters is more like a pre-release pkg for built-in adapters. Usage of experimental/adapters is same\nwith built-in adapters, and be aware that ",(0,o.kt)("strong",{parentName:"p"},"DO NOT USE EXPERIMENTAL/ADAPTERS IN PRODUCTION")),(0,o.kt)("h3",{id:"demo-adapter"},"demo adapter"),(0,o.kt)("p",null,"A demo is implemented in ",(0,o.kt)("inlineCode",{parentName:"p"},"resource_controller_suite_test.go"),". In the demo controller, the employer is represented\nas a service and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoServiceStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n }\n}\n')),(0,o.kt)("p",null,"The employee is represented as a pod and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoPodStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n EmployeeStatuses: PodEmployeeStatuses{\n Ip: string,\n Ipv6: string,\n LifecycleReady: bool,\n ExtraStatus: PodExtraStatus{\n TrafficOn: bool,\n TrafficWeight: int,\n },\n }\n}\n")),(0,o.kt)("p",null,"The DemoResourceProviderClient is a fake client that handles backend provider resources related to the employer/employee\n(service/pods). In the Demo Controller, ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"\nare mocked as resources in the backend provider."),(0,o.kt)("p",null,"How the demo controller adapter realized will be introduced in detail as follows,\n",(0,o.kt)("inlineCode",{parentName:"p"},"DemoControllerAdapter")," was defined, including a kubernetes client and a resourceProviderClient. What included in\nthe Adapter struct can be defined as needed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type DemoControllerAdapter struct {\n client.Client\n resourceProviderClient *DemoResourceProviderClient\n}\n")),(0,o.kt)("p",null,"Declaring that the DemoControllerAdapter implemented ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileAdapter")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),".\nImplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"RconcileAdapter")," is a must action, while ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," isn't, check the remarks\nfor ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller/types.go")," to find why."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"var _ ReconcileAdapter = &DemoControllerAdapter{}\nvar _ ReconcileLifecycleOptions = &DemoControllerAdapter{}\n")),(0,o.kt)("p",null,"Following two methods for DemoControllerAdapter inplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),", defines whether\nDemoControllerAdapter following PodOpsLifecycle and need record employees."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"func (r *DemoControllerAdapter) FollowPodOpsLifeCycle() bool {\n return true\n}\n\nfunc (r *DemoControllerAdapter) NeedRecordEmployees() bool {\n return needRecordEmployees\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"IEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"IEmployee")," are interfaces that includes several methods indicating the status employer and\nemployee."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type IEmployer interface {\n GetEmployerId() string\n GetEmployerStatuses() interface{}\n EmployerEqual(employer IEmployer) (bool, error)\n}\n\ntype IEmployee interface {\n GetEmployeeId() string\n GetEmployeeName() string\n GetEmployeeStatuses() interface{}\n EmployeeEqual(employee IEmployee) (bool, error)\n}\n\ntype DemoServiceStatus struct {\n EmployerId string\n EmployerStatuses DemoServiceDetails\n}\n\ntype DemoServiceDetails struct {\n RemoteVIP string\n RemoteVIPQPS int\n}\n\ntype DemoPodStatus struct {\n EmployeeId string\n EmployeeName string\n EmployeeStatuses PodEmployeeStatuses\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," returns all employees' names selected by employer, here is pods' names selected by\nservice. ",(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," is used for ensuring LifecycleFinalizer and ExpectedFinalizer, so you can give\nit an empty return if your adapter doesn't follow PodOpsLifecycle."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) {\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n selected := make([]string, len(podList.Items))\n for idx, pod := range podList.Items {\n selected[idx] = pod.Name\n }\n\n return selected, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployer")," defines what is expected under the spec of employer and what is\ncurrent status, like the load balancer from a cloud provider. Here in the demo adapter, expected is defined by hardcode\nand current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return nil, nil\n }\n var expect []IEmployer\n expect = append(expect, DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n },\n })\n return expect, nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n var current []IEmployer\n\n req := &DemoResourceVipOps{}\n resp, err := r.resourceProviderClient.QueryVip(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource vip query resp is nil")\n }\n\n for _, employerStatus := range resp.VipStatuses {\n current = append(current, employerStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles creation/update/deletion of resources related to employer on\nrelated backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles\n",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n\n toCreateDemoServiceStatus := make([]DemoServiceStatus, len(toCreates))\n for idx, create := range toCreates {\n createDemoServiceStatus, ok := create.(DemoServiceStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreates employer is not DemoServiceStatus")\n }\n toCreateDemoServiceStatus[idx] = createDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.CreateVip(&DemoResourceVipOps{\n VipStatuses: toCreateDemoServiceStatus,\n })\n if err != nil {\n return nil, toCreates, err\n }\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoServiceStatus := make([]DemoServiceStatus, len(toUpdates))\n for idx, update := range toUpdates {\n updateDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdates employer is not DemoServiceStatus")\n }\n toUpdateDemoServiceStatus[idx] = updateDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.UpdateVip(&DemoResourceVipOps{\n VipStatuses: toUpdateDemoServiceStatus,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoServiceStatus := make([]DemoServiceStatus, len(toDeletes))\n for idx, update := range toDeletes {\n deleteDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDeletes employer is not DemoServiceStatus")\n }\n toDeleteDemoServiceStatus[idx] = deleteDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.DeleteVip(&DemoResourceVipOps{\n VipStatuses: toDeleteDemoServiceStatus,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n return toDeletes, nil, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployee"),"and",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployee")," defines what is expected under the spec of employer and employees\nand what is current status, like real servers under the load balancer from a cloud provider. Here in the demo adapter,\nexpected is calculated from pods and current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'// GetExpectEmployeeStatus return expect employee status\nfunc (r *DemoControllerAdapter) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return []IEmployee{}, nil\n }\n\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n expected := make([]IEmployee, len(podList.Items))\n expectIdx := 0\n for _, pod := range podList.Items {\n if !pod.DeletionTimestamp.IsZero() {\n continue\n }\n status := DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n }\n employeeStatuses, err := GetCommonPodEmployeeStatus(&pod)\n if err != nil {\n return nil, err\n }\n extraStatus := PodExtraStatus{}\n if employeeStatuses.LifecycleReady {\n extraStatus.TrafficOn = true\n extraStatus.TrafficWeight = 100\n } else {\n extraStatus.TrafficOn = false\n extraStatus.TrafficWeight = 0\n }\n employeeStatuses.ExtraStatus = extraStatus\n status.EmployeeStatuses = employeeStatuses\n expected[expectIdx] = status\n expectIdx++\n }\n\n return expected[:expectIdx], nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n var current []IEmployee\n req := &DemoResourceRsOps{}\n resp, err := r.resourceProviderClient.QueryRealServer(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource rs query resp is nil")\n }\n\n for _, rsStatus := range resp.RsStatuses {\n current = append(current, rsStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees")," handles creation/update/deletion of resources related to employee\non related backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees"),"\nhandles ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n toCreateDemoPodStatuses := make([]DemoPodStatus, len(toCreates))\n\n for idx, toCreate := range toCreates {\n podStatus, ok := toCreate.(DemoPodStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreate is not DemoPodStatus")\n }\n toCreateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.CreateRealServer(&DemoResourceRsOps{\n RsStatuses: toCreateDemoPodStatuses,\n })\n if err != nil {\n return nil, toCreates, err\n }\n\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoPodStatuses := make([]DemoPodStatus, len(toUpdates))\n\n for idx, toUpdate := range toUpdates {\n podStatus, ok := toUpdate.(DemoPodStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdate is not DemoPodStatus")\n }\n toUpdateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.UpdateRealServer(&DemoResourceRsOps{\n RsStatuses: toUpdateDemoPodStatuses,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoPodStatuses := make([]DemoPodStatus, len(toDeletes))\n\n for idx, toDelete := range toDeletes {\n podStatus, ok := toDelete.(DemoPodStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDelete is not DemoPodStatus")\n }\n toDeleteDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.DeleteRealServer(&DemoResourceRsOps{\n RsStatuses: toDeleteDemoPodStatuses,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n\n return toDeletes, nil, nil\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/76b33887.749220b6.js b/assets/js/76b33887.749220b6.js new file mode 100644 index 00000000000..54d69f2a3e2 --- /dev/null +++ b/assets/js/76b33887.749220b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[883],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,f=m["".concat(i,".").concat(u)]||m[u]||c[u]||a;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},l="ResourceConsist",s={unversionedId:"operating/manuals/resourceconsist",id:"version-v0.10/operating/manuals/resourceconsist",title:"ResourceConsist",description:"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following",source:"@site/versioned_docs/version-v0.10/operating/manuals/resourceconsist.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/resourceconsist",permalink:"/docs/operating/manuals/resourceconsist",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/resourceconsist.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"CollaSet",permalink:"/docs/operating/manuals/collaset"},next:{title:"PodTransitionRule",permalink:"/docs/operating/manuals/podtransitionrule"}},i={},p=[{value:"Tutorials",id:"tutorials",level:2},{value:"adapters",id:"adapters",level:3},{value:"alibabacloudslb adapter",id:"alibabacloudslb-adapter",level:4},{value:"experimental/adapters",id:"experimentaladapters",level:3},{value:"demo adapter",id:"demo-adapter",level:3}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resourceconsist"},"ResourceConsist"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist/blob/main/README.md"},(0,o.kt)("strong",{parentName:"a"},"ResourceConsist"))," aims to make a customized controller can be realized easily, and offering the ability of following\n",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," for controllers."),(0,o.kt)("h2",{id:"tutorials"},"Tutorials"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"kusionstack.io/resourceconsit")," mainly consists of frame, experimental/adapters and adapters."),(0,o.kt)("p",null,"The frame, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame"),", is used for adapters starting a controller, which handles\nReconcile and Employer/Employees' spec&status. If you wrote an adapter in your own repo, you can import\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/webhook"),",\n]and call AddToMgr to start a controller."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"webhookAdapter is only necessary to be implemented for controllers following PodOpsLifecycle.")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n controllerframe "kusionstack.io/resourceconsist/pkg/frame/controller"\n webhookframe "kusionstack.io/resourceconsist/pkg/frame/webhook"\n)\n\nfunc main() {\n controllerframe.AddToMgr(manager, yourOwnControllerAdapter)\n webhookframe.AddToMgr(manager, yourOwnWebhookAdapter)\n}\n')),(0,o.kt)("h3",{id:"adapters"},"adapters"),(0,o.kt)("p",null,"The adapters, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters"),", consists of built-in adapters. You can start a\ncontroller with built-in adapters just calling AddBuiltinControllerAdaptersToMgr and AddBuiltinWebhookAdaptersToMgr,\npassing built-in adapters' names. Currently, an aliababacloudslb adapter has released. You can use it as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "kusionstack.io/resourceconsist/pkg/adapters"\n)\n\nfunc main() {\n adapters.AddBuiltinControllerAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n adapters.AddBuiltinWebhookAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n}\n')),(0,o.kt)("p",null,"Built-in adapters can also be used like how frame used. You can call NewAdapter from a certain built-in adapter pkg\nand the call frame.AddToMgr to start a controller/webhook"),(0,o.kt)("p",null,"More built-in adapters will be implemented in the future. To make this repo stable, all new built-in adapters will\nbe added to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/experimental/adapters")," first, and then moved to\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters")," until ready to be released."),(0,o.kt)("h4",{id:"alibabacloudslb-adapter"},"alibabacloudslb adapter"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb")," is an adapter that implements ReconcileAdapter. It follows ",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," to\nhandle various scenarios during pod operations, such as creating a new pod, deleting an existing pod, or handling\nchanges to pod configurations. This adapter ensures minimal traffic loss and provides a seamless experience for users\naccessing services load balanced by Alibaba Cloud SLB."),(0,o.kt)("p",null,"In ",(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb"),", the real server is removed from SLB before pod operation in ACK. The LB\nmanagement and real server management are handled by CCM in ACK. Since alibabacloudslb adapter follows PodOpsLifecycle\nand real servers are managed by CCM, ReconcileLifecycleOptions should be implemented. If the cluster is not in ACK or\nCCM is not working in the cluster, the alibabacloudslb controller should implement additional methods of ReconcileAdapter."),(0,o.kt)("h3",{id:"experimentaladapters"},"experimental/adapters"),(0,o.kt)("p",null,"The experimental/adapters is more like a pre-release pkg for built-in adapters. Usage of experimental/adapters is same\nwith built-in adapters, and be aware that ",(0,o.kt)("strong",{parentName:"p"},"DO NOT USE EXPERIMENTAL/ADAPTERS IN PRODUCTION")),(0,o.kt)("h3",{id:"demo-adapter"},"demo adapter"),(0,o.kt)("p",null,"A demo is implemented in ",(0,o.kt)("inlineCode",{parentName:"p"},"resource_controller_suite_test.go"),". In the demo controller, the employer is represented\nas a service and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoServiceStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n }\n}\n')),(0,o.kt)("p",null,"The employee is represented as a pod and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoPodStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n EmployeeStatuses: PodEmployeeStatuses{\n Ip: string,\n Ipv6: string,\n LifecycleReady: bool,\n ExtraStatus: PodExtraStatus{\n TrafficOn: bool,\n TrafficWeight: int,\n },\n }\n}\n")),(0,o.kt)("p",null,"The DemoResourceProviderClient is a fake client that handles backend provider resources related to the employer/employee\n(service/pods). In the Demo Controller, ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"\nare mocked as resources in the backend provider."),(0,o.kt)("p",null,"How the demo controller adapter realized will be introduced in detail as follows,\n",(0,o.kt)("inlineCode",{parentName:"p"},"DemoControllerAdapter")," was defined, including a kubernetes client and a resourceProviderClient. What included in\nthe Adapter struct can be defined as needed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type DemoControllerAdapter struct {\n client.Client\n resourceProviderClient *DemoResourceProviderClient\n}\n")),(0,o.kt)("p",null,"Declaring that the DemoControllerAdapter implemented ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileAdapter")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),".\nImplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"RconcileAdapter")," is a must action, while ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," isn't, check the remarks\nfor ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller/types.go")," to find why."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"var _ ReconcileAdapter = &DemoControllerAdapter{}\nvar _ ReconcileLifecycleOptions = &DemoControllerAdapter{}\n")),(0,o.kt)("p",null,"Following two methods for DemoControllerAdapter inplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),", defines whether\nDemoControllerAdapter following PodOpsLifecycle and need record employees."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"func (r *DemoControllerAdapter) FollowPodOpsLifeCycle() bool {\n return true\n}\n\nfunc (r *DemoControllerAdapter) NeedRecordEmployees() bool {\n return needRecordEmployees\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"IEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"IEmployee")," are interfaces that includes several methods indicating the status employer and\nemployee."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type IEmployer interface {\n GetEmployerId() string\n GetEmployerStatuses() interface{}\n EmployerEqual(employer IEmployer) (bool, error)\n}\n\ntype IEmployee interface {\n GetEmployeeId() string\n GetEmployeeName() string\n GetEmployeeStatuses() interface{}\n EmployeeEqual(employee IEmployee) (bool, error)\n}\n\ntype DemoServiceStatus struct {\n EmployerId string\n EmployerStatuses DemoServiceDetails\n}\n\ntype DemoServiceDetails struct {\n RemoteVIP string\n RemoteVIPQPS int\n}\n\ntype DemoPodStatus struct {\n EmployeeId string\n EmployeeName string\n EmployeeStatuses PodEmployeeStatuses\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," returns all employees' names selected by employer, here is pods' names selected by\nservice. ",(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," is used for ensuring LifecycleFinalizer and ExpectedFinalizer, so you can give\nit an empty return if your adapter doesn't follow PodOpsLifecycle."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) {\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n selected := make([]string, len(podList.Items))\n for idx, pod := range podList.Items {\n selected[idx] = pod.Name\n }\n\n return selected, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployer")," defines what is expected under the spec of employer and what is\ncurrent status, like the load balancer from a cloud provider. Here in the demo adapter, expected is defined by hardcode\nand current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return nil, nil\n }\n var expect []IEmployer\n expect = append(expect, DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n },\n })\n return expect, nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n var current []IEmployer\n\n req := &DemoResourceVipOps{}\n resp, err := r.resourceProviderClient.QueryVip(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource vip query resp is nil")\n }\n\n for _, employerStatus := range resp.VipStatuses {\n current = append(current, employerStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles creation/update/deletion of resources related to employer on\nrelated backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles\n",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n\n toCreateDemoServiceStatus := make([]DemoServiceStatus, len(toCreates))\n for idx, create := range toCreates {\n createDemoServiceStatus, ok := create.(DemoServiceStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreates employer is not DemoServiceStatus")\n }\n toCreateDemoServiceStatus[idx] = createDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.CreateVip(&DemoResourceVipOps{\n VipStatuses: toCreateDemoServiceStatus,\n })\n if err != nil {\n return nil, toCreates, err\n }\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoServiceStatus := make([]DemoServiceStatus, len(toUpdates))\n for idx, update := range toUpdates {\n updateDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdates employer is not DemoServiceStatus")\n }\n toUpdateDemoServiceStatus[idx] = updateDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.UpdateVip(&DemoResourceVipOps{\n VipStatuses: toUpdateDemoServiceStatus,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoServiceStatus := make([]DemoServiceStatus, len(toDeletes))\n for idx, update := range toDeletes {\n deleteDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDeletes employer is not DemoServiceStatus")\n }\n toDeleteDemoServiceStatus[idx] = deleteDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.DeleteVip(&DemoResourceVipOps{\n VipStatuses: toDeleteDemoServiceStatus,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n return toDeletes, nil, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployee"),"and",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployee")," defines what is expected under the spec of employer and employees\nand what is current status, like real servers under the load balancer from a cloud provider. Here in the demo adapter,\nexpected is calculated from pods and current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'// GetExpectEmployeeStatus return expect employee status\nfunc (r *DemoControllerAdapter) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return []IEmployee{}, nil\n }\n\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n expected := make([]IEmployee, len(podList.Items))\n expectIdx := 0\n for _, pod := range podList.Items {\n if !pod.DeletionTimestamp.IsZero() {\n continue\n }\n status := DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n }\n employeeStatuses, err := GetCommonPodEmployeeStatus(&pod)\n if err != nil {\n return nil, err\n }\n extraStatus := PodExtraStatus{}\n if employeeStatuses.LifecycleReady {\n extraStatus.TrafficOn = true\n extraStatus.TrafficWeight = 100\n } else {\n extraStatus.TrafficOn = false\n extraStatus.TrafficWeight = 0\n }\n employeeStatuses.ExtraStatus = extraStatus\n status.EmployeeStatuses = employeeStatuses\n expected[expectIdx] = status\n expectIdx++\n }\n\n return expected[:expectIdx], nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n var current []IEmployee\n req := &DemoResourceRsOps{}\n resp, err := r.resourceProviderClient.QueryRealServer(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource rs query resp is nil")\n }\n\n for _, rsStatus := range resp.RsStatuses {\n current = append(current, rsStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees")," handles creation/update/deletion of resources related to employee\non related backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees"),"\nhandles ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n toCreateDemoPodStatuses := make([]DemoPodStatus, len(toCreates))\n\n for idx, toCreate := range toCreates {\n podStatus, ok := toCreate.(DemoPodStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreate is not DemoPodStatus")\n }\n toCreateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.CreateRealServer(&DemoResourceRsOps{\n RsStatuses: toCreateDemoPodStatuses,\n })\n if err != nil {\n return nil, toCreates, err\n }\n\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoPodStatuses := make([]DemoPodStatus, len(toUpdates))\n\n for idx, toUpdate := range toUpdates {\n podStatus, ok := toUpdate.(DemoPodStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdate is not DemoPodStatus")\n }\n toUpdateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.UpdateRealServer(&DemoResourceRsOps{\n RsStatuses: toUpdateDemoPodStatuses,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoPodStatuses := make([]DemoPodStatus, len(toDeletes))\n\n for idx, toDelete := range toDeletes {\n podStatus, ok := toDelete.(DemoPodStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDelete is not DemoPodStatus")\n }\n toDeleteDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.DeleteRealServer(&DemoResourceRsOps{\n RsStatuses: toDeleteDemoPodStatuses,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n\n return toDeletes, nil, nil\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7772ebc2.11cd736f.js b/assets/js/7772ebc2.11cd736f.js deleted file mode 100644 index 420a70ffdb7..00000000000 --- a/assets/js/7772ebc2.11cd736f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2626],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(f,i(i({ref:n},p),{},{components:t})):r.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const a={id:"base-override"},i="Base and Override",s={unversionedId:"kusion/configuration-walkthrough/base-override",id:"version-v0.10/kusion/configuration-walkthrough/base-override",title:"Base and Override",description:"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/3-base-override.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/base-override",permalink:"/docs/kusion/configuration-walkthrough/base-override",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/3-base-override.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"base-override"},sidebar:"kusion",previous:{title:"KCL Basics",permalink:"/docs/kusion/configuration-walkthrough/kcl-basics"},next:{title:"Workload",permalink:"/docs/kusion/configuration-walkthrough/workload"}},c={},l=[],p={toc:l};function d(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"base-and-override"},"Base and Override"),(0,o.kt)("p",null,"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons."),(0,o.kt)("p",null,"In that context, we advocate for a pattern where you can leverage some Kusion and KCL features to minimize the amount of duplicate configurations, by separating the common base application configuration and environment-specific ones."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The file names in the below examples don't matter as long as they are called out and appear in the correct order in the ",(0,o.kt)("inlineCode",{parentName:"p"},"entries")," field (the field is a list) in ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod"),". The files with common configurations should appear first in the list and stack-specific ones last. The latter one takes precedence."),(0,o.kt)("p",{parentName:"admonition"},"The configurations also don't have be placed into a single ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," file. For complex projects, they can be broken down into smaller organized ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," files for better readability. ")),(0,o.kt)("p",null,"Base configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"base/base.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,o.kt)("p",null,"Environment-specific configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n # dev stack has different app configuration from the base\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n }\n replicas = 2\n }\n}\n')),(0,o.kt)("p",null,"Alternatively, you could locate a specific property (in this case below, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," object) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object using the dot selector shorthand(such as ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.containers.myapp")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.replicas")," below):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload.replicas = 2\n workload.containers.myapp: {\n # dev stack has different app configuration\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"This is especially useful when the application configuration is complex but the override is relatively straightforward."),(0,o.kt)("p",null,"The two examples above are equivalent when overriding the base."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7772ebc2.e028e064.js b/assets/js/7772ebc2.e028e064.js new file mode 100644 index 00000000000..16d01233154 --- /dev/null +++ b/assets/js/7772ebc2.e028e064.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2626],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(f,i(i({ref:n},p),{},{components:t})):r.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const a={id:"base-override"},i="Base and Override",s={unversionedId:"kusion/configuration-walkthrough/base-override",id:"version-v0.10/kusion/configuration-walkthrough/base-override",title:"Base and Override",description:"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/3-base-override.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/base-override",permalink:"/docs/kusion/configuration-walkthrough/base-override",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/3-base-override.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"base-override"},sidebar:"kusion",previous:{title:"KCL Basics",permalink:"/docs/kusion/configuration-walkthrough/kcl-basics"},next:{title:"Workload",permalink:"/docs/kusion/configuration-walkthrough/workload"}},c={},l=[],p={toc:l};function d(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"base-and-override"},"Base and Override"),(0,o.kt)("p",null,"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons."),(0,o.kt)("p",null,"In that context, we advocate for a pattern where you can leverage some Kusion and KCL features to minimize the amount of duplicate configurations, by separating the common base application configuration and environment-specific ones."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The file names in the below examples don't matter as long as they are called out and appear in the correct order in the ",(0,o.kt)("inlineCode",{parentName:"p"},"entries")," field (the field is a list) in ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod"),". The files with common configurations should appear first in the list and stack-specific ones last. The latter one takes precedence."),(0,o.kt)("p",{parentName:"admonition"},"The configurations also don't have be placed into a single ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," file. For complex projects, they can be broken down into smaller organized ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," files for better readability. ")),(0,o.kt)("p",null,"Base configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"base/base.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,o.kt)("p",null,"Environment-specific configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n # dev stack has different app configuration from the base\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n }\n replicas = 2\n }\n}\n')),(0,o.kt)("p",null,"Alternatively, you could locate a specific property (in this case below, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," object) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object using the dot selector shorthand(such as ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.containers.myapp")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.replicas")," below):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload.replicas = 2\n workload.containers.myapp: {\n # dev stack has different app configuration\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"This is especially useful when the application configuration is complex but the override is relatively straightforward."),(0,o.kt)("p",null,"The two examples above are equivalent when overriding the base."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/77c6b439.613db0a6.js b/assets/js/77c6b439.613db0a6.js new file mode 100644 index 00000000000..dee95806279 --- /dev/null +++ b/assets/js/77c6b439.613db0a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8527],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>h});var n=o(67294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var l=n.createContext({}),p=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var o=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(o),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||a;return o?n.createElement(m,r(r({ref:t},c),{},{components:o})):n.createElement(m,r({ref:t},c))}));function h(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=o.length,r=new Array(a);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=o(87462),i=(o(67294),o(3905));const a={id:"overview",title:"Overview",slug:"/"},r="Overview",s={unversionedId:"kusion/what-is-kusion/overview",id:"kusion/what-is-kusion/overview",title:"Overview",description:"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.",source:"@site/docs/kusion/1-what-is-kusion/1-overview.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/",permalink:"/docs/next/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/1-what-is-kusion/1-overview.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview",title:"Overview",slug:"/"},sidebar:"kusion",next:{title:"Kusion vs Other Software",permalink:"/docs/next/kusion/what-is-kusion/kusion-vs-x"}},l={},p=[{value:"What is Kusion?",id:"what-is-kusion",level:2},{value:"Why Kusion?",id:"why-kusion",level:2},{value:"Kusion Highlights",id:"kusion-highlights",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"overview"},"Overview"),(0,i.kt)("p",null,"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the ",(0,i.kt)("a",{parentName:"p",href:"kusion/getting-started/install-kusion"},"Getting Started")," section."),(0,i.kt)("h2",{id:"what-is-kusion"},"What is Kusion?"),(0,i.kt)("p",null,"Kusion is an intent-based Platform Orchestrator that enables developers to specify their desired intent in a declarative way and then using a consistent workflow to drive continuous deployment through application lifecycle. Inspired by the phrase ",(0,i.kt)("strong",{parentName:"p"},"Fusion on Kubernetes"),", Kusion aims to help application and platform developers to develop and deliver in a self-serviceable, fast, reliable, and collaborative way."),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,i.kt)("h2",{id:"why-kusion"},"Why Kusion?"),(0,i.kt)("p",null,"Developers should be able to deploy and run their applications and services end to end. ",(0,i.kt)("strong",{parentName:"p"},'"You build it, you run it", the original promise of DevOps.')),(0,i.kt)("p",null,"But the modern day for most software organizations this promise quickly become unrelalistic since the increasingly complex cloud-native toolchains, while cloud native technologies made huge improvements in areas such as scalability, availability and operability, it also brings downside - the growing burden on developers, which leads to the rise of ",(0,i.kt)("a",{parentName:"p",href:"https://platformengineering.org/"},"Platform Engineering"),"."),(0,i.kt)("p",null,"Another challenge we saw is that a series of ",(0,i.kt)("a",{parentName:"p",href:"https://web.devopstopologies.com/#anti-types"},"antipatterns")," emerge when regular software organizations tries to implement true DevOps. Without well proven reference architecture and supporting tools, it's much more difficult to accomplish the original promise."),(0,i.kt)("p",null,"On one hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion was build to minimize developer's cognitive load"),". With application-centric configuration model, you don't need to deal with tedious infrastructure and configuration management tooling, all you need to be familiar with is ",(0,i.kt)("a",{parentName:"p",href:"kusion/configuration-walkthrough/overview"},"AppConfiguration"),". This approach shields developers from the configurational complexity of Kubernetes but still enable standardization by design."),(0,i.kt)("p",null,"On the other hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion defines a new way for different engineering organizations to collaborate"),'. With the separation of concerns, different roles could focus on their aspects of the configuration based on their knowledge and responsibility, whereas Kusion will dynamically manage and "glue" the opinionated configurations together. Through such a division of labor, the platform team can better manage the differences and complexities of the platform, and app developers could participate in ops work with much less cognitive load.'),(0,i.kt)("h2",{id:"kusion-highlights"},"Kusion Highlights"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Platform as Code")),(0,i.kt)("p",{parentName:"li"},"Specify desired application intent through declarative configuration code, drive continuous deployment with any CI/CD systems or GitOps to match that intent. No ad-hoc scripts, no hard maintain custom workflows, just declarative configuration code.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Dynamic Configuration Management")),(0,i.kt)("p",{parentName:"li"},"Enable platform teams to set baseline-templates, control how and where to deploy application workloads and provision accessory resources. While still enabling application developers freedom via workload-centric specification and deployment. ")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Security & Compliance Built In")),(0,i.kt)("p",{parentName:"li"},"Enforce security and infrastructure best practices with out-of-box ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"base models"),", create security and compliance guardrails for any Kusion deploy with third-party Policy as Code tools. All accessory resource secrets are automatically injected into Workloads.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Lightweight and Open Model Ecosystem")),(0,i.kt)("p",{parentName:"li"},"Pure client-side solution ensures good portability and the rich APIs make it easier to integrate and automate. Large growing model ecosystem covers all stages in application lifecycle, with extensive connections to various infrastructure capabilities. "))),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"Kusion is an early project.")," The end goal of Kusion is to boost ",(0,i.kt)("a",{parentName:"p",href:"https://internaldeveloperplatform.org/"},"Internal Developer Platform")," revolution, and we are iterating on Kusion quickly to strive towards this goal. For any help or feedback, please contact us in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/community/discussions/categories/meeting"},"Slack")," or ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"issues"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/77c6b439.a486d3a5.js b/assets/js/77c6b439.a486d3a5.js deleted file mode 100644 index fe4e798c702..00000000000 --- a/assets/js/77c6b439.a486d3a5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8527],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>h});var n=o(67294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var l=n.createContext({}),p=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var o=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(o),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||a;return o?n.createElement(m,r(r({ref:t},c),{},{components:o})):n.createElement(m,r({ref:t},c))}));function h(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=o.length,r=new Array(a);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=o(87462),i=(o(67294),o(3905));const a={id:"overview",title:"Overview",slug:"/"},r="Overview",s={unversionedId:"kusion/what-is-kusion/overview",id:"kusion/what-is-kusion/overview",title:"Overview",description:"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.",source:"@site/docs/kusion/1-what-is-kusion/1-overview.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/",permalink:"/docs/next/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/1-what-is-kusion/1-overview.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview",title:"Overview",slug:"/"},sidebar:"kusion",next:{title:"Kusion vs Other Software",permalink:"/docs/next/kusion/what-is-kusion/kusion-vs-x"}},l={},p=[{value:"What is Kusion?",id:"what-is-kusion",level:2},{value:"Why Kusion?",id:"why-kusion",level:2},{value:"Kusion Highlights",id:"kusion-highlights",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"overview"},"Overview"),(0,i.kt)("p",null,"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the ",(0,i.kt)("a",{parentName:"p",href:"kusion/getting-started/install-kusion"},"Getting Started")," section."),(0,i.kt)("h2",{id:"what-is-kusion"},"What is Kusion?"),(0,i.kt)("p",null,"Kusion is an intent-based Platform Orchestrator that enables developers to specify their desired intent in a declarative way and then using a consistent workflow to drive continuous deployment through application lifecycle. Inspired by the phrase ",(0,i.kt)("strong",{parentName:"p"},"Fusion on Kubernetes"),", Kusion aims to help application and platform developers to develop and deliver in a self-serviceable, fast, reliable, and collaborative way."),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,i.kt)("h2",{id:"why-kusion"},"Why Kusion?"),(0,i.kt)("p",null,"Developers should be able to deploy and run their applications and services end to end. ",(0,i.kt)("strong",{parentName:"p"},'"You build it, you run it", the original promise of DevOps.')),(0,i.kt)("p",null,"But the modern day for most software organizations this promise quickly become unrelalistic since the increasingly complex cloud-native toolchains, while cloud native technologies made huge improvements in areas such as scalability, availability and operability, it also brings downside - the growing burden on developers, which leads to the rise of ",(0,i.kt)("a",{parentName:"p",href:"https://platformengineering.org/"},"Platform Engineering"),"."),(0,i.kt)("p",null,"Another challenge we saw is that a series of ",(0,i.kt)("a",{parentName:"p",href:"https://web.devopstopologies.com/#anti-types"},"antipatterns")," emerge when regular software organizations tries to implement true DevOps. Without well proven reference architecture and supporting tools, it's much more difficult to accomplish the original promise."),(0,i.kt)("p",null,"On one hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion was build to minimize developer's cognitive load"),". With application-centric configuration model, you don't need to deal with tedious infrastructure and configuration management tooling, all you need to be familiar with is ",(0,i.kt)("a",{parentName:"p",href:"kusion/configuration-walkthrough/overview"},"AppConfiguration"),". This approach shields developers from the configurational complexity of Kubernetes but still enable standardization by design."),(0,i.kt)("p",null,"On the other hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion defines a new way for different engineering organizations to collaborate"),'. With the separation of concerns, different roles could focus on their aspects of the configuration based on their knowledge and responsibility, whereas Kusion will dynamically manage and "glue" the opinionated configurations together. Through such a division of labor, the platform team can better manage the differences and complexities of the platform, and app developers could participate in ops work with much less cognitive load.'),(0,i.kt)("h2",{id:"kusion-highlights"},"Kusion Highlights"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Platform as Code")),(0,i.kt)("p",{parentName:"li"},"Specify desired application intent through declarative configuration code, drive continuous deployment with any CI/CD systems or GitOps to match that intent. No ad-hoc scripts, no hard maintain custom workflows, just declarative configuration code.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Dynamic Configuration Management")),(0,i.kt)("p",{parentName:"li"},"Enable platform teams to set baseline-templates, control how and where to deploy application workloads and provision accessory resources. While still enabling application developers freedom via workload-centric specification and deployment. ")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Security & Compliance Built In")),(0,i.kt)("p",{parentName:"li"},"Enforce security and infrastructure best practices with out-of-box ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"base models"),", create security and compliance guardrails for any Kusion deploy with third-party Policy as Code tools. All accessory resource secrets are automatically injected into Workloads.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Lightweight and Open Model Ecosystem")),(0,i.kt)("p",{parentName:"li"},"Pure client-side solution ensures good portability and the rich APIs make it easier to integrate and automate. Large growing model ecosystem covers all stages in application lifecycle, with extensive connections to various infrastructure capabilities. "))),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"Kusion is an early project.")," The end goal of Kusion is to boost ",(0,i.kt)("a",{parentName:"p",href:"https://internaldeveloperplatform.org/"},"Internal Developer Platform")," revolution, and we are iterating on Kusion quickly to strive towards this goal. For any help or feedback, please contact us in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/community/discussions/categories/meeting"},"Slack")," or ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"issues"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/78ec9a9a.0ec5e5f6.js b/assets/js/78ec9a9a.0ec5e5f6.js deleted file mode 100644 index eed00435832..00000000000 --- a/assets/js/78ec9a9a.0ec5e5f6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9193],{3905:(e,a,n)=>{n.d(a,{Zo:()=>r,kt:()=>m});var t=n(67294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function i(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=t.createContext({}),d=function(e){var a=t.useContext(p),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},r=function(e){var a=d(e.components);return t.createElement(p.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},u=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,i=e.originalType,p=e.parentName,r=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=l,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return n?t.createElement(g,o(o({ref:a},r),{},{components:n})):t.createElement(g,o({ref:a},r))}));function m(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var i=n.length,o=new Array(i);o[0]=u;var s={};for(var p in a)hasOwnProperty.call(a,p)&&(s[p]=a[p]);s.originalType=e,s.mdxType="string"==typeof e?e:l,o[1]=s;for(var d=2;d{n.r(a),n.d(a,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var t=n(87462),l=(n(67294),n(3905));const i={sidebar_position:1},o="CollaSet",s={unversionedId:"operating/manuals/collaset",id:"operating/manuals/collaset",title:"CollaSet",description:"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.",source:"@site/docs/operating/manuals/collaset.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/collaset",permalink:"/docs/next/operating/manuals/collaset",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/collaset.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"operating",previous:{title:"PodOpsLifecycle",permalink:"/docs/next/operating/concepts/podopslifecycle"},next:{title:"ResourceConsist",permalink:"/docs/next/operating/manuals/resourceconsist"}},p={},d=[{value:"Basic Features",id:"basic-features",level:2},{value:"Scaling Pods",id:"scaling-pods",level:3},{value:"Updating Pods",id:"updating-pods",level:3},{value:"Partition",id:"partition",level:4},{value:"Update by Label",id:"update-by-label",level:4},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Scaling Pods",id:"scaling-pods-1",level:3},{value:"Pod Instance ID",id:"pod-instance-id",level:4},{value:"Revision Consistency",id:"revision-consistency",level:4},{value:"Updating Pods",id:"updating-pods-1",level:3},{value:"Update Policy",id:"update-policy",level:4}],r={toc:d};function c(e){let{components:a,...n}=e;return(0,l.kt)("wrapper",(0,t.Z)({},r,n,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"collaset"},"CollaSet"),(0,l.kt)("p",null,"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods."),(0,l.kt)("p",null,"A basic CollaSet configuration is represented in the following YAML format:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Let's explore the features of CollaSet."),(0,l.kt)("h2",{id:"basic-features"},"Basic Features"),(0,l.kt)("h3",{id:"scaling-pods"},"Scaling Pods"),(0,l.kt)("p",null,"CollaSet utilizes the field spec.replicas to indicate the number of Pods under management."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 3 # indicate the number of Pods to manage\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n...\n")),(0,l.kt)("p",null,"Pods can be provisioned by CollaSet."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-85q7g 1/1 Running 0 57s\ncollaset-sample-vx5ws 1/1 Running 0 57s\ncollaset-sample-hr7pv 1/1 Running 0 57s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("p",null,"By default, CollaSet always creates new Pods using the latest template specified in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". CollaSet establishes ownership over a set of Pods through the label selector defined in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector"),". Thus, it's important to ensure that the labels provided in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector")," match those in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template.metadata.labels"),"."),(0,l.kt)("p",null,"CollaSet status provides general information about this CollaSet and all Pods under it."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get cls collaset-sample -o yaml\n......\nstatus:\n availableReplicas: 3\n collisionCount: 0\n conditions:\n - lastTransitionTime: "2023-09-01T03:56:09Z"\n reason: Updated\n status: "True"\n type: Update\n currentRevision: collaset-sample-6d7b7c58f\n observedGeneration: 1\n operatingReplicas: 0\n readyReplicas: 3\n replicas: 3\n scheduledReplicas: 3\n updatedAvailableReplicas: 3\n updatedReadyReplicas: 3\n updatedReplicas: 3\n updatedRevision: collaset-sample-6d7b7c58f\n')),(0,l.kt)("p",null,"Some fields in CollaSet status are explained here:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedRevision")," indicates the latest revision that CollaSet uses to create or update Pods."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"currentRevision")," indicates the last updated revision. It will be set to updatedRevision after all Pods are updated, and their PodReady conditions become True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"replicas")," indicates the count of Pods under this CollaSet."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"scheduledReplicas")," indicates the count of Pods under this CollaSet that successfully got scheduled."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"availableReplicas")," indicates the count of Pods under this CollaSet that have all expected finalizers attached."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," indicates the count of Pods under this CollaSet that have the updated revision."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," indicates the count of Pods under this CollaSet that are counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," and have their PodReady conditions set to True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedAvailableReplicas")," indicates the count of Pods under this CollaSet that is counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," and have all expected finalizers attached."),(0,l.kt)("h3",{id:"updating-pods"},"Updating Pods"),(0,l.kt)("p",null,"CollaSet generates Pods according to the pod template described in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". This template can be updated to signal CollaSet to update each owned Pod:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n......\nspec:\n......\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n......\n")),(0,l.kt)("p",null,"CollaSet immediately updates all Pods it owns with the new Pod template by default."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("p",null,"The update progress can be controlled using partition."),(0,l.kt)("h4",{id:"partition"},"Partition"),(0,l.kt)("p",null,"Similar to StatefulSet, ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," is used to control the upgrade progress."),(0,l.kt)("p",null,"By default, if not indicated, all Pods will be updated when spec.template changes. The ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," can be adjusted from 0 to ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.replicas")," to specify how many Pods CollaSet should update. ",(0,l.kt)("strong",{parentName:"p"},"Unlike StatefulSet, the partition in CollaSet represents the number of Pods to update.")),(0,l.kt)("p",null,"Let's update the image back to nginx:1.25.2:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.25.2 # changed from nginx:1.24.0 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # use partition to control upgrade progress\n")),(0,l.kt)("p",null,"In this case, CollaSet only updates 1 Pod to the updated revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.25.2 # only 1 Pod updated\n - image: nginx:1.24.0\n')),(0,l.kt)("h4",{id:"update-by-label"},"Update by Label"),(0,l.kt)("p",null,"By configuring the ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," rolling update policy, users can precisely specify which Pods they want to update by using labels."),(0,l.kt)("p",null,"If you go back to the sample in the ",(0,l.kt)("a",{parentName:"p",href:"#Partition"},"section Partition")," and change ",(0,l.kt)("inlineCode",{parentName:"p"},"byPartition")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," like the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n- byPartition:\n- partition: 1\n+ byLabel: {}\n")),(0,l.kt)("p",null,"Subsequently, each Pod will only be updated if it's marked with the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/update-included"),"."),(0,l.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,l.kt)("h3",{id:"scaling-pods-1"},"Scaling Pods"),(0,l.kt)("h4",{id:"pod-instance-id"},"Pod Instance ID"),(0,l.kt)("p",null,"Each Pod created by CollaSet has a unique ID held by the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/instance-id"),", which can be used to identify each individual Pod."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: Pod\nmetadata:\n labels:\n collaset.kusionstack.io/instance-id: "0" # Pod instance ID\n...\n')),(0,l.kt)("p",null,"CollaSet provides a context to specify an ID pool, which defaults to the same name as the CollaSet and is immutable."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"...\nspec:\n scaleStrategy:\n context: \n")),(0,l.kt)("p",null,"The same ID pool name can be indicated for multiple CollaSets, allowing them to share a single ID pool. Consequently, each Pod created by these CollaSets will be assigned a unique ID."),(0,l.kt)("p",null,"For example, these are two CollaSets with the same context:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ cat ~/sample.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-a\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n---\n\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-b\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Then create these CollaSets with the sample file:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default apply -f ~/sample.yaml\ncollaset.apps.kusionstack.io/collaset-sample-a created\ncollaset.apps.kusionstack.io/collaset-sample-b created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-a-g4sjj 1/1 Running 0 42s\ncollaset-sample-a-ph9vc 1/1 Running 0 42s\ncollaset-sample-b-fqkq4 1/1 Running 0 42s\ncollaset-sample-b-lqg8f 1/1 Running 0 42s\n\n$ kubectl -n default get pod -o yaml | grep collaset.kusionstack.io/instance-id\n collaset.kusionstack.io/instance-id: "0"\n collaset.kusionstack.io/instance-id: "1"\n collaset.kusionstack.io/instance-id: "3"\n collaset.kusionstack.io/instance-id: "2"\n')),(0,l.kt)("p",null,"Now, the 4 Pods created by these 2 CollaSets will have a unique instance ID."),(0,l.kt)("h4",{id:"revision-consistency"},"Revision Consistency"),(0,l.kt)("p",null,"Pods within a CollaSet can utilize more than two different Pod templates simultaneously, including both the current and updated revisions. This can result from partial updates. To ensure the stability of Pod revisions over time, CollaSet records this information. When a Pod is deleted, CollaSet recreates it using its previous revision."),(0,l.kt)("p",null,"It can be reproduced by following steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Provision a new CollaSet with replicas 3.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 4s\ncollaset-sample-glgnb 1/1 Running 0 4s\ncollaset-sample-qs46r 1/1 Running 0 4s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.24.0 and set the partition to 2. Then there will be 2 Pods with image nginx:1.24.0 and 1 Pod with image nginx:1.25.2.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 2 # update 2 Pods\n\n# Wait until these 2 Pods are updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("ol",{start:3},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.23.4 and set the partition to 1.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.23.4 # changed from nginx:1.24.0\n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # update 1 Pod\n\n# Wait until the Pod is updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # Pod collaset-sample-qs46r\n - image: nginx:1.23.4\n')),(0,l.kt)("p",null,"Now, there are 3 Pods, each of which has an individual image. If we then delete the Pod with the image nginx:1.24.0, the new Pod replacing it will be created with the same image nginx:1.24.0 in order for the Pod to inherit the revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl delete -n default delete pod collaset-sample-qs46r\npod "collaset-sample-qs46r" deleted\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 3h\ncollaset-sample-ht9x6 1/1 Running 0 2m27s # Pod recreated\ncollaset-sample-qs46r 1/1 Running 1 (3h ago) 3h\n\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # image has not been changed\n - image: nginx:1.23.4\n')),(0,l.kt)("h3",{id:"updating-pods-1"},"Updating Pods"),(0,l.kt)("h4",{id:"update-policy"},"Update Policy"),(0,l.kt)("p",null,"In addition to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," update policy, which is identical to Deployment and StatefulSet, CollaSet offers the ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," update policy."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # Options: InPlaceIfPossible, ReCreate\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," is the default value, which instructs CollaSets to try to update Pods in place when only container images, labels, and annotations have changed. If some other fields have changed too, the policy will back off to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," policy."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," indicates CollaSets always delete the old Pod and create a new one with an updated revision."),(0,l.kt)("p",null,"If update pod template with ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," policy as following example, the Pod will not be recreated."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # use InPlaceIfPossible policy\n\n$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5wvlh 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-ldvrg 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-pbz75 1/1 Running 1 (6s ago) 2m10s\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/78ec9a9a.4cdedd58.js b/assets/js/78ec9a9a.4cdedd58.js new file mode 100644 index 00000000000..9c8035b1ed7 --- /dev/null +++ b/assets/js/78ec9a9a.4cdedd58.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9193],{3905:(e,a,n)=>{n.d(a,{Zo:()=>r,kt:()=>m});var t=n(67294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function i(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=t.createContext({}),d=function(e){var a=t.useContext(p),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},r=function(e){var a=d(e.components);return t.createElement(p.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},u=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,i=e.originalType,p=e.parentName,r=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=l,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return n?t.createElement(g,o(o({ref:a},r),{},{components:n})):t.createElement(g,o({ref:a},r))}));function m(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var i=n.length,o=new Array(i);o[0]=u;var s={};for(var p in a)hasOwnProperty.call(a,p)&&(s[p]=a[p]);s.originalType=e,s.mdxType="string"==typeof e?e:l,o[1]=s;for(var d=2;d{n.r(a),n.d(a,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var t=n(87462),l=(n(67294),n(3905));const i={sidebar_position:1},o="CollaSet",s={unversionedId:"operating/manuals/collaset",id:"operating/manuals/collaset",title:"CollaSet",description:"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.",source:"@site/docs/operating/manuals/collaset.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/collaset",permalink:"/docs/next/operating/manuals/collaset",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/collaset.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"operating",previous:{title:"PodOpsLifecycle",permalink:"/docs/next/operating/concepts/podopslifecycle"},next:{title:"ResourceConsist",permalink:"/docs/next/operating/manuals/resourceconsist"}},p={},d=[{value:"Basic Features",id:"basic-features",level:2},{value:"Scaling Pods",id:"scaling-pods",level:3},{value:"Updating Pods",id:"updating-pods",level:3},{value:"Partition",id:"partition",level:4},{value:"Update by Label",id:"update-by-label",level:4},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Scaling Pods",id:"scaling-pods-1",level:3},{value:"Pod Instance ID",id:"pod-instance-id",level:4},{value:"Revision Consistency",id:"revision-consistency",level:4},{value:"Updating Pods",id:"updating-pods-1",level:3},{value:"Update Policy",id:"update-policy",level:4}],r={toc:d};function c(e){let{components:a,...n}=e;return(0,l.kt)("wrapper",(0,t.Z)({},r,n,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"collaset"},"CollaSet"),(0,l.kt)("p",null,"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods."),(0,l.kt)("p",null,"A basic CollaSet configuration is represented in the following YAML format:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Let's explore the features of CollaSet."),(0,l.kt)("h2",{id:"basic-features"},"Basic Features"),(0,l.kt)("h3",{id:"scaling-pods"},"Scaling Pods"),(0,l.kt)("p",null,"CollaSet utilizes the field spec.replicas to indicate the number of Pods under management."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 3 # indicate the number of Pods to manage\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n...\n")),(0,l.kt)("p",null,"Pods can be provisioned by CollaSet."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-85q7g 1/1 Running 0 57s\ncollaset-sample-vx5ws 1/1 Running 0 57s\ncollaset-sample-hr7pv 1/1 Running 0 57s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("p",null,"By default, CollaSet always creates new Pods using the latest template specified in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". CollaSet establishes ownership over a set of Pods through the label selector defined in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector"),". Thus, it's important to ensure that the labels provided in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector")," match those in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template.metadata.labels"),"."),(0,l.kt)("p",null,"CollaSet status provides general information about this CollaSet and all Pods under it."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get cls collaset-sample -o yaml\n......\nstatus:\n availableReplicas: 3\n collisionCount: 0\n conditions:\n - lastTransitionTime: "2023-09-01T03:56:09Z"\n reason: Updated\n status: "True"\n type: Update\n currentRevision: collaset-sample-6d7b7c58f\n observedGeneration: 1\n operatingReplicas: 0\n readyReplicas: 3\n replicas: 3\n scheduledReplicas: 3\n updatedAvailableReplicas: 3\n updatedReadyReplicas: 3\n updatedReplicas: 3\n updatedRevision: collaset-sample-6d7b7c58f\n')),(0,l.kt)("p",null,"Some fields in CollaSet status are explained here:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedRevision")," indicates the latest revision that CollaSet uses to create or update Pods."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"currentRevision")," indicates the last updated revision. It will be set to updatedRevision after all Pods are updated, and their PodReady conditions become True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"replicas")," indicates the count of Pods under this CollaSet."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"scheduledReplicas")," indicates the count of Pods under this CollaSet that successfully got scheduled."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"availableReplicas")," indicates the count of Pods under this CollaSet that have all expected finalizers attached."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," indicates the count of Pods under this CollaSet that have the updated revision."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," indicates the count of Pods under this CollaSet that are counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," and have their PodReady conditions set to True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedAvailableReplicas")," indicates the count of Pods under this CollaSet that is counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," and have all expected finalizers attached."),(0,l.kt)("h3",{id:"updating-pods"},"Updating Pods"),(0,l.kt)("p",null,"CollaSet generates Pods according to the pod template described in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". This template can be updated to signal CollaSet to update each owned Pod:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n......\nspec:\n......\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n......\n")),(0,l.kt)("p",null,"CollaSet immediately updates all Pods it owns with the new Pod template by default."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("p",null,"The update progress can be controlled using partition."),(0,l.kt)("h4",{id:"partition"},"Partition"),(0,l.kt)("p",null,"Similar to StatefulSet, ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," is used to control the upgrade progress."),(0,l.kt)("p",null,"By default, if not indicated, all Pods will be updated when spec.template changes. The ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," can be adjusted from 0 to ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.replicas")," to specify how many Pods CollaSet should update. ",(0,l.kt)("strong",{parentName:"p"},"Unlike StatefulSet, the partition in CollaSet represents the number of Pods to update.")),(0,l.kt)("p",null,"Let's update the image back to nginx:1.25.2:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.25.2 # changed from nginx:1.24.0 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # use partition to control upgrade progress\n")),(0,l.kt)("p",null,"In this case, CollaSet only updates 1 Pod to the updated revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.25.2 # only 1 Pod updated\n - image: nginx:1.24.0\n')),(0,l.kt)("h4",{id:"update-by-label"},"Update by Label"),(0,l.kt)("p",null,"By configuring the ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," rolling update policy, users can precisely specify which Pods they want to update by using labels."),(0,l.kt)("p",null,"If you go back to the sample in the ",(0,l.kt)("a",{parentName:"p",href:"#Partition"},"section Partition")," and change ",(0,l.kt)("inlineCode",{parentName:"p"},"byPartition")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," like the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n- byPartition:\n- partition: 1\n+ byLabel: {}\n")),(0,l.kt)("p",null,"Subsequently, each Pod will only be updated if it's marked with the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/update-included"),"."),(0,l.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,l.kt)("h3",{id:"scaling-pods-1"},"Scaling Pods"),(0,l.kt)("h4",{id:"pod-instance-id"},"Pod Instance ID"),(0,l.kt)("p",null,"Each Pod created by CollaSet has a unique ID held by the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/instance-id"),", which can be used to identify each individual Pod."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: Pod\nmetadata:\n labels:\n collaset.kusionstack.io/instance-id: "0" # Pod instance ID\n...\n')),(0,l.kt)("p",null,"CollaSet provides a context to specify an ID pool, which defaults to the same name as the CollaSet and is immutable."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"...\nspec:\n scaleStrategy:\n context: \n")),(0,l.kt)("p",null,"The same ID pool name can be indicated for multiple CollaSets, allowing them to share a single ID pool. Consequently, each Pod created by these CollaSets will be assigned a unique ID."),(0,l.kt)("p",null,"For example, these are two CollaSets with the same context:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ cat ~/sample.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-a\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n---\n\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-b\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Then create these CollaSets with the sample file:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default apply -f ~/sample.yaml\ncollaset.apps.kusionstack.io/collaset-sample-a created\ncollaset.apps.kusionstack.io/collaset-sample-b created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-a-g4sjj 1/1 Running 0 42s\ncollaset-sample-a-ph9vc 1/1 Running 0 42s\ncollaset-sample-b-fqkq4 1/1 Running 0 42s\ncollaset-sample-b-lqg8f 1/1 Running 0 42s\n\n$ kubectl -n default get pod -o yaml | grep collaset.kusionstack.io/instance-id\n collaset.kusionstack.io/instance-id: "0"\n collaset.kusionstack.io/instance-id: "1"\n collaset.kusionstack.io/instance-id: "3"\n collaset.kusionstack.io/instance-id: "2"\n')),(0,l.kt)("p",null,"Now, the 4 Pods created by these 2 CollaSets will have a unique instance ID."),(0,l.kt)("h4",{id:"revision-consistency"},"Revision Consistency"),(0,l.kt)("p",null,"Pods within a CollaSet can utilize more than two different Pod templates simultaneously, including both the current and updated revisions. This can result from partial updates. To ensure the stability of Pod revisions over time, CollaSet records this information. When a Pod is deleted, CollaSet recreates it using its previous revision."),(0,l.kt)("p",null,"It can be reproduced by following steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Provision a new CollaSet with replicas 3.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 4s\ncollaset-sample-glgnb 1/1 Running 0 4s\ncollaset-sample-qs46r 1/1 Running 0 4s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.24.0 and set the partition to 2. Then there will be 2 Pods with image nginx:1.24.0 and 1 Pod with image nginx:1.25.2.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 2 # update 2 Pods\n\n# Wait until these 2 Pods are updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("ol",{start:3},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.23.4 and set the partition to 1.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.23.4 # changed from nginx:1.24.0\n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # update 1 Pod\n\n# Wait until the Pod is updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # Pod collaset-sample-qs46r\n - image: nginx:1.23.4\n')),(0,l.kt)("p",null,"Now, there are 3 Pods, each of which has an individual image. If we then delete the Pod with the image nginx:1.24.0, the new Pod replacing it will be created with the same image nginx:1.24.0 in order for the Pod to inherit the revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl delete -n default delete pod collaset-sample-qs46r\npod "collaset-sample-qs46r" deleted\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 3h\ncollaset-sample-ht9x6 1/1 Running 0 2m27s # Pod recreated\ncollaset-sample-qs46r 1/1 Running 1 (3h ago) 3h\n\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # image has not been changed\n - image: nginx:1.23.4\n')),(0,l.kt)("h3",{id:"updating-pods-1"},"Updating Pods"),(0,l.kt)("h4",{id:"update-policy"},"Update Policy"),(0,l.kt)("p",null,"In addition to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," update policy, which is identical to Deployment and StatefulSet, CollaSet offers the ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," update policy."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # Options: InPlaceIfPossible, ReCreate\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," is the default value, which instructs CollaSets to try to update Pods in place when only container images, labels, and annotations have changed. If some other fields have changed too, the policy will back off to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," policy."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," indicates CollaSets always delete the old Pod and create a new one with an updated revision."),(0,l.kt)("p",null,"If update pod template with ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," policy as following example, the Pod will not be recreated."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # use InPlaceIfPossible policy\n\n$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5wvlh 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-ldvrg 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-pbz75 1/1 Running 1 (6s ago) 2m10s\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/79b30505.121a45b0.js b/assets/js/79b30505.121a45b0.js new file mode 100644 index 00000000000..d0aace4b0af --- /dev/null +++ b/assets/js/79b30505.121a45b0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3038],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,g=d["".concat(l,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},u),{},{components:n})):r.createElement(g,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const i={},a="What is KusionStack Operating?",s={unversionedId:"operating/introduction/introduction",id:"version-v0.10/operating/introduction/introduction",title:"What is KusionStack Operating?",description:"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,",source:"@site/versioned_docs/version-v0.10/operating/introduction/introduction.md",sourceDirName:"operating/introduction",slug:"/operating/introduction/",permalink:"/docs/operating/introduction/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/introduction/introduction.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",next:{title:"Installation",permalink:"/docs/operating/started/install"}},l={},c=[{value:"Key features",id:"key-features",level:2},{value:"Fine-grained operation",id:"fine-grained-operation",level:3},{value:"Advanced workloads",id:"advanced-workloads",level:3},{value:"Streamlined Pod Operation",id:"streamlined-pod-operation",level:3},{value:"Risk management",id:"risk-management",level:3},{value:"Future works",id:"future-works",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"what-is-kusionstack-operating"},"What is KusionStack Operating?"),(0,o.kt)("p",null,"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,\nwith a primary aim of bridging the gap between platform development and Kubernetes."),(0,o.kt)("p",null,"By keeping more operation works finished in Kubernetes layer,\nKusionStack Operating reduces complexity when interacting with Kubernetes\nand enhances convenience for platform developers."),(0,o.kt)("h2",{id:"key-features"},"Key features"),(0,o.kt)("p",null,"KusionStack Operating currently provides the following features,\nstreamlining application operations when developing platforms based on Kubernetes:"),(0,o.kt)("h3",{id:"fine-grained-operation"},"Fine-grained operation"),(0,o.kt)("p",null,"KusionStack Operating introduces PodOpsLifecycle to extend native Pod lifecycle with additional phases such as PreCheck, Preparing, etc.\nAll operators within KusionStack Operating will respect PodOpsLifecycle,\nso that PodOpsLifecycle is able to orchestrate all of these operators to operate each Pod coordinately. "),(0,o.kt)("h3",{id:"advanced-workloads"},"Advanced workloads"),(0,o.kt)("p",null,"KusionStack Operating offers several workloads to ensure it is convenient and effective to delivery and operate application resources."),(0,o.kt)("p",null,"Recently, Operating provides the workload CollaSet.\nBesides the basic ability of scaling and updating Pods like Deployment and StatefulSet of Kubernetes,\nCollaSet also provides a range of scale and update strategies,\nlike in-place update with container image and pod revision consistency."),(0,o.kt)("h3",{id:"streamlined-pod-operation"},"Streamlined Pod Operation"),(0,o.kt)("p",null,"KusionStack Operating introduces resource consist framework that offers a graceful way\nto integrate resource management around Pods, including traffic control, into the PodOpsLifecycle.\nThis simplifies the works for platform developers dealing with Pod operation details.\nKusionStack also integrates some resources by default, such as Aliyun SLB."),(0,o.kt)("h3",{id:"risk-management"},"Risk management"),(0,o.kt)("p",null,"Building upon the PodOpsLifecycle, KusionStack Operating introduces the workload named PodTransitionRule\nwhich will keep risks of pod operation under control.\nBy providing a MaxUnavailable rule similar to Kubernetes' PodDisruptionBudget (PDB),\nit ensures there are always enough Pods available for service.\nFurthermore, it allows for custom rules through extension via webhooks and label hooks."),(0,o.kt)("h2",{id:"future-works"},"Future works"),(0,o.kt)("p",null,"KusionStack Operating project is currently in its early stages.\nOur goal is to simplify platform development. We will continue building in areas such as application operations,\nobservability, and insight. We hope the Operating will make it easier for you to build platforms."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/79b30505.afc2508c.js b/assets/js/79b30505.afc2508c.js deleted file mode 100644 index f497e29f569..00000000000 --- a/assets/js/79b30505.afc2508c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3038],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,g=d["".concat(l,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},u),{},{components:n})):r.createElement(g,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const i={},a="What is KusionStack Operating?",s={unversionedId:"operating/introduction/introduction",id:"version-v0.10/operating/introduction/introduction",title:"What is KusionStack Operating?",description:"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,",source:"@site/versioned_docs/version-v0.10/operating/introduction/introduction.md",sourceDirName:"operating/introduction",slug:"/operating/introduction/",permalink:"/docs/operating/introduction/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/introduction/introduction.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",next:{title:"Installation",permalink:"/docs/operating/started/install"}},l={},c=[{value:"Key features",id:"key-features",level:2},{value:"Fine-grained operation",id:"fine-grained-operation",level:3},{value:"Advanced workloads",id:"advanced-workloads",level:3},{value:"Streamlined Pod Operation",id:"streamlined-pod-operation",level:3},{value:"Risk management",id:"risk-management",level:3},{value:"Future works",id:"future-works",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"what-is-kusionstack-operating"},"What is KusionStack Operating?"),(0,o.kt)("p",null,"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,\nwith a primary aim of bridging the gap between platform development and Kubernetes."),(0,o.kt)("p",null,"By keeping more operation works finished in Kubernetes layer,\nKusionStack Operating reduces complexity when interacting with Kubernetes\nand enhances convenience for platform developers."),(0,o.kt)("h2",{id:"key-features"},"Key features"),(0,o.kt)("p",null,"KusionStack Operating currently provides the following features,\nstreamlining application operations when developing platforms based on Kubernetes:"),(0,o.kt)("h3",{id:"fine-grained-operation"},"Fine-grained operation"),(0,o.kt)("p",null,"KusionStack Operating introduces PodOpsLifecycle to extend native Pod lifecycle with additional phases such as PreCheck, Preparing, etc.\nAll operators within KusionStack Operating will respect PodOpsLifecycle,\nso that PodOpsLifecycle is able to orchestrate all of these operators to operate each Pod coordinately. "),(0,o.kt)("h3",{id:"advanced-workloads"},"Advanced workloads"),(0,o.kt)("p",null,"KusionStack Operating offers several workloads to ensure it is convenient and effective to delivery and operate application resources."),(0,o.kt)("p",null,"Recently, Operating provides the workload CollaSet.\nBesides the basic ability of scaling and updating Pods like Deployment and StatefulSet of Kubernetes,\nCollaSet also provides a range of scale and update strategies,\nlike in-place update with container image and pod revision consistency."),(0,o.kt)("h3",{id:"streamlined-pod-operation"},"Streamlined Pod Operation"),(0,o.kt)("p",null,"KusionStack Operating introduces resource consist framework that offers a graceful way\nto integrate resource management around Pods, including traffic control, into the PodOpsLifecycle.\nThis simplifies the works for platform developers dealing with Pod operation details.\nKusionStack also integrates some resources by default, such as Aliyun SLB."),(0,o.kt)("h3",{id:"risk-management"},"Risk management"),(0,o.kt)("p",null,"Building upon the PodOpsLifecycle, KusionStack Operating introduces the workload named PodTransitionRule\nwhich will keep risks of pod operation under control.\nBy providing a MaxUnavailable rule similar to Kubernetes' PodDisruptionBudget (PDB),\nit ensures there are always enough Pods available for service.\nFurthermore, it allows for custom rules through extension via webhooks and label hooks."),(0,o.kt)("h2",{id:"future-works"},"Future works"),(0,o.kt)("p",null,"KusionStack Operating project is currently in its early stages.\nOur goal is to simplify platform development. We will continue building in areas such as application operations,\nobservability, and insight. We hope the Operating will make it easier for you to build platforms."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7b92056b.1d96726c.js b/assets/js/7b92056b.1d96726c.js new file mode 100644 index 00000000000..90957b8af41 --- /dev/null +++ b/assets/js/7b92056b.1d96726c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1320],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,g=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(g,o(o({ref:t},p),{},{components:n})):r.createElement(g,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const s={},o="Using Cloud Secrets Manager",i={unversionedId:"kusion/user-guides/secrets-management/using-cloud-secrets",id:"kusion/user-guides/secrets-management/using-cloud-secrets",title:"Using Cloud Secrets Manager",description:"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc",source:"@site/docs/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",sourceDirName:"kusion/5-user-guides/5-secrets-management",slug:"/kusion/user-guides/secrets-management/using-cloud-secrets",permalink:"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions"},next:{title:"Kusion Commands",permalink:"/docs/next/kusion/reference/commands/"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Setting up workspace",id:"setting-up-workspace",level:2},{value:"Update AppConfiguration",id:"update-appconfiguration",level:2},{value:"Apply and Verify",id:"apply-and-verify",level:2}],p={toc:l};function u(e){let{components:t,...s}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"using-cloud-secrets-manager"},"Using Cloud Secrets Manager"),(0,a.kt)("p",null,"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc"),(0,a.kt)("p",null,"Kusion provides out-of-the-box support to reference existing external secrets management solution, this tutorial introduces that how to pull the secret from AWS Secrets Manager to make it available to applications."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,a.kt)("p",null,"Additionally, you also need to configure the obtained AccessKey and SecretKey as environment variables: "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"aws iam account",src:n(24838).Z,width:"2874",height:"1398"})),(0,a.kt)("h2",{id:"setting-up-workspace"},"Setting up workspace"),(0,a.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,a.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,a.kt)("p",null,"In the case of setting up cloud secrets manager, platform teams need to specify which secrets management solution to use and necessary information to access on the workspace level."),(0,a.kt)("p",null,"A sample ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with AWS Secrets Manager settings:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"modules:\n ...\nsecretStore:\n provider:\n aws:\n region: us-east-1\n profile: The optional profile to be used to interact with AWS Secrets Manager.\n...\n")),(0,a.kt)("h2",{id:"update-appconfiguration"},"Update AppConfiguration"),(0,a.kt)("p",null,"At this point we are set up for good! Now you can declare external type of secrets via the ",(0,a.kt)("inlineCode",{parentName:"p"},"secrets")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model to consume sensitive data stored in AWS Secrets Manager."),(0,a.kt)("p",null,"See the example below for a full, deployable AppConfiguration."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\ngitsync: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "syncer": c.Container {\n image: "dyrnq/git-sync"\n # Run the following command as defined\n command: [\n "--repo=https://github.com/KusionStack/kusion"\n "--ref=HEAD"\n "--root=/mnt/git"\n ]\n # Consume secrets in environment variables\n env: {\n "GIT_SYNC_USERNAME": "secret://git-auth/username"\n "GIT_SYNC_PASSWORD": "secret://git-auth/password"\n }\n }\n }\n # Secrets used to retrieve secret data from AWS Secrets Manager\n secrets: {\n "git-auth": sec.Secret {\n type: "external"\n data: {\n "username": "ref://git-auth-info/username"\n "password": "ref://git-auth-info/password"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"apply-and-verify"},"Apply and Verify"),(0,a.kt)("p",null,"Run ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply")," command to deploy above application, then use the below command to verify if the secret got deployed:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get secret -n secretdemo\n")),(0,a.kt)("p",null,"You will find ",(0,a.kt)("inlineCode",{parentName:"p"},"git-auth")," of type Opaque automatically created and contains sensitive information pulled from AWS Secrets Manager."))}u.isMDXComponent=!0},24838:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"}}]); \ No newline at end of file diff --git a/assets/js/7b92056b.b2c99df4.js b/assets/js/7b92056b.b2c99df4.js deleted file mode 100644 index bcaed07aed5..00000000000 --- a/assets/js/7b92056b.b2c99df4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1320],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=l(n),m=a,g=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(g,o(o({ref:t},p),{},{components:n})):r.createElement(g,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const s={},o="Using Cloud Secrets Manager",i={unversionedId:"kusion/user-guides/secrets-management/using-cloud-secrets",id:"kusion/user-guides/secrets-management/using-cloud-secrets",title:"Using Cloud Secrets Manager",description:"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc",source:"@site/docs/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",sourceDirName:"kusion/5-user-guides/5-secrets-management",slug:"/kusion/user-guides/secrets-management/using-cloud-secrets",permalink:"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions"},next:{title:"Kusion Commands",permalink:"/docs/next/kusion/reference/commands/"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Setting up workspace",id:"setting-up-workspace",level:2},{value:"Update AppConfiguration",id:"update-appconfiguration",level:2},{value:"Apply and Verify",id:"apply-and-verify",level:2}],p={toc:l};function u(e){let{components:t,...s}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"using-cloud-secrets-manager"},"Using Cloud Secrets Manager"),(0,a.kt)("p",null,"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc"),(0,a.kt)("p",null,"Kusion provides out-of-the-box support to reference existing external secrets management solution, this tutorial introduces that how to pull the secret from AWS Secrets Manager to make it available to applications."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,a.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,a.kt)("p",null,"Additionally, you also need to configure the obtained AccessKey and SecretKey as environment variables: "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export AWS_ACCESS_KEY_ID="AKIAQZDxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="oE/xxxx" # replace it with your SecretKey\n')),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"aws iam account",src:n(24838).Z,width:"2874",height:"1398"})),(0,a.kt)("h2",{id:"setting-up-workspace"},"Setting up workspace"),(0,a.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,a.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,a.kt)("p",null,"In the case of setting up cloud secrets manager, platform teams need to specify which secrets management solution to use and necessary information to access on the workspace level."),(0,a.kt)("p",null,"A sample ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with AWS Secrets Manager settings:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"modules:\n ...\nsecretStore:\n provider:\n aws:\n region: us-east-1\n profile: The optional profile to be used to interact with AWS Secrets Manager.\n...\n")),(0,a.kt)("h2",{id:"update-appconfiguration"},"Update AppConfiguration"),(0,a.kt)("p",null,"At this point we are set up for good! Now you can declare external type of secrets via the ",(0,a.kt)("inlineCode",{parentName:"p"},"secrets")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model to consume sensitive data stored in AWS Secrets Manager."),(0,a.kt)("p",null,"See the example below for a full, deployable AppConfiguration."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import models.schema.v1 as ac\nimport models.schema.v1.workload as wl\nimport models.schema.v1.workload.container as c\nimport models.schema.v1.workload.secret as sec\n\ngitsync: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "syncer": c.Container {\n image: "dyrnq/git-sync"\n # Run the following command as defined\n command: [\n "--repo=https://github.com/KusionStack/kusion"\n "--ref=HEAD"\n "--root=/mnt/git"\n ]\n # Consume secrets in environment variables\n env: {\n "GIT_SYNC_USERNAME": "secret://git-auth/username"\n "GIT_SYNC_PASSWORD": "secret://git-auth/password"\n }\n }\n }\n # Secrets used to retrieve secret data from AWS Secrets Manager\n secrets: {\n "git-auth": sec.Secret {\n type: "external"\n data: {\n "username": "ref://git-auth-info/username"\n "password": "ref://git-auth-info/password"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"apply-and-verify"},"Apply and Verify"),(0,a.kt)("p",null,"Run ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply")," command to deploy above application, then use the below command to verify if the secret got deployed:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get secret -n secretdemo\n")),(0,a.kt)("p",null,"You will find ",(0,a.kt)("inlineCode",{parentName:"p"},"git-auth")," of type Opaque automatically created and contains sensitive information pulled from AWS Secrets Manager."))}u.isMDXComponent=!0},24838:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/aws-iam-account-2216105e7fa18fb2f7bf4be7e19f98bd.png"}}]); \ No newline at end of file diff --git a/assets/js/7d19cf58.48b5dd20.js b/assets/js/7d19cf58.9c4cd7e8.js similarity index 51% rename from assets/js/7d19cf58.48b5dd20.js rename to assets/js/7d19cf58.9c4cd7e8.js index 54d9816421c..e071fa8ecb6 100644 --- a/assets/js/7d19cf58.48b5dd20.js +++ b/assets/js/7d19cf58.9c4cd7e8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3883],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=r,f=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const o={id:"operational-rules"},i="Operational Rules",l={unversionedId:"kusion/configuration-walkthrough/operational-rules",id:"version-v0.10/kusion/configuration-walkthrough/operational-rules",title:"Operational Rules",description:"The opsRule attribute in the AppConfiguration instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/9-operational-rules.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/operational-rules",permalink:"/docs/kusion/configuration-walkthrough/operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/9-operational-rules.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{id:"operational-rules"},sidebar:"kusion",previous:{title:"Application Monitoring",permalink:"/docs/kusion/configuration-walkthrough/monitoring"},next:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/kusion/user-guides/cloud-resources/database"}},p={},s=[{value:"Import",id:"import",level:2},{value:"Max Unavailable Replicas",id:"max-unavailable-replicas",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"operational-rules"},"Operational Rules"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"opsRule")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.trait as t\n")),(0,r.kt)("h2",{id:"max-unavailable-replicas"},"Max Unavailable Replicas"),(0,r.kt)("p",null,"Currently, ",(0,r.kt)("inlineCode",{parentName:"p"},"OpsRule")," supports setting a ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," parameter, which specifies the maximum number of pods that can be rendered unavailable at any time. It can be either a fraction of the total pods for the current application or a fixed number. This operational rule is particularly helpful against unexpected changes or deletes to the workloads. It can also prevent too many workloads from going down during an application upgrade."),(0,r.kt)("p",null,"More rules will be available in future versions of Kusion."),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a percentage of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a fixed number of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n opsRule: t.OpsRule {\n maxUnavailable: 2\n }\n}\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3883],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=r,f=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const o={id:"operational-rules"},i="Operational Rules",l={unversionedId:"kusion/configuration-walkthrough/operational-rules",id:"version-v0.10/kusion/configuration-walkthrough/operational-rules",title:"Operational Rules",description:"The opsRule attribute in the AppConfiguration instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/9-operational-rules.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/operational-rules",permalink:"/docs/kusion/configuration-walkthrough/operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/9-operational-rules.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{id:"operational-rules"},sidebar:"kusion",previous:{title:"Application Monitoring",permalink:"/docs/kusion/configuration-walkthrough/monitoring"},next:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/kusion/user-guides/cloud-resources/database"}},p={},s=[{value:"Import",id:"import",level:2},{value:"Max Unavailable Replicas",id:"max-unavailable-replicas",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"operational-rules"},"Operational Rules"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"opsRule")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.trait as t\n")),(0,r.kt)("h2",{id:"max-unavailable-replicas"},"Max Unavailable Replicas"),(0,r.kt)("p",null,"Currently, ",(0,r.kt)("inlineCode",{parentName:"p"},"OpsRule")," supports setting a ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," parameter, which specifies the maximum number of pods that can be rendered unavailable at any time. It can be either a fraction of the total pods for the current application or a fixed number. This operational rule is particularly helpful against unexpected changes or deletes to the workloads. It can also prevent too many workloads from going down during an application upgrade."),(0,r.kt)("p",null,"More rules will be available in future versions of Kusion."),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a percentage of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a fixed number of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n opsRule: t.OpsRule {\n maxUnavailable: 2\n }\n}\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7dad11d2.124f1ab7.js b/assets/js/7dad11d2.124f1ab7.js new file mode 100644 index 00000000000..7533967c476 --- /dev/null +++ b/assets/js/7dad11d2.124f1ab7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6956],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(n),u=a,k=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={id:"configuration",sidebar_label:"Configuration"},r="Configuration",s={unversionedId:"kusion/concepts/configuration",id:"kusion/concepts/configuration",title:"Configuration",description:"Kusion can be configured with some global settings, which are separate from the AppConfiguration written by the application developers and the workspace configurations written by the platform engineers.",source:"@site/docs/kusion/3-concepts/8-configuration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/configuration",permalink:"/docs/next/kusion/concepts/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/8-configuration.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{id:"configuration",sidebar_label:"Configuration"},sidebar:"kusion",previous:{title:"Backend",permalink:"/docs/next/kusion/concepts/backend"},next:{title:"How Kusion Works?",permalink:"/docs/next/kusion/concepts/how-kusion-works"}},l={},p=[{value:"Configuration Management",id:"configuration-management",level:2},{value:"Get a Specified Configuration Item",id:"get-a-specified-configuration-item",level:3},{value:"List the Configuration Items",id:"list-the-configuration-items",level:3},{value:"Set a Specified Configuration Item",id:"set-a-specified-configuration-item",level:3},{value:"Unset a Specified Configuration Item",id:"unset-a-specified-configuration-item",level:3},{value:"Backend Configurations",id:"backend-configurations",level:2},{value:"Available Configuration Items",id:"available-configuration-items",level:3}],c={toc:p};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"Kusion can be configured with some global settings, which are separate from the AppConfiguration written by the application developers and the workspace configurations written by the platform engineers. "),(0,a.kt)("p",null,"The configurations are only relevant to the Kusion itself, and can be managed by command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config"),". The configuration items are specified, which are in the hierarchical format with full stop for segmentation, such as ",(0,a.kt)("inlineCode",{parentName:"p"},"backends.current"),". For now, only the backend configurations are included."),(0,a.kt)("p",null,"The configuration is stored in the file ",(0,a.kt)("inlineCode",{parentName:"p"},"${KUSION_HOME}/config.yaml"),". For sensitive data, such as password, access key id and secret, setting them in the configuration file is not recommended, using the corresponding environment variables is safer. "),(0,a.kt)("h2",{id:"configuration-management"},"Configuration Management"),(0,a.kt)("p",null,"Kusion provides the command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config"),", and its sub-commands ",(0,a.kt)("inlineCode",{parentName:"p"},"get"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"list"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"set"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"unset")," to manage the configuration. The usages are shown as below:"),(0,a.kt)("h3",{id:"get-a-specified-configuration-item"},"Get a Specified Configuration Item"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config get")," to get the value of a specified configuration item, only the registered item can be obtained correctly. The example is as below."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"# get a configuration item\nkusion config get backends.current\n")),(0,a.kt)("h3",{id:"list-the-configuration-items"},"List the Configuration Items"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config list")," to list all the Kusion configurations, where the result is in the YAML format. The example is as below."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"# list all the Kusion configurations\nkusion config list\n")),(0,a.kt)("h3",{id:"set-a-specified-configuration-item"},"Set a Specified Configuration Item"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config set")," to set the value of a specified configuration item, where the type of the value of is also determinate. Kusion supports ",(0,a.kt)("inlineCode",{parentName:"p"},"string"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"bool"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"array")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"map")," as the value type, which should be conveyed in the following format through CLI."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"string"),": the original format, such as ",(0,a.kt)("inlineCode",{parentName:"li"},"local-dev"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"oss-pre"),";"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"int"),": convert to string, such as ",(0,a.kt)("inlineCode",{parentName:"li"},"3306"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"80"),";"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"bool"),": convert to string, only support ",(0,a.kt)("inlineCode",{parentName:"li"},"true")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"false"),";"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"array"),": convert to string with JSON marshal, such as ",(0,a.kt)("inlineCode",{parentName:"li"},'\'["mysql","oss"]\''),". To preserve the format, enclosing the string content in single quotes is a good idea, or there may be unexpected errors;"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"map"),": convert to string with JSON marshal, such as ",(0,a.kt)("inlineCode",{parentName:"li"},'\'{"path":"\\etc"}\''),".")),(0,a.kt)("p",null,"Besides the type, some configuration items have more setting requirements. The configuration item dependency may exist, that is, a configuration item must be set after another item. And there may exist more restrictions for the configuration values themselves. For example, the valid keys for the map type value, the data range for the int type value. For detailed configuration item information, please refer to the following content of this article."),(0,a.kt)("p",null,"The example of setting configuration item is as blow."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},'# set a configuration item of type string\nkusion config set backends.pre.type mysql\n\n# set a configuration item of type int\nkusion config set backends.pre.configs.port 3306\n\n# set a configuration item of type map\nkusion config set backends.prod `{"configs":{"bucket":"kusion"},"type":"s3"}`\n')),(0,a.kt)("h3",{id:"unset-a-specified-configuration-item"},"Unset a Specified Configuration Item"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config unset")," to unset a specified configuration item. Be attention, some items have dependencies, which must be unset in a correct order. The example is as below."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"# unset a specified configuration item\nkusion config unset backends.pre\n")),(0,a.kt)("h2",{id:"backend-configurations"},"Backend Configurations"),(0,a.kt)("p",null,"The backend configurations define the place to store Workspace, Spec and State files. Multiple backends and current backend are supported to set."),(0,a.kt)("h3",{id:"available-configuration-items"},"Available Configuration Items"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.current"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the current used backend name. It can be set as the configured backend name. If not set, the default local backend will be used."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"map"),", a total backend configuration, contains type and config items, whose format is as below. It can be unset when the backend is not the current.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'{\n "type": "${backend_type}", # type string, required, support local, mysql, oss, s3.\n "configs": ${backend_configs} # type map, optional for type local, required for the others, the specific keys depend on the type, refer to the description of backends.{$name}.configs.\n}\n')),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.type"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the backend type, support ",(0,a.kt)("inlineCode",{parentName:"li"},"local"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"s3")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"oss"),". It can be unset when the backend is not the current, and the corresponding ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.configs")," are empty."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"map"),", the backend config items, whose format depends on the backend type and is as below. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type"),".")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'# type local\n{\n "path": "${local_path}" # type string, optional, the directory to store the files. If not set, use the default path ${KUSION_HOME}.\n}\n\n# type mysql\n {\n "dbName": "${mysql_db_name}", # type string, required, the database name.\n "user": "${mysql_user}", # type string, required, the database user.\n "password": "${mysql_password}", # type string, optional, the database password, which can be also obtained by environment variable KUSION_BACKEND_MYSQL_PASSWORD.\n "host": "${mysql_host}", # type string, required, the database host.\n "port": "${mysql_port}" # type string, optional, the database port. If not set, use the default port 3306.\n }\n\n# type oss\n {\n "endpoint": "${oss_endpoint}", # type string, required, the oss endpoint.\n "accessKeyID": "${oss_access_key_id}", # type string, optional, the oss access key id, which can be also obtained by environment variable OSS_ACCESS_KEY_ID.\n "accessKeySecret": "${oss_access_key_secret}", # type string, optional, the oss access key secret, which can be also obtained by environment variable OSS_ACCESS_KEY_SECRET\n "bucket": "${oss_bucket}", # type string, required, the oss bucket.\n "prefix": "${oss_prefix}" # type string, optional, the prefix to store the files.\n }\n\n # type s3\n {\n "region": "${s3_region}", # type string, optional, the aws region, which can be also obtained by environment variables AWS_REGION and AWS_DEFAULT_REGION.\n "endpoint": "${s3_endpoint}", # type string, optional, the aws endpoint. \n "accessKeyID": "${s3_access_key_id}", # type string, optional, the aws access key id, which can be also obtained by environment variable AWS_ACCESS_KEY_ID.\n "accessKeySecret": "${s3_access_key_secret}", # type string, optional, the aws access key secret, which can be also obtained by environment variable AWS_SECRET_ACCESS_KEY\n "bucket": "${s3_bucket}", # type string, required, the s3 bucket.\n "prefix": "${s3_prefix}" # type string, optional, the prefix to store the files.\n }\n')),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.path"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the path of local type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"local"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.dbName"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database name of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.user"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database user of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.password"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database password of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". It can be also obtained by environment variable ",(0,a.kt)("inlineCode",{parentName:"li"},"KUSION_BACKEND_MYSQL_PASSWORD"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.host"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database host of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.port"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"int"),", the database port of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". If not set, the default value ",(0,a.kt)("inlineCode",{parentName:"li"},"3306")," will be used."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.endpoint"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the endpoint of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.accessKeyID"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the access key id of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". For ",(0,a.kt)("inlineCode",{parentName:"li"},"oss"),", it can be also obtained by environment variable ",(0,a.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_ID"),"; while for s3, it is ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_ACCESS_KEY_ID"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.accessKeySecret"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the access key secret of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". For ",(0,a.kt)("inlineCode",{parentName:"li"},"oss"),", it can be also obtained by environment variable ",(0,a.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_SECRET"),"; while for s3, it is ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_SECRET_ACCESS_KEY"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.bucket"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the bucket of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.prefix"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the prefix to store the files of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.region"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the aws region of s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". It can be also obtained by environment variables ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_REGION")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_DEFAULT_REGION"),", where the former is priority.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7dad11d2.2974f534.js b/assets/js/7dad11d2.2974f534.js deleted file mode 100644 index 7e1e34dff96..00000000000 --- a/assets/js/7dad11d2.2974f534.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6956],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(n),u=a,k=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={id:"configuration",sidebar_label:"Configuration"},r="Configuration",s={unversionedId:"kusion/concepts/configuration",id:"kusion/concepts/configuration",title:"Configuration",description:"Kusion can be configured with some global settings, which are separate from the AppConfiguration written by the application developers and the workspace configurations written by the platform engineers.",source:"@site/docs/kusion/3-concepts/8-configuration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/configuration",permalink:"/docs/next/kusion/concepts/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/8-configuration.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{id:"configuration",sidebar_label:"Configuration"},sidebar:"kusion",previous:{title:"Backend Configuration",permalink:"/docs/next/kusion/concepts/backend-configuration"},next:{title:"How Kusion Works?",permalink:"/docs/next/kusion/concepts/how-kusion-works"}},l={},p=[{value:"Configuration Management",id:"configuration-management",level:2},{value:"Get a Specified Configuration Item",id:"get-a-specified-configuration-item",level:3},{value:"List the Configuration Items",id:"list-the-configuration-items",level:3},{value:"Set a Specified Configuration Item",id:"set-a-specified-configuration-item",level:3},{value:"Unset a Specified Configuration Item",id:"unset-a-specified-configuration-item",level:3},{value:"Backend Configurations",id:"backend-configurations",level:2},{value:"Available Configuration Items",id:"available-configuration-items",level:3}],c={toc:p};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"Kusion can be configured with some global settings, which are separate from the AppConfiguration written by the application developers and the workspace configurations written by the platform engineers. "),(0,a.kt)("p",null,"The configurations are only relevant to the Kusion itself, and can be managed by command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config"),". The configuration items are specified, which are in the hierarchical format with full stop for segmentation, such as ",(0,a.kt)("inlineCode",{parentName:"p"},"backends.current"),". For now, only the backend configurations are included."),(0,a.kt)("p",null,"The configuration is stored in the file ",(0,a.kt)("inlineCode",{parentName:"p"},"${KUSION_HOME}/config.yaml"),". For sensitive data, such as password, access key id and secret, setting them in the configuration file is not recommended, using the corresponding environment variables is safer. "),(0,a.kt)("h2",{id:"configuration-management"},"Configuration Management"),(0,a.kt)("p",null,"Kusion provides the command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config"),", and its sub-commands ",(0,a.kt)("inlineCode",{parentName:"p"},"get"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"list"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"set"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"unset")," to manage the configuration. The usages are shown as below:"),(0,a.kt)("h3",{id:"get-a-specified-configuration-item"},"Get a Specified Configuration Item"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config get")," to get the value of a specified configuration item, only the registered item can be obtained correctly. The example is as below."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"# get a configuration item\nkusion config get backends.current\n")),(0,a.kt)("h3",{id:"list-the-configuration-items"},"List the Configuration Items"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config list")," to list all the Kusion configurations, where the result is in the YAML format. The example is as below."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"# list all the Kusion configurations\nkusion config list\n")),(0,a.kt)("h3",{id:"set-a-specified-configuration-item"},"Set a Specified Configuration Item"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config set")," to set the value of a specified configuration item, where the type of the value of is also determinate. Kusion supports ",(0,a.kt)("inlineCode",{parentName:"p"},"string"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"bool"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"array")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"map")," as the value type, which should be conveyed in the following format through CLI."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"string"),": the original format, such as ",(0,a.kt)("inlineCode",{parentName:"li"},"local-dev"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"oss-pre"),";"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"int"),": convert to string, such as ",(0,a.kt)("inlineCode",{parentName:"li"},"3306"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"80"),";"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"bool"),": convert to string, only support ",(0,a.kt)("inlineCode",{parentName:"li"},"true")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"false"),";"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"array"),": convert to string with JSON marshal, such as ",(0,a.kt)("inlineCode",{parentName:"li"},'\'["mysql","oss"]\''),". To preserve the format, enclosing the string content in single quotes is a good idea, or there may be unexpected errors;"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"map"),": convert to string with JSON marshal, such as ",(0,a.kt)("inlineCode",{parentName:"li"},'\'{"path":"\\etc"}\''),".")),(0,a.kt)("p",null,"Besides the type, some configuration items have more setting requirements. The configuration item dependency may exist, that is, a configuration item must be set after another item. And there may exist more restrictions for the configuration values themselves. For example, the valid keys for the map type value, the data range for the int type value. For detailed configuration item information, please refer to the following content of this article."),(0,a.kt)("p",null,"The example of setting configuration item is as blow."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},'# set a configuration item of type string\nkusion config set backends.pre.type mysql\n\n# set a configuration item of type int\nkusion config set backends.pre.configs.port 3306\n\n# set a configuration item of type map\nkusion config set backends.prod `{"configs":{"bucket":"kusion"},"type":"s3"}`\n')),(0,a.kt)("h3",{id:"unset-a-specified-configuration-item"},"Unset a Specified Configuration Item"),(0,a.kt)("p",null,"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion config unset")," to unset a specified configuration item. Be attention, some items have dependencies, which must be unset in a correct order. The example is as below."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"# unset a specified configuration item\nkusion config unset backends.pre\n")),(0,a.kt)("h2",{id:"backend-configurations"},"Backend Configurations"),(0,a.kt)("p",null,"The backend configurations define the place to store Workspace, Spec and State files. Multiple backends and current backend are supported to set."),(0,a.kt)("h3",{id:"available-configuration-items"},"Available Configuration Items"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.current"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the current used backend name. It can be set as the configured backend name. If not set, the default local backend will be used."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"map"),", a total backend configuration, contains type and config items, whose format is as below. It can be unset when the backend is not the current.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'{\n "type": "${backend_type}", # type string, required, support local, mysql, oss, s3.\n "configs": ${backend_configs} # type map, optional for type local, required for the others, the specific keys depend on the type, refer to the description of backends.{$name}.configs.\n}\n')),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.type"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the backend type, support ",(0,a.kt)("inlineCode",{parentName:"li"},"local"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"s3")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"oss"),". It can be unset when the backend is not the current, and the corresponding ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.configs")," are empty."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"map"),", the backend config items, whose format depends on the backend type and is as below. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type"),".")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'# type local\n{\n "path": "${local_path}" # type string, optional, the directory to store the files. If not set, use the default path ${KUSION_HOME}.\n}\n\n# type mysql\n {\n "dbName": "${mysql_db_name}", # type string, required, the database name.\n "user": "${mysql_user}", # type string, required, the database user.\n "password": "${mysql_password}", # type string, optional, the database password, which can be also obtained by environment variable KUSION_BACKEND_MYSQL_PASSWORD.\n "host": "${mysql_host}", # type string, required, the database host.\n "port": "${mysql_port}" # type string, optional, the database port. If not set, use the default port 3306.\n }\n\n# type oss\n {\n "endpoint": "${oss_endpoint}", # type string, required, the oss endpoint.\n "accessKeyID": "${oss_access_key_id}", # type string, optional, the oss access key id, which can be also obtained by environment variable OSS_ACCESS_KEY_ID.\n "accessKeySecret": "${oss_access_key_secret}", # type string, optional, the oss access key secret, which can be also obtained by environment variable OSS_ACCESS_KEY_SECRET\n "bucket": "${oss_bucket}", # type string, required, the oss bucket.\n "prefix": "${oss_prefix}" # type string, optional, the prefix to store the files.\n }\n\n # type s3\n {\n "region": "${s3_region}", # type string, optional, the aws region, which can be also obtained by environment variables AWS_REGION and AWS_DEFAULT_REGION.\n "endpoint": "${s3_endpoint}", # type string, optional, the aws endpoint. \n "accessKeyID": "${s3_access_key_id}", # type string, optional, the aws access key id, which can be also obtained by environment variable AWS_ACCESS_KEY_ID.\n "accessKeySecret": "${s3_access_key_secret}", # type string, optional, the aws access key secret, which can be also obtained by environment variable AWS_SECRET_ACCESS_KEY\n "bucket": "${s3_bucket}", # type string, required, the s3 bucket.\n "prefix": "${s3_prefix}" # type string, optional, the prefix to store the files.\n }\n')),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.path"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the path of local type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"local"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.dbName"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database name of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.user"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database user of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.password"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database password of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". It can be also obtained by environment variable ",(0,a.kt)("inlineCode",{parentName:"li"},"KUSION_BACKEND_MYSQL_PASSWORD"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.host"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the database host of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.port"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"int"),", the database port of mysql type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"mysql"),". If not set, the default value ",(0,a.kt)("inlineCode",{parentName:"li"},"3306")," will be used."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.endpoint"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the endpoint of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.accessKeyID"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the access key id of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". For ",(0,a.kt)("inlineCode",{parentName:"li"},"oss"),", it can be also obtained by environment variable ",(0,a.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_ID"),"; while for s3, it is ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_ACCESS_KEY_ID"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.accessKeySecret"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the access key secret of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". For ",(0,a.kt)("inlineCode",{parentName:"li"},"oss"),", it can be also obtained by environment variable ",(0,a.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_SECRET"),"; while for s3, it is ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_SECRET_ACCESS_KEY"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.bucket"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the bucket of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.prefix"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the prefix to store the files of oss or s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"oss")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"backends.{$name}.configs.region"),": type ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", the aws region of s3 type backend. It must be set after ",(0,a.kt)("inlineCode",{parentName:"li"},"backends.{$name}.type")," and which must be ",(0,a.kt)("inlineCode",{parentName:"li"},"s3"),". It can be also obtained by environment variables ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_REGION")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"AWS_DEFAULT_REGION"),", where the former is priority.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7f5c0070.6531cfd8.js b/assets/js/7f5c0070.6531cfd8.js new file mode 100644 index 00000000000..720e0df3a33 --- /dev/null +++ b/assets/js/7f5c0070.6531cfd8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[357],{3905:(e,n,r)=>{r.d(n,{Zo:()=>p,kt:()=>f});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function a(e){for(var n=1;n=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=t.createContext({}),l=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):a(a({},n),e)),r},p=function(e){var n=l(e.components);return t.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),f=o,m=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return r?t.createElement(m,a(a({ref:n},p),{},{components:r})):t.createElement(m,a({ref:n},p))}));function f(e,n){var r=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var t=r(87462),o=(r(67294),r(3905));const i={id:"overview",sidebar_label:"Overview"},a="Overview",s={unversionedId:"kusion/reference/model/overview",id:"version-v0.9/kusion/reference/model/overview",title:"Overview",description:"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/1-overview.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/overview",permalink:"/docs/v0.9/kusion/reference/model/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/1-overview.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview",sidebar_label:"Overview"},sidebar:"kusion",previous:{title:"Kusion Model Library",permalink:"/docs/v0.9/kusion/reference/model/"},next:{title:"App Configuration",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration"}},c={},l=[],p={toc:l};function d(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,t.Z)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"overview"},"Overview"),(0,o.kt)("p",null,"KusionStack presets application configuration models described by KCL, where the model is called ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model"),". The GitHub repository ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," is used to store these models, which is known as ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model Library"),"."),(0,o.kt)("p",null,"The original intention of designing Kusion Model is to enhance the efficiency and improve the experience of YAML users. Through the unified application model defined by code, abstract and encapsulate complex configuration items, omit repetitive and derivable configurations, and supplement with necessary verification logic. Only the necessary attributes get exposed, users get an out-of-the-box, easy-to-understand configuration interface, which reduces the difficulty and improves the reliability of the configuration work."),(0,o.kt)("p",null,"Kusion Model Library currently provides the Kusion Model ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". The design of ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is developer-centric, based on Ant Group's decades of practice in building and managing hyperscale IDP (Internal Developer Platform), and the best practice of community. ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," describes the full lifecycle of an application."),(0,o.kt)("p",null,"A simple example of using ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to describe an application is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "wordpress": c.Container {\n image: "wordpress:latest"\n env: {\n "WORDPRESS_DB_HOST": "secret://wordpress-db/hostAddress"\n "WORDPRESS_DB_PASSWORD": "secret://wordpress-db/password"\n }\n resources: {\n "cpu": "1"\n "memory": "2Gi"\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n \n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n category: "serverless_basic"\n }\n}\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7f5c0070.bac41f7f.js b/assets/js/7f5c0070.bac41f7f.js deleted file mode 100644 index 0f2da81bee8..00000000000 --- a/assets/js/7f5c0070.bac41f7f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[357],{3905:(e,n,r)=>{r.d(n,{Zo:()=>p,kt:()=>f});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function a(e){for(var n=1;n=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=t.createContext({}),l=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):a(a({},n),e)),r},p=function(e){var n=l(e.components);return t.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),f=o,m=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return r?t.createElement(m,a(a({ref:n},p),{},{components:r})):t.createElement(m,a({ref:n},p))}));function f(e,n){var r=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var t=r(87462),o=(r(67294),r(3905));const i={id:"overview",sidebar_label:"Overview"},a="Overview",s={unversionedId:"kusion/reference/model/overview",id:"version-v0.9/kusion/reference/model/overview",title:"Overview",description:"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/1-overview.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/overview",permalink:"/docs/v0.9/kusion/reference/model/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/1-overview.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview",sidebar_label:"Overview"},sidebar:"kusion",previous:{title:"Kusion Model Library",permalink:"/docs/v0.9/kusion/reference/model/"},next:{title:"App Configuration",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration"}},c={},l=[],p={toc:l};function d(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,t.Z)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"overview"},"Overview"),(0,o.kt)("p",null,"KusionStack presets application configuration models described by KCL, where the model is called ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model"),". The GitHub repository ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," is used to store these models, which is known as ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model Library"),"."),(0,o.kt)("p",null,"The original intention of designing Kusion Model is to enhance the efficiency and improve the experience of YAML users. Through the unified application model defined by code, abstract and encapsulate complex configuration items, omit repetitive and derivable configurations, and supplement with necessary verification logic. Only the necessary attributes get exposed, users get an out-of-the-box, easy-to-understand configuration interface, which reduces the difficulty and improves the reliability of the configuration work."),(0,o.kt)("p",null,"Kusion Model Library currently provides the Kusion Model ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". The design of ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is developer-centric, based on Ant Group's decades of practice in building and managing hyperscale IDP (Internal Developer Platform), and the best practice of community. ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," describes the full lifecycle of an application."),(0,o.kt)("p",null,"A simple example of using ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to describe an application is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "wordpress": c.Container {\n image: "wordpress:latest"\n env: {\n "WORDPRESS_DB_HOST": "secret://wordpress-db/hostAddress"\n "WORDPRESS_DB_PASSWORD": "secret://wordpress-db/password"\n }\n resources: {\n "cpu": "1"\n "memory": "2Gi"\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n \n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n category: "serverless_basic"\n }\n}\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/82029501.26d61c93.js b/assets/js/82029501.18008d5b.js similarity index 56% rename from assets/js/82029501.26d61c93.js rename to assets/js/82029501.18008d5b.js index 21dfdadc23d..ccbb5944c40 100644 --- a/assets/js/82029501.26d61c93.js +++ b/assets/js/82029501.18008d5b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5408],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=o,k=d["".concat(l,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(k,a(a({ref:t},p),{},{components:n})):r.createElement(k,a({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,a=new Array(s);a[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,a[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const s={},a="kusion workspace list",i={unversionedId:"kusion/reference/commands/kusion-workspace-list",id:"version-v0.10/kusion/reference/commands/kusion-workspace-list",title:"kusion workspace list",description:"List all workspace names",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-list.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-list",permalink:"/docs/kusion/reference/commands/kusion-workspace-list",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-list.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace delete",permalink:"/docs/kusion/reference/commands/kusion-workspace-delete"},next:{title:"kusion workspace show",permalink:"/docs/kusion/reference/commands/kusion-workspace-show"}},l={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-list"},"kusion workspace list"),(0,o.kt)("p",null,"List all workspace names"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command list the names of all workspaces."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace list\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # List all workspace names\n kusion workspace list\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for list\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5408],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=o,k=d["".concat(l,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(k,a(a({ref:t},p),{},{components:n})):r.createElement(k,a({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,a=new Array(s);a[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,a[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const s={},a="kusion workspace list",i={unversionedId:"kusion/reference/commands/kusion-workspace-list",id:"version-v0.10/kusion/reference/commands/kusion-workspace-list",title:"kusion workspace list",description:"List all workspace names",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-list.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-list",permalink:"/docs/kusion/reference/commands/kusion-workspace-list",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-list.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace delete",permalink:"/docs/kusion/reference/commands/kusion-workspace-delete"},next:{title:"kusion workspace show",permalink:"/docs/kusion/reference/commands/kusion-workspace-show"}},l={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-list"},"kusion workspace list"),(0,o.kt)("p",null,"List all workspace names"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command list the names of all workspaces."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace list\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # List all workspace names\n kusion workspace list\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for list\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/821c5d9e.0845ce23.js b/assets/js/821c5d9e.0845ce23.js new file mode 100644 index 00000000000..f5a0a412dfd --- /dev/null +++ b/assets/js/821c5d9e.0845ce23.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[401],{3905:(e,a,t)=>{t.d(a,{Zo:()=>d,kt:()=>m});var n=t(67294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function o(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);a&&(n=n.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var a=1;a=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=n.createContext({}),p=function(e){var a=n.useContext(l),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},d=function(e){var a=p(e.components);return n.createElement(l.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},u=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=p(t),m=r,h=u["".concat(l,".").concat(m)]||u[m]||c[m]||o;return t?n.createElement(h,i(i({ref:a},d),{},{components:t})):n.createElement(h,i({ref:a},d))}));function m(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=u;var s={};for(var l in a)hasOwnProperty.call(a,l)&&(s[l]=a[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var p=2;p{t.r(a),t.d(a,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=t(87462),r=(t(67294),t(3905));const o={sidebar_position:6},i="Managed Databases",s={unversionedId:"kusion/config-walkthrough/database",id:"version-v0.9/kusion/config-walkthrough/database",title:"Managed Databases",description:"The database attribute in the AppConfiguration instance is used to describe the specification for any databases needed for the application.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/database.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/database",permalink:"/docs/v0.9/kusion/config-walkthrough/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/database.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"kusion",previous:{title:"Application Networking",permalink:"/docs/v0.9/kusion/config-walkthrough/networking"},next:{title:"Secret Management",permalink:"/docs/v0.9/kusion/config-walkthrough/secret"}},l={},p=[{value:"Import",id:"import",level:2},{value:"Types of Database offerings",id:"types-of-database-offerings",level:2},{value:"Cloud Credentials and Permissions",id:"cloud-credentials-and-permissions",level:2},{value:"Configure Database",id:"configure-database",level:2},{value:"Provision a Cloud Database",id:"provision-a-cloud-database",level:3},{value:"AWS RDS Instance",id:"aws-rds-instance",level:4},{value:"AliCloud RDS Instance",id:"alicloud-rds-instance",level:4},{value:"Local Database",id:"local-database",level:3},{value:"Database Credentials",id:"database-credentials",level:2},{value:"Configure Network Access",id:"configure-network-access",level:2},{value:"Subnet ID",id:"subnet-id",level:3},{value:"Private Routing",id:"private-routing",level:3}],d={toc:p};function c(e){let{components:a,...t}=e;return(0,r.kt)("wrapper",(0,n.Z)({},d,t,{components:a,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"managed-databases"},"Managed Databases"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"database")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for any databases needed for the application."),(0,r.kt)("p",null,"You can currently have only one ",(0,r.kt)("inlineCode",{parentName:"p"},"database")," per ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),"."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.accessories.database as db\n")),(0,r.kt)("h2",{id:"types-of-database-offerings"},"Types of Database offerings"),(0,r.kt)("p",null,"As of version 0.9.0, Kusion supports the following database offerings on the cloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://aws.amazon.com/rds/"},"AWS")),(0,r.kt)("li",{parentName:"ul"},"Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/databases"},"AliCloud"))),(0,r.kt)("p",null,"More database types on more cloud vendors will be added in the future."),(0,r.kt)("p",null,"Alternatively, Kusion also supports creating a database at ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost")," for local testing needs. A local database is quicker to stand up and easier to manage. It also eliminates the need for an account and any relevant costs with the cloud providers in the case that a local testing environment is sufficient."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"You do need a local Kubernetes cluster to run the database workloads. You can refer to ",(0,r.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/start/"},"Minikube")," or ",(0,r.kt)("a",{parentName:"p",href:"https://kind.sigs.k8s.io/docs/user/quick-start/"},"Kind")," to get started.\nTo see an end-to-end use case for standing up a local testing environment including a local database, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"Kusion Quickstart"),".")),(0,r.kt)("h2",{id:"cloud-credentials-and-permissions"},"Cloud Credentials and Permissions"),(0,r.kt)("p",null,"Kusion provisions databases on the cloud via ",(0,r.kt)("a",{parentName:"p",href:"https://www.terraform.io/"},"terraform")," providers. For it to create ",(0,r.kt)("em",{parentName:"p"},"any")," cloud resources, it requires a set of credentials that belongs to an account that has the appropriate write access, as well as a provider region so the terraform provider can be initialized properly."),(0,r.kt)("p",null,"For AWS, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export AWS_ACCESS_KEY_ID="xxxxxxxxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="xxxxxxx" # replace it with your SecretKey\nexport AWS_PROVIDER_REGION="xx-xxxx-x" # replace it with your AWS Region\n')),(0,r.kt)("p",null,"For AliCloud, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export ALICLOUD_ACCESS_KEY="xxxxxxxxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="xxxxxxxxx" # replace it with your SecretKey\nexport ALICLOUD_PROVIDER_REGION="xx-xxxxxxx" # replace it with your AliCloud Region\n')),(0,r.kt)("p",null,"The user account that owns these credentials would need to have the proper permission policies attached to create databases and security groups. If you are using the cloud-managed policies, the policies needed to provision a database and configure firewall rules are listed below."),(0,r.kt)("p",null,"For AWS:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"For AliCloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"Alternatively, you can use customer managed policies if the cloud provider built-in policies don't meet your needs. The list of permissions needed are in the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonRDSFullAccess.html#AmazonRDSFullAccess-json"},"AmazonRDSFullAccess Policy Document")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonVPCFullAccess.html"},"AmazonVPCFullAccess Policy Document"),". It will most likely be a subset of the permissions in the policy documents."),(0,r.kt)("h2",{id:"configure-database"},"Configure Database"),(0,r.kt)("h3",{id:"provision-a-cloud-database"},"Provision a Cloud Database"),(0,r.kt)("p",null,"Assuming the steps in the ",(0,r.kt)("a",{parentName:"p",href:"#cloud-credentials-and-permissions"},"Cloud Credentials and Permissions")," section is setup properly, you can now provision cloud databases via Kusion."),(0,r.kt)("h4",{id:"aws-rds-instance"},"AWS RDS Instance"),(0,r.kt)("p",null,"To provision an AWS RDS instance with MySQL v5.7:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "aws"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "db.t3.micro"\n securityIPs = ["0.0.0.0/0"]\n }\n}\n')),(0,r.kt)("p",null,"It's highly recommended to replace ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," and closely manage the whitelist of IPs that can access the database for security purposes. The ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," in the example above or if ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," is omitted altogether will allow connections from anywhere which would typically be a security bad practice."),(0,r.kt)("p",null,"The supported ",(0,r.kt)("inlineCode",{parentName:"p"},"engine")," values are ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"MariaDB"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"Postgres")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"SQLServer-SE"),". "),(0,r.kt)("p",null,"The supported engine versions can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MySQL.Concepts.VersionMgmt.html"},"MySQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MariaDB.Concepts.VersionMgmt.html#MariaDB.Concepts.VersionMgmt.Supported"},"MariaDB versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.DBVersions"},"PostgreSQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SQLServer.html#SQLServer.Concepts.General.VersionSupport"},"Microsoft SQL Server versions"))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," field determines the computation and memory capacity of the RDS instance. The ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.micro")," instance type in the example above represents the ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance class with a size of ",(0,r.kt)("inlineCode",{parentName:"p"},"micro"),". In the same ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance family there are also ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.small"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.medium"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.2xlarge"),", etc."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Support"},"here"),"."),(0,r.kt)("p",null,"You can also adjust the storage capacity for the database instance by changing the ",(0,r.kt)("inlineCode",{parentName:"p"},"size")," field which is storage size measured in gigabytes. The minimum is 20. More details can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#Concepts.Storage.GeneralSSD"},"here"),"."),(0,r.kt)("h4",{id:"alicloud-rds-instance"},"AliCloud RDS Instance"),(0,r.kt)("p",null,"To provision an AWS RDS instance with MySQL v5.7. AliCloud RDS has several additional fields such as ",(0,r.kt)("inlineCode",{parentName:"p"},"category"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "8.0"\n size: 20\n instanceType: "mysql.n2.serverless.1cc"\n category = "serverless_basic"\n subnetID = "{your-alicloud-vswitch-id}"\n securityIPs = ["0.0.0.0/0"]\n privateRouting = False\n }\n}\n')),(0,r.kt)("p",null,"We will walkthrough ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," in the ",(0,r.kt)("a",{parentName:"p",href:"#configure-network-access"},"Configure Network Access")," section."),(0,r.kt)("p",null,"The supported ",(0,r.kt)("inlineCode",{parentName:"p"},"engine")," values are ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"MariaDB"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"PostgreSQL")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"SQLServer"),". "),(0,r.kt)("p",null,"The supported engine versions can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/major-version-lifecycle-description"},"MySQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/developer-reference/api-rds-2014-08-15-createdbinstance"},"MariaDB versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/lifecycles-of-major-engine-versions"},"PostgreSQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-sql-server/release-notes-for-minor-engine-versions-of-apsaradb-rds-for-sql-server"},"Microsoft SQL Server versions"))),(0,r.kt)("p",null,"A summarized version can be found ",(0,r.kt)("a",{parentName:"p",href:"https://www.alibabacloud.com/help/en/rds/developer-reference/api-rds-2014-08-15-createdbinstance"},"here")," in the ",(0,r.kt)("inlineCode",{parentName:"p"},"EngineVersion")," parameter."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/primary-apsaradb-rds-for-mysql-instance-types#concept-2096487"},"MySQL instance types(x86)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mariadb/instance-types#concept-2096591"},"MariaDB instance types")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/primary-apsaradb-rds-for-postgresql-instance-types#concept-2096578"},"PostgreSQL instance types")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-sql-server/primary-apsaradb-rds-for-sql-server-instance-types#concept-2096545"},"Microsoft SQL Server instance types"))),(0,r.kt)("h3",{id:"local-database"},"Local Database"),(0,r.kt)("p",null,"To deploy a local database with MySQL v8.0:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "local"\n engine: "MySQL"\n version: "8.0"\n instanceType: "local"\n }\n}\n')),(0,r.kt)("p",null,"The supported ",(0,r.kt)("inlineCode",{parentName:"p"},"engine")," values are ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"MariaDB")," as of version 0.9.0. Kusion will stand up a ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," deployment and expose it as a service in the local Kubernetes cluster for local workloads to connect to."),(0,r.kt)("h2",{id:"database-credentials"},"Database Credentials"),(0,r.kt)("p",null,"There is no need to manage the database credentials manually. Kusion will automatically generate a random password, set it as the credential when creating the database, and then inject the hostname, username and password into the application runtime."),(0,r.kt)("p",null,"You have the option to BYO (Bring Your Own) username for the database credential by specifying the ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"database"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n # ...\n username: "my_username"\n }\n}\n')),(0,r.kt)("p",null,"You cannot bring your own password. The password will always be managed by Kusion automatically."),(0,r.kt)("p",null,"The database credentials are injected into the environment variables of the application container. You can access them via the following env vars:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# env | grep KUSION_DB\nKUSION_DB_HOST=wordpress.xxxxxxxx.us-east-1.rds.amazonaws.com\nKUSION_DB_USERNAME=xxxxxxxxx\nKUSION_DB_PASSWORD=xxxxxxxxx\n")),(0,r.kt)("p",null,"You can use these environment variables out of the box. Or most likely, your application might retrieve the connection details from a different set of environment variables. In that case, you can map the kusion environment variables to the ones expected by your application using the ",(0,r.kt)("inlineCode",{parentName:"p"},"$()")," expression."),(0,r.kt)("p",null,"This example below will assign the value of ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_HOST"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER"),", likewise for ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_PASSWORD")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_PASSWORD"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3-apache"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n }\n # ...\n }\n }\n # ...\n }\n database: db.Database {\n # ...\n }\n}\n')),(0,r.kt)("h2",{id:"configure-network-access"},"Configure Network Access"),(0,r.kt)("p",null,"You can also optionally configure the network access to the database as part of the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". This is highly recommended because it dramatically increases the security posture of your cloud environment in the means of least privilege principle."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"Database")," schema declares the list of network addresses that are allowed to access the database. The network addresses are in the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/what-is/cidr/"},"CIDR notation")," and can be either a private IP range (",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc1918"},"RFC-1918")," and ",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6598"},"RFC-6598")," address) or a public one."),(0,r.kt)("p",null,"If the database need to be accessed from a public location (which should most likely not be the case in a production environment), ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," need to include the public IP address of the traffic source (For instance, if the RDS database needs to be accessed from your computer)."),(0,r.kt)("p",null,"To configure AWS RDS to restrict network access from a VPC with a CIDR of ",(0,r.kt)("inlineCode",{parentName:"p"},"10.0.1.0/24")," and a public IP of ",(0,r.kt)("inlineCode",{parentName:"p"},"103.192.227.125"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "aws"\n ...\n securityIPs = ["10.0.1.0/24", "103.192.227.125/32"]\n }\n}\n')),(0,r.kt)("p",null,"Depending on the cloud provider, the default behavior of the database firewall settings may differ if omitted."),(0,r.kt)("h3",{id:"subnet-id"},"Subnet ID"),(0,r.kt)("p",null,"On AWS, you have the option to launch the RDS instance inside a specific VPC if a ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is present in the application configuration. By default, if ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is not provided, the RDS will be created in the default VPC for that account. However, the recommendation is to self-manage your VPCs to provider better isolation from a network security perspective."),(0,r.kt)("p",null,"On AliCloud, the ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is required. The concept of subnet maps to VSwitch in AliCloud."),(0,r.kt)("p",null,"To place the RDS instance into a specific VPC on AWS:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "aws"\n ...\n subnetID: "subnet-xxxxxxxxxxxxxxxx" # replace it with your vpc subnet ID\n }\n}\n')),(0,r.kt)("h3",{id:"private-routing"},"Private Routing"),(0,r.kt)("p",null,"There is an option to enforce private routing on certain cloud providers if both the workload and the database are running on the cloud."),(0,r.kt)("p",null,"On AliCloud, you can set the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". The database host generated will be a private FQDN that is only resolvable and accessible from within the AliCloud VPCs. Setting ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when ",(0,r.kt)("inlineCode",{parentName:"p"},"type")," is ",(0,r.kt)("inlineCode",{parentName:"p"},"aws")," is a no-op."),(0,r.kt)("p",null,"To enforce private routing on AliCloud:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "alicloud"\n ...\n privateRouting: true\n }\n}\n')),(0,r.kt)("p",null,"Kusion will then generate a private FQDN and inject it into the application runtime as the environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST")," for the application to use. A complete list of Kusion-managed environment variable can be found ",(0,r.kt)("a",{parentName:"p",href:"../reference/model/naming-conventions#list-of-magic-variables"},"here"),"."),(0,r.kt)("p",null,"Otherwise when using the public FQDN to connect to a database from the workload, the route will depend on cloud provider's routing preference. The options are generally either:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Travel as far as possible on the cloud provider's global backbone network, or also referred to as cold potato routing, or"),(0,r.kt)("li",{parentName:"ul"},"Egress as early as possible to the public Internet and re-enter the cloud provider's datacenter later, or also referred to as hot potato routing")),(0,r.kt)("p",null,"The prior generally has better performance but is also more expensive."),(0,r.kt)("p",null,"You can find a good read on the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/blogs/architecture/internet-routing-and-traffic-engineering/"},"AWS Blog")," or the ",(0,r.kt)("a",{parentName:"p",href:"https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/routing-preference-overview"},"Microsoft Learn"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/821c5d9e.cfaf598f.js b/assets/js/821c5d9e.cfaf598f.js deleted file mode 100644 index 0152acfd6a5..00000000000 --- a/assets/js/821c5d9e.cfaf598f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[401],{3905:(e,a,t)=>{t.d(a,{Zo:()=>d,kt:()=>m});var n=t(67294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function o(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);a&&(n=n.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var a=1;a=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=n.createContext({}),p=function(e){var a=n.useContext(l),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},d=function(e){var a=p(e.components);return n.createElement(l.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},u=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=p(t),m=r,h=u["".concat(l,".").concat(m)]||u[m]||c[m]||o;return t?n.createElement(h,i(i({ref:a},d),{},{components:t})):n.createElement(h,i({ref:a},d))}));function m(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=u;var s={};for(var l in a)hasOwnProperty.call(a,l)&&(s[l]=a[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var p=2;p{t.r(a),t.d(a,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=t(87462),r=(t(67294),t(3905));const o={sidebar_position:6},i="Managed Databases",s={unversionedId:"kusion/config-walkthrough/database",id:"version-v0.9/kusion/config-walkthrough/database",title:"Managed Databases",description:"The database attribute in the AppConfiguration instance is used to describe the specification for any databases needed for the application.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/database.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/database",permalink:"/docs/v0.9/kusion/config-walkthrough/database",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/database.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"kusion",previous:{title:"Application Networking",permalink:"/docs/v0.9/kusion/config-walkthrough/networking"},next:{title:"Secret Management",permalink:"/docs/v0.9/kusion/config-walkthrough/secret"}},l={},p=[{value:"Import",id:"import",level:2},{value:"Types of Database offerings",id:"types-of-database-offerings",level:2},{value:"Cloud Credentials and Permissions",id:"cloud-credentials-and-permissions",level:2},{value:"Configure Database",id:"configure-database",level:2},{value:"Provision a Cloud Database",id:"provision-a-cloud-database",level:3},{value:"AWS RDS Instance",id:"aws-rds-instance",level:4},{value:"AliCloud RDS Instance",id:"alicloud-rds-instance",level:4},{value:"Local Database",id:"local-database",level:3},{value:"Database Credentials",id:"database-credentials",level:2},{value:"Configure Network Access",id:"configure-network-access",level:2},{value:"Subnet ID",id:"subnet-id",level:3},{value:"Private Routing",id:"private-routing",level:3}],d={toc:p};function c(e){let{components:a,...t}=e;return(0,r.kt)("wrapper",(0,n.Z)({},d,t,{components:a,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"managed-databases"},"Managed Databases"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"database")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for any databases needed for the application."),(0,r.kt)("p",null,"You can currently have only one ",(0,r.kt)("inlineCode",{parentName:"p"},"database")," per ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),"."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.accessories.database as db\n")),(0,r.kt)("h2",{id:"types-of-database-offerings"},"Types of Database offerings"),(0,r.kt)("p",null,"As of version 0.9.0, Kusion supports the following database offerings on the cloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://aws.amazon.com/rds/"},"AWS")),(0,r.kt)("li",{parentName:"ul"},"Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/databases"},"AliCloud"))),(0,r.kt)("p",null,"More database types on more cloud vendors will be added in the future."),(0,r.kt)("p",null,"Alternatively, Kusion also supports creating a database at ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost")," for local testing needs. A local database is quicker to stand up and easier to manage. It also eliminates the need for an account and any relevant costs with the cloud providers in the case that a local testing environment is sufficient."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"You do need a local Kubernetes cluster to run the database workloads. You can refer to ",(0,r.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/start/"},"Minikube")," or ",(0,r.kt)("a",{parentName:"p",href:"https://kind.sigs.k8s.io/docs/user/quick-start/"},"Kind")," to get started.\nTo see an end-to-end use case for standing up a local testing environment including a local database, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"Kusion Quickstart"),".")),(0,r.kt)("h2",{id:"cloud-credentials-and-permissions"},"Cloud Credentials and Permissions"),(0,r.kt)("p",null,"Kusion provisions databases on the cloud via ",(0,r.kt)("a",{parentName:"p",href:"https://www.terraform.io/"},"terraform")," providers. For it to create ",(0,r.kt)("em",{parentName:"p"},"any")," cloud resources, it requires a set of credentials that belongs to an account that has the appropriate write access, as well as a provider region so the terraform provider can be initialized properly."),(0,r.kt)("p",null,"For AWS, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export AWS_ACCESS_KEY_ID="xxxxxxxxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="xxxxxxx" # replace it with your SecretKey\nexport AWS_PROVIDER_REGION="xx-xxxx-x" # replace it with your AWS Region\n')),(0,r.kt)("p",null,"For AliCloud, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export ALICLOUD_ACCESS_KEY="xxxxxxxxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="xxxxxxxxx" # replace it with your SecretKey\nexport ALICLOUD_PROVIDER_REGION="xx-xxxxxxx" # replace it with your AliCloud Region\n')),(0,r.kt)("p",null,"The user account that owns these credentials would need to have the proper permission policies attached to create databases and security groups. If you are using the cloud-managed policies, the policies needed to provision a database and configure firewall rules are listed below."),(0,r.kt)("p",null,"For AWS:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"For AliCloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"Alternatively, you can use customer managed policies if the cloud provider built-in policies don't meet your needs. The list of permissions needed are in the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonRDSFullAccess.html#AmazonRDSFullAccess-json"},"AmazonRDSFullAccess Policy Document")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonVPCFullAccess.html"},"AmazonVPCFullAccess Policy Document"),". It will most likely be a subset of the permissions in the policy documents."),(0,r.kt)("h2",{id:"configure-database"},"Configure Database"),(0,r.kt)("h3",{id:"provision-a-cloud-database"},"Provision a Cloud Database"),(0,r.kt)("p",null,"Assuming the steps in the ",(0,r.kt)("a",{parentName:"p",href:"#cloud-credentials-and-permissions"},"Cloud Credentials and Permissions")," section is setup properly, you can now provision cloud databases via Kusion."),(0,r.kt)("h4",{id:"aws-rds-instance"},"AWS RDS Instance"),(0,r.kt)("p",null,"To provision an AWS RDS instance with MySQL v5.7:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "aws"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "db.t3.micro"\n securityIPs = ["0.0.0.0/0"]\n }\n}\n')),(0,r.kt)("p",null,"It's highly recommended to replace ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," and closely manage the whitelist of IPs that can access the database for security purposes. The ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," in the example above or if ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," is omitted altogether will allow connections from anywhere which would typically be a security bad practice."),(0,r.kt)("p",null,"The supported ",(0,r.kt)("inlineCode",{parentName:"p"},"engine")," values are ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"MariaDB"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"Postgres")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"SQLServer-SE"),". "),(0,r.kt)("p",null,"The supported engine versions can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MySQL.Concepts.VersionMgmt.html"},"MySQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MariaDB.Concepts.VersionMgmt.html#MariaDB.Concepts.VersionMgmt.Supported"},"MariaDB versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.DBVersions"},"PostgreSQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SQLServer.html#SQLServer.Concepts.General.VersionSupport"},"Microsoft SQL Server versions"))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," field determines the computation and memory capacity of the RDS instance. The ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.micro")," instance type in the example above represents the ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance class with a size of ",(0,r.kt)("inlineCode",{parentName:"p"},"micro"),". In the same ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance family there are also ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.small"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.medium"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.2xlarge"),", etc."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Support"},"here"),"."),(0,r.kt)("p",null,"You can also adjust the storage capacity for the database instance by changing the ",(0,r.kt)("inlineCode",{parentName:"p"},"size")," field which is storage size measured in gigabytes. The minimum is 20. More details can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#Concepts.Storage.GeneralSSD"},"here"),"."),(0,r.kt)("h4",{id:"alicloud-rds-instance"},"AliCloud RDS Instance"),(0,r.kt)("p",null,"To provision an AWS RDS instance with MySQL v5.7. AliCloud RDS has several additional fields such as ",(0,r.kt)("inlineCode",{parentName:"p"},"category"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "8.0"\n size: 20\n instanceType: "mysql.n2.serverless.1cc"\n category = "serverless_basic"\n subnetID = "{your-alicloud-vswitch-id}"\n securityIPs = ["0.0.0.0/0"]\n privateRouting = False\n }\n}\n')),(0,r.kt)("p",null,"We will walkthrough ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," in the ",(0,r.kt)("a",{parentName:"p",href:"#configure-network-access"},"Configure Network Access")," section."),(0,r.kt)("p",null,"The supported ",(0,r.kt)("inlineCode",{parentName:"p"},"engine")," values are ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"MariaDB"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"PostgreSQL")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"SQLServer"),". "),(0,r.kt)("p",null,"The supported engine versions can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/major-version-lifecycle-description"},"MySQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/developer-reference/api-rds-2014-08-15-createdbinstance"},"MariaDB versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/lifecycles-of-major-engine-versions"},"PostgreSQL versions")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-sql-server/release-notes-for-minor-engine-versions-of-apsaradb-rds-for-sql-server"},"Microsoft SQL Server versions"))),(0,r.kt)("p",null,"A summarized version can be found ",(0,r.kt)("a",{parentName:"p",href:"https://www.alibabacloud.com/help/en/rds/developer-reference/api-rds-2014-08-15-createdbinstance"},"here")," in the ",(0,r.kt)("inlineCode",{parentName:"p"},"EngineVersion")," parameter."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/primary-apsaradb-rds-for-mysql-instance-types#concept-2096487"},"MySQL instance types(x86)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mariadb/instance-types#concept-2096591"},"MariaDB instance types")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/primary-apsaradb-rds-for-postgresql-instance-types#concept-2096578"},"PostgreSQL instance types")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-sql-server/primary-apsaradb-rds-for-sql-server-instance-types#concept-2096545"},"Microsoft SQL Server instance types"))),(0,r.kt)("h3",{id:"local-database"},"Local Database"),(0,r.kt)("p",null,"To deploy a local database with MySQL v8.0:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "local"\n engine: "MySQL"\n version: "8.0"\n instanceType: "local"\n }\n}\n')),(0,r.kt)("p",null,"The supported ",(0,r.kt)("inlineCode",{parentName:"p"},"engine")," values are ",(0,r.kt)("inlineCode",{parentName:"p"},"MySQL")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"MariaDB")," as of version 0.9.0. Kusion will stand up a ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," deployment and expose it as a service in the local Kubernetes cluster for local workloads to connect to."),(0,r.kt)("h2",{id:"database-credentials"},"Database Credentials"),(0,r.kt)("p",null,"There is no need to manage the database credentials manually. Kusion will automatically generate a random password, set it as the credential when creating the database, and then inject the hostname, username and password into the application runtime."),(0,r.kt)("p",null,"You have the option to BYO (Bring Your Own) username for the database credential by specifying the ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"database"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n # ...\n username: "my_username"\n }\n}\n')),(0,r.kt)("p",null,"You cannot bring your own password. The password will always be managed by Kusion automatically."),(0,r.kt)("p",null,"The database credentials are injected into the environment variables of the application container. You can access them via the following env vars:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# env | grep KUSION_DB\nKUSION_DB_HOST=wordpress.xxxxxxxx.us-east-1.rds.amazonaws.com\nKUSION_DB_USERNAME=xxxxxxxxx\nKUSION_DB_PASSWORD=xxxxxxxxx\n")),(0,r.kt)("p",null,"You can use these environment variables out of the box. Or most likely, your application might retrieve the connection details from a different set of environment variables. In that case, you can map the kusion environment variables to the ones expected by your application using the ",(0,r.kt)("inlineCode",{parentName:"p"},"$()")," expression."),(0,r.kt)("p",null,"This example below will assign the value of ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_HOST"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER"),", likewise for ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_PASSWORD")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_PASSWORD"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3-apache"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD)"\n }\n # ...\n }\n }\n # ...\n }\n database: db.Database {\n # ...\n }\n}\n')),(0,r.kt)("h2",{id:"configure-network-access"},"Configure Network Access"),(0,r.kt)("p",null,"You can also optionally configure the network access to the database as part of the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". This is highly recommended because it dramatically increases the security posture of your cloud environment in the means of least privilege principle."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"Database")," schema declares the list of network addresses that are allowed to access the database. The network addresses are in the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/what-is/cidr/"},"CIDR notation")," and can be either a private IP range (",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc1918"},"RFC-1918")," and ",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6598"},"RFC-6598")," address) or a public one."),(0,r.kt)("p",null,"If the database need to be accessed from a public location (which should most likely not be the case in a production environment), ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," need to include the public IP address of the traffic source (For instance, if the RDS database needs to be accessed from your computer)."),(0,r.kt)("p",null,"To configure AWS RDS to restrict network access from a VPC with a CIDR of ",(0,r.kt)("inlineCode",{parentName:"p"},"10.0.1.0/24")," and a public IP of ",(0,r.kt)("inlineCode",{parentName:"p"},"103.192.227.125"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "aws"\n ...\n securityIPs = ["10.0.1.0/24", "103.192.227.125/32"]\n }\n}\n')),(0,r.kt)("p",null,"Depending on the cloud provider, the default behavior of the database firewall settings may differ if omitted."),(0,r.kt)("h3",{id:"subnet-id"},"Subnet ID"),(0,r.kt)("p",null,"On AWS, you have the option to launch the RDS instance inside a specific VPC if a ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is present in the application configuration. By default, if ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is not provided, the RDS will be created in the default VPC for that account. However, the recommendation is to self-manage your VPCs to provider better isolation from a network security perspective."),(0,r.kt)("p",null,"On AliCloud, the ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is required. The concept of subnet maps to VSwitch in AliCloud."),(0,r.kt)("p",null,"To place the RDS instance into a specific VPC on AWS:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "aws"\n ...\n subnetID: "subnet-xxxxxxxxxxxxxxxx" # replace it with your vpc subnet ID\n }\n}\n')),(0,r.kt)("h3",{id:"private-routing"},"Private Routing"),(0,r.kt)("p",null,"There is an option to enforce private routing on certain cloud providers if both the workload and the database are running on the cloud."),(0,r.kt)("p",null,"On AliCloud, you can set the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". The database host generated will be a private FQDN that is only resolvable and accessible from within the AliCloud VPCs. Setting ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when ",(0,r.kt)("inlineCode",{parentName:"p"},"type")," is ",(0,r.kt)("inlineCode",{parentName:"p"},"aws")," is a no-op."),(0,r.kt)("p",null,"To enforce private routing on AliCloud:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n # ...\n database: db.Database {\n type: "alicloud"\n ...\n privateRouting: true\n }\n}\n')),(0,r.kt)("p",null,"Kusion will then generate a private FQDN and inject it into the application runtime as the environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST")," for the application to use. A complete list of Kusion-managed environment variable can be found ",(0,r.kt)("a",{parentName:"p",href:"../reference/model/naming-conventions#list-of-magic-variables"},"here"),"."),(0,r.kt)("p",null,"Otherwise when using the public FQDN to connect to a database from the workload, the route will depend on cloud provider's routing preference. The options are generally either:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Travel as far as possible on the cloud provider's global backbone network, or also referred to as cold potato routing, or"),(0,r.kt)("li",{parentName:"ul"},"Egress as early as possible to the public Internet and re-enter the cloud provider's datacenter later, or also referred to as hot potato routing")),(0,r.kt)("p",null,"The prior generally has better performance but is also more expensive."),(0,r.kt)("p",null,"You can find a good read on the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/blogs/architecture/internet-routing-and-traffic-engineering/"},"AWS Blog")," or the ",(0,r.kt)("a",{parentName:"p",href:"https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/routing-preference-overview"},"Microsoft Learn"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/82345ec9.bb06a026.js b/assets/js/82345ec9.bb06a026.js deleted file mode 100644 index ba6c4f39970..00000000000 --- a/assets/js/82345ec9.bb06a026.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6076],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(t),m=a,k=u["".concat(p,".").concat(m)]||u[m]||d[m]||i;return t?o.createElement(k,r(r({ref:n},c),{},{components:t})):o.createElement(k,r({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,r=new Array(i);r[0]=u;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),a=(t(67294),t(3905));const i={sidebar_position:4},r="Workload",l={unversionedId:"kusion/config-walkthrough/workload",id:"version-v0.9/kusion/config-walkthrough/workload",title:"Workload",description:"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application. It is the only required field when instantiating an AppConfiguration.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/workload.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/workload",permalink:"/docs/v0.9/kusion/config-walkthrough/workload",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/workload.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"kusion",previous:{title:"Base and Override",permalink:"/docs/v0.9/kusion/config-walkthrough/base_override"},next:{title:"Application Networking",permalink:"/docs/v0.9/kusion/config-walkthrough/networking"}},p={},s=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Import",id:"import",level:2},{value:"Types of Workloads",id:"types-of-workloads",level:2},{value:"Configure containers",id:"configure-containers",level:2},{value:"Application image",id:"application-image",level:3},{value:"Resource Requirements",id:"resource-requirements",level:3},{value:"Health Probes",id:"health-probes",level:3},{value:"Lifecycle Hooks",id:"lifecycle-hooks",level:3},{value:"Create Files",id:"create-files",level:3},{value:"Customize container initialization",id:"customize-container-initialization",level:3},{value:"Configure Replicas",id:"configure-replicas",level:2},{value:"Differences between Services and Jobs",id:"differences-between-services-and-jobs",level:2},{value:"Exposure",id:"exposure",level:3},{value:"Workload Implementations",id:"workload-implementations",level:3},{value:"Job Schedule",id:"job-schedule",level:3},{value:"Workload References",id:"workload-references",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"workload"},"Workload"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application. It is the only required field when instantiating an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),"."),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," maps to an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance 1:1. If there are more than one workload, they should be considered different applications."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#import"},"Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#types-of-workloads"},"Types of workloads")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-containers"},"Configure containers"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#application-image"},"Application image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#resource-requirements"},"Resource Requirements")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#health-probes"},"Health Probes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#lifecycle-hooks"},"Lifecycle Hooks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#create-files"},"Create Files")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#customize-container-initialization"},"Customize container initialization")))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-replicas"},"Configure Replicas")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#differences-between-services-and-jobs"},"Differences between Services and Jobs")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#workload-references"},"Workload References"))),(0,a.kt)("h2",{id:"import"},"Import"),(0,a.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n")),(0,a.kt)("h2",{id:"types-of-workloads"},"Types of Workloads"),(0,a.kt)("p",null,"There are currently two types of workloads defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Service"),', representing a long-running, scalable workload type that should "never" go down and respond to short-lived latency-sensitive requests. This workload type is commonly used for web applications and services that expose APIs.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Job"),", representing batch tasks that take from a few seconds to days to complete and then stop. These are commonly used for batch processing that is less sensitive to short-term performance fluctuations.")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {}\n}\n")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Job {}\n}\n")),(0,a.kt)("p",null,"Of course, the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instances above is not sufficient to describe an application. We still need to provide more details in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," section."),(0,a.kt)("h2",{id:"configure-containers"},"Configure containers"),(0,a.kt)("p",null,"Kusion is built on top of cloud-native philosophies. One of which is that applications should run as loosely coupled microservices on abstract and self-contained software units, such as containers."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute in a workload instance is used to define the behavior for the containers that run application workload. The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is a map, from the name of the container to the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog.models.schema.v1.workload.container.Container")," Object which includes the container configurations."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The name of the container is in the context of the configuration file, so you could refer to it later. It's not referring to the name of the container in the Kubernetes cluster (or any other runtime).")),(0,a.kt)("p",null,"Everything defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is considered an application container, as opposed to a sidecar container. Sidecar containers will be introduced in a different attribute in a future version."),(0,a.kt)("p",null,"In most of the cases, only one application container is needed. Ideally, we recommend mapping an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance to a microservice in the microservice terminology."),(0,a.kt)("p",null,"We will walkthrough the details of configuring a container using an example of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type."),(0,a.kt)("p",null,"To add an application container:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n }\n }\n}\n')),(0,a.kt)("h3",{id:"application-image"},"Application image"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application image to run. This is the only required field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"To specify an application image:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n }\n }\n}\n')),(0,a.kt)("h3",{id:"resource-requirements"},"Resource Requirements"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"resources")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application resource requirements such as cpu and memory."),(0,a.kt)("p",null,"You can specify an upper limit (which maps to resource limits only) or a range as the resource requirements (which maps to resource requests and limits in Kubernetes)."),(0,a.kt)("p",null,"To specify an upper bound (only resource limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"To specify a range (both resource requests and limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # Sets requests to cpu=250m and memory=256Mi\n # Sets limits to cpu=500m and memory=512Mi\n resources: {\n "cpu": "250m-500m"\n "memory": "256Mi-512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"health-probes"},"Health Probes"),(0,a.kt)("p",null,"There are three types of ",(0,a.kt)("inlineCode",{parentName:"p"},"Probe")," defined in a ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"livenessProbe")," - used to determine if the container is healthy and running"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"readinessProbe")," - used to determine if the container is ready to accept traffic"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," - used to determine if the container has started properly. Liveness and readiness probes don't start until ",(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," succeeds. Commonly used for containers that takes a while to start")),(0,a.kt)("p",null,"The probes are optional. You can only have one Probe of each kind for a given ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),"."),(0,a.kt)("p",null,"To configure a ",(0,a.kt)("inlineCode",{parentName:"p"},"Http")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"readinessProbe")," that probes the health via HTTP request and a ",(0,a.kt)("inlineCode",{parentName:"p"},"Exec")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"livenessProbe")," which executes a command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure an Http type readiness probe at /healthz\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "/healthz"\n }\n initialDelaySeconds: 10\n timeoutSeconds: 5\n periodSeconds: 15\n successThreshold: 3\n failureThreshold: 1\n }\n # Configure an Exec type liveness probe that executes probe.sh\n livenessProbe: p.Probe {\n probeHandler: p.Exec {\n command: ["probe.sh"]\n }\n initialDelaySeconds: 10\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"lifecycle-hooks"},"Lifecycle Hooks"),(0,a.kt)("p",null,"You can also configure lifecycle hooks that triggers in response to container lifecycle events such as liveness/startup probe failure, preemption, resource contention, etc."),(0,a.kt)("p",null,"There are two types that is currently supported:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PreStop")," - triggers before the container is terminated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PostStart")," - triggers after the container is initialized.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure lifecycle hooks\n lifecycle: lc.Lifecycle {\n # Configures an Exec type pre-stop hook that executes preStop.sh\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n # Configures an Http type pre-stop hook at /post-start\n postStart: p.Http {\n url: "/post-start"\n }\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"create-files"},"Create Files"),(0,a.kt)("p",null,"You can also create files on-demand during the container initialization."),(0,a.kt)("p",null,"To create a custom file and mount it to ",(0,a.kt)("inlineCode",{parentName:"p"},"/home/admin/my-file")," when the container starts:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n # Creates a file during container startup\n files: {\n "/home/admin/my-file": c.FileSpec {\n content: "some file contents"\n mode: "0777"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"customize-container-initialization"},"Customize container initialization"),(0,a.kt)("p",null,"You can also customize the container entrypoint via ",(0,a.kt)("inlineCode",{parentName:"p"},"command"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"args"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"workingDir"),". These should ",(0,a.kt)("strong",{parentName:"p"},"most likely not be required"),". In most of the cases, the entrypoint details should be baked into the application image itself."),(0,a.kt)("p",null,"To customize the container entrypoint:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # This command will overwrite the entrypoint set in the image Dockerfile\n command: ["/usr/local/bin/my-init-script.sh"]\n # Extra arguments append to command defined above\n args: [\n "--log-dir=/home/my-app/logs"\n "--timeout=60s"\n ]\n # Run the command as defined above, in the directory "/tmp"\n workingDir: "/tmp"\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"configure-replicas"},"Configure Replicas"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"replicas")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance describes the number of identical copies to run at the same time. It is generally recommended to have multiple replicas in production environments to eliminate any single point of failure. In Kubernetes, this corresponds to the ",(0,a.kt)("inlineCode",{parentName:"p"},"spec.replicas")," field in the relevant workload manifests."),(0,a.kt)("p",null,"To configure a workload to have a replica count of 3:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n replicas: 3\n # ...\n }\n # ...\n}\n")),(0,a.kt)("p",null,"Autoscaling will be supported in a future version of Kusion, at which point you will be able to specify a range of replicas."),(0,a.kt)("h2",{id:"differences-between-services-and-jobs"},"Differences between Services and Jobs"),(0,a.kt)("p",null,"The two types of workloads, namely ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),", share a majority of the attributes with some minor differences."),(0,a.kt)("h3",{id:"exposure"},"Exposure"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," usually represents a long-running, scalable workload that responds to short-lived latency-sensitive requests and never go down. Hence a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," has an additional attribute that determines how it is exposed and can be accessed. A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," does NOT the option to be exposed. We will explore more in the ",(0,a.kt)("a",{parentName:"p",href:"networking"},"application networking walkthrough"),"."),(0,a.kt)("h3",{id:"workload-implementations"},"Workload Implementations"),(0,a.kt)("p",null,"Kusion also supports multiple kinds of Kubernetes workload implementations for a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type workload. The current supported kinds are ",(0,a.kt)("inlineCode",{parentName:"p"},"Deployment"),"(default) and ",(0,a.kt)("inlineCode",{parentName:"p"},"CollaSet"),", which is a workload type defined in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"KusionStack-operating toolkit")," under the KusionStack family. You can learn more about ",(0,a.kt)("inlineCode",{parentName:"p"},"CollaSet")," ",(0,a.kt)("a",{parentName:"p",href:"https://kusionstack.io/"},"here"),"."),(0,a.kt)("p",null,"To specify a ",(0,a.kt)("inlineCode",{parentName:"p"},"CollaSet")," kind ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n type: "CollaSet"\n # ...\n }\n}\n')),(0,a.kt)("p",null,"If ",(0,a.kt)("inlineCode",{parentName:"p"},"type")," is not provided, Kusion defaults to use the Kubernetes ",(0,a.kt)("inlineCode",{parentName:"p"},"Deployment"),"."),(0,a.kt)("h3",{id:"job-schedule"},"Job Schedule"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," can be configured to run in a recurring manner. In this case, the job will have a cron-format schedule that represents its recurring schedule."),(0,a.kt)("p",null,"To configure a job to run at 21:00 every night:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: wl.Job {\n containers: {\n # ...\n }\n schedule: "0 21 * * *"\n }\n')),(0,a.kt)("h2",{id:"workload-references"},"Workload References"),(0,a.kt)("p",null,"You can find workload references ",(0,a.kt)("a",{parentName:"p",href:"../reference/model/catalog_models/workload/doc_service"},"here"),"."),(0,a.kt)("p",null,"You can find workload schema source ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/schema/v1/workload"},"here"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/82345ec9.fa9665d4.js b/assets/js/82345ec9.fa9665d4.js new file mode 100644 index 00000000000..e04a11ba3fd --- /dev/null +++ b/assets/js/82345ec9.fa9665d4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6076],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(t),m=a,k=u["".concat(p,".").concat(m)]||u[m]||d[m]||i;return t?o.createElement(k,r(r({ref:n},c),{},{components:t})):o.createElement(k,r({ref:n},c))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,r=new Array(i);r[0]=u;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),a=(t(67294),t(3905));const i={sidebar_position:4},r="Workload",l={unversionedId:"kusion/config-walkthrough/workload",id:"version-v0.9/kusion/config-walkthrough/workload",title:"Workload",description:"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application. It is the only required field when instantiating an AppConfiguration.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/workload.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/workload",permalink:"/docs/v0.9/kusion/config-walkthrough/workload",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/workload.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"kusion",previous:{title:"Base and Override",permalink:"/docs/v0.9/kusion/config-walkthrough/base_override"},next:{title:"Application Networking",permalink:"/docs/v0.9/kusion/config-walkthrough/networking"}},p={},s=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Import",id:"import",level:2},{value:"Types of Workloads",id:"types-of-workloads",level:2},{value:"Configure containers",id:"configure-containers",level:2},{value:"Application image",id:"application-image",level:3},{value:"Resource Requirements",id:"resource-requirements",level:3},{value:"Health Probes",id:"health-probes",level:3},{value:"Lifecycle Hooks",id:"lifecycle-hooks",level:3},{value:"Create Files",id:"create-files",level:3},{value:"Customize container initialization",id:"customize-container-initialization",level:3},{value:"Configure Replicas",id:"configure-replicas",level:2},{value:"Differences between Services and Jobs",id:"differences-between-services-and-jobs",level:2},{value:"Exposure",id:"exposure",level:3},{value:"Workload Implementations",id:"workload-implementations",level:3},{value:"Job Schedule",id:"job-schedule",level:3},{value:"Workload References",id:"workload-references",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"workload"},"Workload"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application. It is the only required field when instantiating an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),"."),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," maps to an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance 1:1. If there are more than one workload, they should be considered different applications."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#import"},"Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#types-of-workloads"},"Types of workloads")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-containers"},"Configure containers"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#application-image"},"Application image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#resource-requirements"},"Resource Requirements")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#health-probes"},"Health Probes")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#lifecycle-hooks"},"Lifecycle Hooks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#create-files"},"Create Files")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#customize-container-initialization"},"Customize container initialization")))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configure-replicas"},"Configure Replicas")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#differences-between-services-and-jobs"},"Differences between Services and Jobs")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#workload-references"},"Workload References"))),(0,a.kt)("h2",{id:"import"},"Import"),(0,a.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n")),(0,a.kt)("h2",{id:"types-of-workloads"},"Types of Workloads"),(0,a.kt)("p",null,"There are currently two types of workloads defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Service"),', representing a long-running, scalable workload type that should "never" go down and respond to short-lived latency-sensitive requests. This workload type is commonly used for web applications and services that expose APIs.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Job"),", representing batch tasks that take from a few seconds to days to complete and then stop. These are commonly used for batch processing that is less sensitive to short-term performance fluctuations.")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {}\n}\n")),(0,a.kt)("p",null,"To instantiate a ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Job {}\n}\n")),(0,a.kt)("p",null,"Of course, the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instances above is not sufficient to describe an application. We still need to provide more details in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," section."),(0,a.kt)("h2",{id:"configure-containers"},"Configure containers"),(0,a.kt)("p",null,"Kusion is built on top of cloud-native philosophies. One of which is that applications should run as loosely coupled microservices on abstract and self-contained software units, such as containers."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute in a workload instance is used to define the behavior for the containers that run application workload. The ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is a map, from the name of the container to the ",(0,a.kt)("inlineCode",{parentName:"p"},"catalog.models.schema.v1.workload.container.Container")," Object which includes the container configurations."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The name of the container is in the context of the configuration file, so you could refer to it later. It's not referring to the name of the container in the Kubernetes cluster (or any other runtime).")),(0,a.kt)("p",null,"Everything defined in the ",(0,a.kt)("inlineCode",{parentName:"p"},"containers")," attribute is considered an application container, as opposed to a sidecar container. Sidecar containers will be introduced in a different attribute in a future version."),(0,a.kt)("p",null,"In most of the cases, only one application container is needed. Ideally, we recommend mapping an ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance to a microservice in the microservice terminology."),(0,a.kt)("p",null,"We will walkthrough the details of configuring a container using an example of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type."),(0,a.kt)("p",null,"To add an application container:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n }\n }\n}\n')),(0,a.kt)("h3",{id:"application-image"},"Application image"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application image to run. This is the only required field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"To specify an application image:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n }\n }\n}\n')),(0,a.kt)("h3",{id:"resource-requirements"},"Resource Requirements"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"resources")," attribute in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema specifies the application resource requirements such as cpu and memory."),(0,a.kt)("p",null,"You can specify an upper limit (which maps to resource limits only) or a range as the resource requirements (which maps to resource requests and limits in Kubernetes)."),(0,a.kt)("p",null,"To specify an upper bound (only resource limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("p",null,"To specify a range (both resource requests and limits):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # Sets requests to cpu=250m and memory=256Mi\n # Sets limits to cpu=500m and memory=512Mi\n resources: {\n "cpu": "250m-500m"\n "memory": "256Mi-512Mi"\n }\n # ...\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"health-probes"},"Health Probes"),(0,a.kt)("p",null,"There are three types of ",(0,a.kt)("inlineCode",{parentName:"p"},"Probe")," defined in a ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"livenessProbe")," - used to determine if the container is healthy and running"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"readinessProbe")," - used to determine if the container is ready to accept traffic"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," - used to determine if the container has started properly. Liveness and readiness probes don't start until ",(0,a.kt)("inlineCode",{parentName:"li"},"startupProbe")," succeeds. Commonly used for containers that takes a while to start")),(0,a.kt)("p",null,"The probes are optional. You can only have one Probe of each kind for a given ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),"."),(0,a.kt)("p",null,"To configure a ",(0,a.kt)("inlineCode",{parentName:"p"},"Http")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"readinessProbe")," that probes the health via HTTP request and a ",(0,a.kt)("inlineCode",{parentName:"p"},"Exec")," type ",(0,a.kt)("inlineCode",{parentName:"p"},"livenessProbe")," which executes a command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure an Http type readiness probe at /healthz\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "/healthz"\n }\n initialDelaySeconds: 10\n timeoutSeconds: 5\n periodSeconds: 15\n successThreshold: 3\n failureThreshold: 1\n }\n # Configure an Exec type liveness probe that executes probe.sh\n livenessProbe: p.Probe {\n probeHandler: p.Exec {\n command: ["probe.sh"]\n }\n initialDelaySeconds: 10\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"lifecycle-hooks"},"Lifecycle Hooks"),(0,a.kt)("p",null,"You can also configure lifecycle hooks that triggers in response to container lifecycle events such as liveness/startup probe failure, preemption, resource contention, etc."),(0,a.kt)("p",null,"There are two types that is currently supported:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PreStop")," - triggers before the container is terminated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PostStart")," - triggers after the container is initialized.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # Configure lifecycle hooks\n lifecycle: lc.Lifecycle {\n # Configures an Exec type pre-stop hook that executes preStop.sh\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n # Configures an Http type pre-stop hook at /post-start\n postStart: p.Http {\n url: "/post-start"\n }\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"create-files"},"Create Files"),(0,a.kt)("p",null,"You can also create files on-demand during the container initialization."),(0,a.kt)("p",null,"To create a custom file and mount it to ",(0,a.kt)("inlineCode",{parentName:"p"},"/home/admin/my-file")," when the container starts:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n }\n # ...\n # Creates a file during container startup\n files: {\n "/home/admin/my-file": c.FileSpec {\n content: "some file contents"\n mode: "0777"\n }\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"customize-container-initialization"},"Customize container initialization"),(0,a.kt)("p",null,"You can also customize the container entrypoint via ",(0,a.kt)("inlineCode",{parentName:"p"},"command"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"args"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"workingDir"),". These should ",(0,a.kt)("strong",{parentName:"p"},"most likely not be required"),". In most of the cases, the entrypoint details should be baked into the application image itself."),(0,a.kt)("p",null,"To customize the container entrypoint:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v5"\n # ...\n # This command will overwrite the entrypoint set in the image Dockerfile\n command: ["/usr/local/bin/my-init-script.sh"]\n # Extra arguments append to command defined above\n args: [\n "--log-dir=/home/my-app/logs"\n "--timeout=60s"\n ]\n # Run the command as defined above, in the directory "/tmp"\n workingDir: "/tmp"\n }\n }\n }\n}\n')),(0,a.kt)("h2",{id:"configure-replicas"},"Configure Replicas"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"replicas")," field in the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance describes the number of identical copies to run at the same time. It is generally recommended to have multiple replicas in production environments to eliminate any single point of failure. In Kubernetes, this corresponds to the ",(0,a.kt)("inlineCode",{parentName:"p"},"spec.replicas")," field in the relevant workload manifests."),(0,a.kt)("p",null,"To configure a workload to have a replica count of 3:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n replicas: 3\n # ...\n }\n # ...\n}\n")),(0,a.kt)("p",null,"Autoscaling will be supported in a future version of Kusion, at which point you will be able to specify a range of replicas."),(0,a.kt)("h2",{id:"differences-between-services-and-jobs"},"Differences between Services and Jobs"),(0,a.kt)("p",null,"The two types of workloads, namely ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Job"),", share a majority of the attributes with some minor differences."),(0,a.kt)("h3",{id:"exposure"},"Exposure"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," usually represents a long-running, scalable workload that responds to short-lived latency-sensitive requests and never go down. Hence a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," has an additional attribute that determines how it is exposed and can be accessed. A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," does NOT the option to be exposed. We will explore more in the ",(0,a.kt)("a",{parentName:"p",href:"networking"},"application networking walkthrough"),"."),(0,a.kt)("h3",{id:"workload-implementations"},"Workload Implementations"),(0,a.kt)("p",null,"Kusion also supports multiple kinds of Kubernetes workload implementations for a ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," type workload. The current supported kinds are ",(0,a.kt)("inlineCode",{parentName:"p"},"Deployment"),"(default) and ",(0,a.kt)("inlineCode",{parentName:"p"},"CollaSet"),", which is a workload type defined in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"KusionStack-operating toolkit")," under the KusionStack family. You can learn more about ",(0,a.kt)("inlineCode",{parentName:"p"},"CollaSet")," ",(0,a.kt)("a",{parentName:"p",href:"https://kusionstack.io/"},"here"),"."),(0,a.kt)("p",null,"To specify a ",(0,a.kt)("inlineCode",{parentName:"p"},"CollaSet")," kind ",(0,a.kt)("inlineCode",{parentName:"p"},"Service"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n type: "CollaSet"\n # ...\n }\n}\n')),(0,a.kt)("p",null,"If ",(0,a.kt)("inlineCode",{parentName:"p"},"type")," is not provided, Kusion defaults to use the Kubernetes ",(0,a.kt)("inlineCode",{parentName:"p"},"Deployment"),"."),(0,a.kt)("h3",{id:"job-schedule"},"Job Schedule"),(0,a.kt)("p",null,"A ",(0,a.kt)("inlineCode",{parentName:"p"},"Job")," can be configured to run in a recurring manner. In this case, the job will have a cron-format schedule that represents its recurring schedule."),(0,a.kt)("p",null,"To configure a job to run at 21:00 every night:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: wl.Job {\n containers: {\n # ...\n }\n schedule: "0 21 * * *"\n }\n')),(0,a.kt)("h2",{id:"workload-references"},"Workload References"),(0,a.kt)("p",null,"You can find workload references ",(0,a.kt)("a",{parentName:"p",href:"../reference/model/catalog_models/workload/doc_service"},"here"),"."),(0,a.kt)("p",null,"You can find workload schema source ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/schema/v1/workload"},"here"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/82e833af.89312298.js b/assets/js/82e833af.89312298.js deleted file mode 100644 index 05b1eca1a1e..00000000000 --- a/assets/js/82e833af.89312298.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9310],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>d});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=a.createContext({}),p=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=p(t),d=r,k=m["".concat(l,".").concat(d)]||m[d]||u[d]||o;return t?a.createElement(k,s(s({ref:n},c),{},{components:t})):a.createElement(k,s({ref:n},c))}));function d(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,s=new Array(o);s[0]=m;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={sidebar_position:4},s="Try a Sample",i={unversionedId:"ctrlmesh/started/try",id:"version-v0.9/ctrlmesh/started/try",title:"Try a Sample",description:"This guide lets you quickly evaluate KusionStack Controller Mesh.",source:"@site/versioned_docs/version-v0.9/ctrlmesh/started/try.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/try",permalink:"/docs/v0.9/ctrlmesh/started/try",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/started/try.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"ctrlmesh",previous:{title:"Installation",permalink:"/docs/v0.9/ctrlmesh/started/install"},next:{title:"FAQ",permalink:"/docs/v0.9/ctrlmesh/faq/"}},l={},p=[{value:"Install Controller Mesh Manager",id:"install-controller-mesh-manager",level:2},{value:"Enable Custom Operator Sharding",id:"enable-custom-operator-sharding",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"try-a-sample"},"Try a Sample"),(0,r.kt)("p",null,"This guide lets you quickly evaluate KusionStack Controller Mesh. "),(0,r.kt)("h2",{id:"install-controller-mesh-manager"},"Install Controller Mesh Manager"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Install with helm")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# Firstly add KusionStack charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Wait manager ready\n$ kubectl -n ctrlmesh get po\nNAME READY STATUS RESTARTS AGE\nctrlmesh-57d6b4df57-mdslc 1/1 Running 0 40s\nctrlmesh-57d6b4df57-mtv2s 1/1 Running 0 40s\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"/docs/v0.9/ctrlmesh/started/install"},"Install manager with more options")),(0,r.kt)("h2",{id:"enable-custom-operator-sharding"},"Enable Custom Operator Sharding"),(0,r.kt)("p",null,"You can use the ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("a",{parentName:"strong",href:"https://kusionstack.io/docs/operating/introduction/"},"Operating v0.1.1"))," available here."),(0,r.kt)("p",null,"Deploy the sample operator with ShardingConfig:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm repo update\n$ helm install sample-operating kusionstack/operating \\\n --version v0.2.0 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true\n\n$ kubectl -n kusionstack-system get sts\nNAME READY AGE\nkusionstack-operating 5/5 1m45s\n\n# The proxy container will be automatically injected into the pod\n$ kubectl -n kusionstack-system get po\nNAME READY STATUS RESTARTS AGE\nkusionstack-operating-0 2/2 Running 0 42s\nkusionstack-operating-1 2/2 Running 0 32s\nkusionstack-operating-2 2/2 Running 0 21s\nkusionstack-operating-3 2/2 Running 0 12s\nkusionstack-operating-4 0/2 ContainerCreating 0 1s\n\n# Now we have three shards with three lease.\n# operating-0-canary -> [kusionstack-operating-0]\n# operating-1-normal -> [kusionstack-operating-1, kusionstack-operating-2]\n# operating-2-normal -> [kusionstack-operating-3, kusionstack-operating-4]\n$ kubectl -n kusionstack-system get lease\nNAME HOLDER AGE\nkusionstack-controller-manager---operating-0-canary kusionstack-operating-0_81b5bbae-be63-45ed-a939-e67e0c3d6326 12m\nkusionstack-controller-manager---operating-1-normal kusionstack-operating-1_e4bbad49-e6ec-42fa-8ffd-caae82156a3e 12m\nkusionstack-controller-manager---operating-2-normal kusionstack-operating-3_94f7f81a-f9e6-47d6-b72b-e16da479e9be 12m\n")),(0,r.kt)("p",null," Show the sample ShardingConfig:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm template sample-operating kusionstack/operating \\\n --version v0.1.1 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true \\\n --show-only templates/shardingconfig.yaml\n")),(0,r.kt)("p",null,"Here is a sample ",(0,r.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"---\n# Source: operating/templates/shardingconfig.yaml\napiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-root\n namespace: kusionstack-system\nspec:\n # Auto sharding config\n root:\n prefix: operating\n targetStatefulSet: kusionstack-operating\n canary:\n replicas: 1\n inNamespaces:\n - kusionstack-system\n auto:\n everyShardReplicas: 2\n shardingSize: 2\n resourceSelector:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - configmaps\n - pods\n - endpoints\n - services\n - replicasets\n - apiGroups:\n - apps.kusionstack.io\n resources:\n - '*'\n controller:\n leaderElectionName: kusionstack-controller-manager\n")),(0,r.kt)("p",null,"You can configure the ShardingConfig according to your requirements."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"In order to enable the ShardingConfig, you also need to add the following label to the pod template.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/enable-proxy: 'true'"),(0,r.kt)("br",{parentName:"p"}),"\n","We plan to deprecate it in future versions.")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Supported OS/ARCH",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("strong",{parentName:"p"},"ControllerMesh")," v0.1.0: ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/amd64"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/arm64"),".",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("strong",{parentName:"p"},"Operating")," v0.1.1: ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/amd64"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/arm64"),". ")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/82e833af.c38d7cc4.js b/assets/js/82e833af.c38d7cc4.js new file mode 100644 index 00000000000..e4d3d29a830 --- /dev/null +++ b/assets/js/82e833af.c38d7cc4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9310],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>d});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=a.createContext({}),p=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=p(t),d=r,k=m["".concat(l,".").concat(d)]||m[d]||u[d]||o;return t?a.createElement(k,s(s({ref:n},c),{},{components:t})):a.createElement(k,s({ref:n},c))}));function d(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,s=new Array(o);s[0]=m;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={sidebar_position:4},s="Try a Sample",i={unversionedId:"ctrlmesh/started/try",id:"version-v0.9/ctrlmesh/started/try",title:"Try a Sample",description:"This guide lets you quickly evaluate KusionStack Controller Mesh.",source:"@site/versioned_docs/version-v0.9/ctrlmesh/started/try.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/try",permalink:"/docs/v0.9/ctrlmesh/started/try",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/started/try.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"ctrlmesh",previous:{title:"Installation",permalink:"/docs/v0.9/ctrlmesh/started/install"},next:{title:"FAQ",permalink:"/docs/v0.9/ctrlmesh/faq/"}},l={},p=[{value:"Install Controller Mesh Manager",id:"install-controller-mesh-manager",level:2},{value:"Enable Custom Operator Sharding",id:"enable-custom-operator-sharding",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"try-a-sample"},"Try a Sample"),(0,r.kt)("p",null,"This guide lets you quickly evaluate KusionStack Controller Mesh. "),(0,r.kt)("h2",{id:"install-controller-mesh-manager"},"Install Controller Mesh Manager"),(0,r.kt)("p",null,"Controller Mesh requires ",(0,r.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Install with helm")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# Firstly add KusionStack charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Wait manager ready\n$ kubectl -n ctrlmesh get po\nNAME READY STATUS RESTARTS AGE\nctrlmesh-57d6b4df57-mdslc 1/1 Running 0 40s\nctrlmesh-57d6b4df57-mtv2s 1/1 Running 0 40s\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"/docs/v0.9/ctrlmesh/started/install"},"Install manager with more options")),(0,r.kt)("h2",{id:"enable-custom-operator-sharding"},"Enable Custom Operator Sharding"),(0,r.kt)("p",null,"You can use the ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("a",{parentName:"strong",href:"https://kusionstack.io/docs/operating/introduction/"},"Operating v0.1.1"))," available here."),(0,r.kt)("p",null,"Deploy the sample operator with ShardingConfig:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm repo update\n$ helm install sample-operating kusionstack/operating \\\n --version v0.2.0 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true\n\n$ kubectl -n kusionstack-system get sts\nNAME READY AGE\nkusionstack-operating 5/5 1m45s\n\n# The proxy container will be automatically injected into the pod\n$ kubectl -n kusionstack-system get po\nNAME READY STATUS RESTARTS AGE\nkusionstack-operating-0 2/2 Running 0 42s\nkusionstack-operating-1 2/2 Running 0 32s\nkusionstack-operating-2 2/2 Running 0 21s\nkusionstack-operating-3 2/2 Running 0 12s\nkusionstack-operating-4 0/2 ContainerCreating 0 1s\n\n# Now we have three shards with three lease.\n# operating-0-canary -> [kusionstack-operating-0]\n# operating-1-normal -> [kusionstack-operating-1, kusionstack-operating-2]\n# operating-2-normal -> [kusionstack-operating-3, kusionstack-operating-4]\n$ kubectl -n kusionstack-system get lease\nNAME HOLDER AGE\nkusionstack-controller-manager---operating-0-canary kusionstack-operating-0_81b5bbae-be63-45ed-a939-e67e0c3d6326 12m\nkusionstack-controller-manager---operating-1-normal kusionstack-operating-1_e4bbad49-e6ec-42fa-8ffd-caae82156a3e 12m\nkusionstack-controller-manager---operating-2-normal kusionstack-operating-3_94f7f81a-f9e6-47d6-b72b-e16da479e9be 12m\n")),(0,r.kt)("p",null," Show the sample ShardingConfig:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm template sample-operating kusionstack/operating \\\n --version v0.1.1 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true \\\n --show-only templates/shardingconfig.yaml\n")),(0,r.kt)("p",null,"Here is a sample ",(0,r.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"---\n# Source: operating/templates/shardingconfig.yaml\napiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-root\n namespace: kusionstack-system\nspec:\n # Auto sharding config\n root:\n prefix: operating\n targetStatefulSet: kusionstack-operating\n canary:\n replicas: 1\n inNamespaces:\n - kusionstack-system\n auto:\n everyShardReplicas: 2\n shardingSize: 2\n resourceSelector:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - configmaps\n - pods\n - endpoints\n - services\n - replicasets\n - apiGroups:\n - apps.kusionstack.io\n resources:\n - '*'\n controller:\n leaderElectionName: kusionstack-controller-manager\n")),(0,r.kt)("p",null,"You can configure the ShardingConfig according to your requirements."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"In order to enable the ShardingConfig, you also need to add the following label to the pod template.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/enable-proxy: 'true'"),(0,r.kt)("br",{parentName:"p"}),"\n","We plan to deprecate it in future versions.")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Supported OS/ARCH",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("strong",{parentName:"p"},"ControllerMesh")," v0.1.0: ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/amd64"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/arm64"),".",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("strong",{parentName:"p"},"Operating")," v0.1.1: ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/amd64"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"linux/arm64"),". ")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/83192466.380d49f8.js b/assets/js/83192466.380d49f8.js new file mode 100644 index 00000000000..ffc8ea9c93e --- /dev/null +++ b/assets/js/83192466.380d49f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1599],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return n?o.createElement(h,a(a({ref:t},p),{},{components:n})):o.createElement(h,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:2},a="PodOpsLifecycle",l={unversionedId:"operating/concepts/podopslifecycle",id:"version-v0.10/operating/concepts/podopslifecycle",title:"PodOpsLifecycle",description:"Background",source:"@site/versioned_docs/version-v0.10/operating/concepts/podopslifecycle.md",sourceDirName:"operating/concepts",slug:"/operating/concepts/podopslifecycle",permalink:"/docs/operating/concepts/podopslifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/concepts/podopslifecycle.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/operating/started/demo-graceful-operation"},next:{title:"CollaSet",permalink:"/docs/operating/manuals/collaset"}},c={},s=[{value:"Background",id:"background",level:2},{value:"Introduction",id:"introduction",level:2},{value:"Developer's Guide",id:"developers-guide",level:2},{value:"Operation Controller",id:"operation-controller",level:3},{value:"Pod Cooperation Controller",id:"pod-cooperation-controller",level:3},{value:"Key Features",id:"key-features",level:2},{value:"Concurrency Support",id:"concurrency-support",level:3}],p={toc:s};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"podopslifecycle"},"PodOpsLifecycle"),(0,r.kt)("h2",{id:"background"},"Background"),(0,r.kt)("p",null,"Kubernetes provides a set of default controllers for workload management, such as StatefulSet, Deployment, and DaemonSet, which are responsible for Pod operations.\nMeanwhile, application users may also have some services outside the Kubernetes cluster that are closely related to the Pod Lifecycle, including traffic routing, service discovery, or alert monitoring.\nHowever, they face challenges in participating in the operational lifecycle of a Pod, even if they are connected to Kubernetes by developing a controller that watches the Pods."),(0,r.kt)("p",null,"PodOpsLifecycle aims to offer Kubernetes administrators and developers finer-grained control over the entire lifecycle of a Pod.\nIt enables developers to execute necessary actions before, during, and after specific phases of a Pod operation.\nFor instance, removing the Pod's IP from the traffic route before initiating the Pod operation, performing the actual Pod operations, and adding it back after the Pod operation is completed to achieve a smooth and graceful Pod operation, and prevent any traffic loss."),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"In PodOpsLifecycle, participants are classified into two roles: ",(0,r.kt)("inlineCode",{parentName:"p"},"operation controllers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"cooperation controllers"),"."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operation controllers")," are responsible for operating Pods, such as Deployments and StatefulSets from Kubernetes, and CollaSets from Operating which intend to scale, update, or recreate Pods."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Cooperation controllers")," are sensitive with Pod status. They handle resources or configurations around Pods, which may include traffic controller, alert monitoring controller, etc. These controllers typically reconcile Kubernetes resources around Pods with external services, such as sync Pod IPs with the LB provider, or maintaining Pods' metadata with application monitoring system.")),(0,r.kt)("p",null,"The two types of controllers do not need to be aware of each other. All controllers are organized by PodOpsLifecycle. Additionally, KusionStack Operating introduces extra phases around the native Kubernetes Pod Lifecycle: ServiceAvailable, Preparing, and Completing."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle",src:n(79164).Z,width:"1500",height:"978"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Completing"),": After a Pod is created or updated and becomes ready, Operating marks its PodOpsLifecycle as the ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing")," phase. During this phase, the Pod is in a ready condition, prompting cooperation controllers to perform actions such as registering the Pod IP in the traffic route. Once all cooperation controllers complete their tasks, Operating sets the PodOpsLifecycle to the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"ServiceAvailable"),": This phase indicates that the Pod is in a normal state and ready to serve. If everything goes smoothly, the Pod remains in the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase until the next operation."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Preparing"),": When an operation controller needs to operate the Pod, it triggers a new PodOpsLifecycle. The Pod then transitions from the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase to the ",(0,r.kt)("inlineCode",{parentName:"li"},"Preparing")," phase. During this phase, the Pod is initially marked as Unready by setting ReadinessGate to false. All cooperation controllers then begin preparing tasks, such as removing the Pod's IP from the traffic route. After completing these tasks, the Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operating"),": If a Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase, it is expected to accept any kind of operation without any damage, including recreation, scaling-in, upgrading, etc. Operation controllers are permitted to apply any changes to this Pod. Once all these operations are completed, the Pod advances to the next phase \u2014 ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing"),", and the PodOpsLifecycle continues.")),(0,r.kt)("p",null,"The PodOpsLifecycle detail and the relationship with Kubernetes native Pod Lifecycle is showed by following sequence diagram."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle-sequence-diagram",src:n(57590).Z,width:"1500",height:"694"})),(0,r.kt)("h2",{id:"developers-guide"},"Developer's Guide"),(0,r.kt)("p",null,"This section introduces how to develop operation controllers and cooperation controllers to interact with PodOpsLifecycle."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The operation controller is responsible for a set of Pod operation tasks. KusionStack Operating has already provided various types of operation controllers. Users only need to develop a new operation controller if a new kind of Pod operation needs to be added."),(0,r.kt)("li",{parentName:"ul"},"The cooperation controller participates in PodOpsLifecycle before and after operating on a Pod, such as the Traffic controller, alert monitoring controller, and other controllers responsible for maintaining the Pod and application status. Users should develop a new cooperation controller only when there is a new type of service or status around the Pod that needs to be maintained, such as integrating with a new traffic provider.")),(0,r.kt)("h3",{id:"operation-controller"},"Operation Controller"),(0,r.kt)("p",null,"The operation controller is responsible for Pod operations. The tasks that an operation controller needs to perform during PodOpsLifecycle include triggering a PodOpsLifecycle, checking whether the Pod has entered the Operating phase, performing Pod operations, and marking Pod operations as finished. These actions interacting with PodOpsLifecycle are provided in the package ",(0,r.kt)("inlineCode",{parentName:"p"},"kusionstack.io/operating/pkg/controllers/utils/podopslifecycle/utils.go"),"."),(0,r.kt)("p",null,"A simple operation controller reconcile method would look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n "sigs.k8s.io/controller-runtime/pkg/client"\n \n "kusionstack.io/operating/pkg/controllers/utils/podopslifecycle"\n)\n\nvar operationAdapter = &OperationOpsLifecycleAdapter{}\n\ntype OperationOpsLifecycleAdapter struct {\n}\n\n// GetID indicates ID of the PodOpsLifecycle\nfunc (a *OperationOpsLifecycleAdapter) GetID() string {\n return "new-id"\n}\n\n// GetType indicates type for this Operation Controller\nfunc (a *OperationOpsLifecycleAdapter) GetType() podopslifecycle.OperationType {\n return "new-type"\n}\n\n// AllowMultiType indicates whether multiple IDs which have the same Type are allowed\nfunc (a *OperationOpsLifecycleAdapter) AllowMultiType() bool {\n return true\n}\n\n// WhenBegin is a hook, which will be executed when begin a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenBegin(pod client.Object) (bool, error) {\n return false, nil\n}\n\n// WhenFinish is a hook, which will be executed when finish a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenFinish(pod client.Object) (bool, error) {\n return false, nil\n}\n\n......\nfunc (r *PodOperationReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n // check if the Pod needs operation\n if !r.needOperation(pod) {\n return reconcile.Result{}, nil\n }\n\n // if PodOpsLifecycle has not been triggered, trigger it\n if !podopslifecycle.IsDuringOps(OpsLifecycleAdapter, pod) {\n if updated, err := podopslifecycle.Begin(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n } else if updated {\n return reconcile.Result{}, nil\n }\n }\n\n // waiting until Pod enters operating phase\n if _, allowed := podopslifecycle.AllowOps(operationAdapter, 0, pod); !allowed {\n return reconcile.Result{}, nil\n }\n\n // do operation works\n if completed := r.doPodOperation(pod); !completed {\n return reconcile.Result{}, nil\n }\n\n // after operation works completed, finish operating phase to continue PodOpsLifecycle\n if _, err := podopslifecycle.Finish(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n }\n}\n')),(0,r.kt)("h3",{id:"pod-cooperation-controller"},"Pod Cooperation Controller"),(0,r.kt)("p",null,"There are two ways to develop a cooperation controller.\nOne way is to develop a controller using the controller runtime and adhering to some conventions of PodOpsLifecycle and Kubernetes.\nAnother way is to take the use of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist"},"ResourceConsist")," framework provided by KusionStack, which can be referenced from its ",(0,r.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/resourceconsist"},"documentation"),"."),(0,r.kt)("p",null,"The following outlines the first approach."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "k8s.io/apimachinery/pkg/api/errors"\n k8spod "k8s.io/kubernetes/pkg/api/v1/pod/util.go"\n "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n\n operatingapps "kusionstack.io/operating/apis/apps/v1alpha1"\n)\n\nconst (\n // Finalizer needs to have prefix: `prot.podopslifecycle.kusionstack.io`.\n // KusionStack Operating keeps this prefix back-compatible,\n // so that it can be hard code to decouple with KusionStack Operating.\n finalizerPrefix = operatingapps.PodOperationProtectionFinalizerPrefix\n\n protectionFinalizer = finalizerPrefix + "/" + "unique-id"\n)\n\n......\nfunc (r *PodResourceReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n if k8spod.IsPodReady(pod) {\n // do resource reconcile like add Pod IP to traffic route\n r.trafficOn(pod.status.PodIP)\n // It is important to add a unique finalizer on this Pod\n return reconcile.Result{}, r.addFinalizer(ctx, pod, protectionFinalizer)\n }\n\n if !k8spod.IsPodReady(pod) {\n // do resource reconcile like remove Pod IP from traffic route\n r.trafficOff(pod.status.PodIP)\n // It is important to remove the unique finalizer from this Pod\n return reconcile.Result{}, r.removeFinalizer(ctx, pod, protectionFinalizer)\n }\n}\n\nfunc (r *PodResourceReconciler) addFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.AddFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n\nfunc (r *PodResourceReconciler) removeFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if !controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.RemoveFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n')),(0,r.kt)("h2",{id:"key-features"},"Key Features"),(0,r.kt)("h3",{id:"concurrency-support"},"Concurrency Support"),(0,r.kt)("p",null,"PodOpsLifecycle in KusionStack Operating supports concurrency.\nIt means PodOpsLifecycle is able to organize and track multi controllers operating the same pod at the same time.\nFor example, when a controller is going to update Pod, other controllers are allowed to do other operations at the same time, like delete, restart, recreate it,\nalthough the result may not be meaningful."))}d.isMDXComponent=!0},57590:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-sequence-diagram-47bc9fbcab1c539cb11e8bc5f3987cf5.png"},79164:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-6ed0948e3faaf60bcd3ddb5c572038cf.png"}}]); \ No newline at end of file diff --git a/assets/js/83192466.b599c16b.js b/assets/js/83192466.b599c16b.js deleted file mode 100644 index cdf3f03643a..00000000000 --- a/assets/js/83192466.b599c16b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1599],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return n?o.createElement(h,a(a({ref:t},p),{},{components:n})):o.createElement(h,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:2},a="PodOpsLifecycle",l={unversionedId:"operating/concepts/podopslifecycle",id:"version-v0.10/operating/concepts/podopslifecycle",title:"PodOpsLifecycle",description:"Background",source:"@site/versioned_docs/version-v0.10/operating/concepts/podopslifecycle.md",sourceDirName:"operating/concepts",slug:"/operating/concepts/podopslifecycle",permalink:"/docs/operating/concepts/podopslifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/concepts/podopslifecycle.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/operating/started/demo-graceful-operation"},next:{title:"CollaSet",permalink:"/docs/operating/manuals/collaset"}},c={},s=[{value:"Background",id:"background",level:2},{value:"Introduction",id:"introduction",level:2},{value:"Developer's Guide",id:"developers-guide",level:2},{value:"Operation Controller",id:"operation-controller",level:3},{value:"Pod Cooperation Controller",id:"pod-cooperation-controller",level:3},{value:"Key Features",id:"key-features",level:2},{value:"Concurrency Support",id:"concurrency-support",level:3}],p={toc:s};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"podopslifecycle"},"PodOpsLifecycle"),(0,r.kt)("h2",{id:"background"},"Background"),(0,r.kt)("p",null,"Kubernetes provides a set of default controllers for workload management, such as StatefulSet, Deployment, and DaemonSet, which are responsible for Pod operations.\nMeanwhile, application users may also have some services outside the Kubernetes cluster that are closely related to the Pod Lifecycle, including traffic routing, service discovery, or alert monitoring.\nHowever, they face challenges in participating in the operational lifecycle of a Pod, even if they are connected to Kubernetes by developing a controller that watches the Pods."),(0,r.kt)("p",null,"PodOpsLifecycle aims to offer Kubernetes administrators and developers finer-grained control over the entire lifecycle of a Pod.\nIt enables developers to execute necessary actions before, during, and after specific phases of a Pod operation.\nFor instance, removing the Pod's IP from the traffic route before initiating the Pod operation, performing the actual Pod operations, and adding it back after the Pod operation is completed to achieve a smooth and graceful Pod operation, and prevent any traffic loss."),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"In PodOpsLifecycle, participants are classified into two roles: ",(0,r.kt)("inlineCode",{parentName:"p"},"operation controllers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"cooperation controllers"),"."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operation controllers")," are responsible for operating Pods, such as Deployments and StatefulSets from Kubernetes, and CollaSets from Operating which intend to scale, update, or recreate Pods."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Cooperation controllers")," are sensitive with Pod status. They handle resources or configurations around Pods, which may include traffic controller, alert monitoring controller, etc. These controllers typically reconcile Kubernetes resources around Pods with external services, such as sync Pod IPs with the LB provider, or maintaining Pods' metadata with application monitoring system.")),(0,r.kt)("p",null,"The two types of controllers do not need to be aware of each other. All controllers are organized by PodOpsLifecycle. Additionally, KusionStack Operating introduces extra phases around the native Kubernetes Pod Lifecycle: ServiceAvailable, Preparing, and Completing."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle",src:n(79164).Z,width:"1500",height:"978"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Completing"),": After a Pod is created or updated and becomes ready, Operating marks its PodOpsLifecycle as the ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing")," phase. During this phase, the Pod is in a ready condition, prompting cooperation controllers to perform actions such as registering the Pod IP in the traffic route. Once all cooperation controllers complete their tasks, Operating sets the PodOpsLifecycle to the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"ServiceAvailable"),": This phase indicates that the Pod is in a normal state and ready to serve. If everything goes smoothly, the Pod remains in the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase until the next operation."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Preparing"),": When an operation controller needs to operate the Pod, it triggers a new PodOpsLifecycle. The Pod then transitions from the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase to the ",(0,r.kt)("inlineCode",{parentName:"li"},"Preparing")," phase. During this phase, the Pod is initially marked as Unready by setting ReadinessGate to false. All cooperation controllers then begin preparing tasks, such as removing the Pod's IP from the traffic route. After completing these tasks, the Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operating"),": If a Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase, it is expected to accept any kind of operation without any damage, including recreation, scaling-in, upgrading, etc. Operation controllers are permitted to apply any changes to this Pod. Once all these operations are completed, the Pod advances to the next phase \u2014 ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing"),", and the PodOpsLifecycle continues.")),(0,r.kt)("p",null,"The PodOpsLifecycle detail and the relationship with Kubernetes native Pod Lifecycle is showed by following sequence diagram."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle-sequence-diagram",src:n(57590).Z,width:"1500",height:"694"})),(0,r.kt)("h2",{id:"developers-guide"},"Developer's Guide"),(0,r.kt)("p",null,"This section introduces how to develop operation controllers and cooperation controllers to interact with PodOpsLifecycle."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The operation controller is responsible for a set of Pod operation tasks. KusionStack Operating has already provided various types of operation controllers. Users only need to develop a new operation controller if a new kind of Pod operation needs to be added."),(0,r.kt)("li",{parentName:"ul"},"The cooperation controller participates in PodOpsLifecycle before and after operating on a Pod, such as the Traffic controller, alert monitoring controller, and other controllers responsible for maintaining the Pod and application status. Users should develop a new cooperation controller only when there is a new type of service or status around the Pod that needs to be maintained, such as integrating with a new traffic provider.")),(0,r.kt)("h3",{id:"operation-controller"},"Operation Controller"),(0,r.kt)("p",null,"The operation controller is responsible for Pod operations. The tasks that an operation controller needs to perform during PodOpsLifecycle include triggering a PodOpsLifecycle, checking whether the Pod has entered the Operating phase, performing Pod operations, and marking Pod operations as finished. These actions interacting with PodOpsLifecycle are provided in the package ",(0,r.kt)("inlineCode",{parentName:"p"},"kusionstack.io/operating/pkg/controllers/utils/podopslifecycle/utils.go"),"."),(0,r.kt)("p",null,"A simple operation controller reconcile method would look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n "sigs.k8s.io/controller-runtime/pkg/client"\n \n "kusionstack.io/operating/pkg/controllers/utils/podopslifecycle"\n)\n\nvar operationAdapter = &OperationOpsLifecycleAdapter{}\n\ntype OperationOpsLifecycleAdapter struct {\n}\n\n// GetID indicates ID of the PodOpsLifecycle\nfunc (a *OperationOpsLifecycleAdapter) GetID() string {\n return "new-id"\n}\n\n// GetType indicates type for this Operation Controller\nfunc (a *OperationOpsLifecycleAdapter) GetType() podopslifecycle.OperationType {\n return "new-type"\n}\n\n// AllowMultiType indicates whether multiple IDs which have the same Type are allowed\nfunc (a *OperationOpsLifecycleAdapter) AllowMultiType() bool {\n return true\n}\n\n// WhenBegin is a hook, which will be executed when begin a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenBegin(pod client.Object) (bool, error) {\n return false, nil\n}\n\n// WhenFinish is a hook, which will be executed when finish a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenFinish(pod client.Object) (bool, error) {\n return false, nil\n}\n\n......\nfunc (r *PodOperationReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n // check if the Pod needs operation\n if !r.needOperation(pod) {\n return reconcile.Result{}, nil\n }\n\n // if PodOpsLifecycle has not been triggered, trigger it\n if !podopslifecycle.IsDuringOps(OpsLifecycleAdapter, pod) {\n if updated, err := podopslifecycle.Begin(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n } else if updated {\n return reconcile.Result{}, nil\n }\n }\n\n // waiting until Pod enters operating phase\n if _, allowed := podopslifecycle.AllowOps(operationAdapter, 0, pod); !allowed {\n return reconcile.Result{}, nil\n }\n\n // do operation works\n if completed := r.doPodOperation(pod); !completed {\n return reconcile.Result{}, nil\n }\n\n // after operation works completed, finish operating phase to continue PodOpsLifecycle\n if _, err := podopslifecycle.Finish(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n }\n}\n')),(0,r.kt)("h3",{id:"pod-cooperation-controller"},"Pod Cooperation Controller"),(0,r.kt)("p",null,"There are two ways to develop a cooperation controller.\nOne way is to develop a controller using the controller runtime and adhering to some conventions of PodOpsLifecycle and Kubernetes.\nAnother way is to take the use of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist"},"ResourceConsist")," framework provided by KusionStack, which can be referenced from its ",(0,r.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/resourceconsist"},"documentation"),"."),(0,r.kt)("p",null,"The following outlines the first approach."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "k8s.io/apimachinery/pkg/api/errors"\n k8spod "k8s.io/kubernetes/pkg/api/v1/pod/util.go"\n "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n\n operatingapps "kusionstack.io/operating/apis/apps/v1alpha1"\n)\n\nconst (\n // Finalizer needs to have prefix: `prot.podopslifecycle.kusionstack.io`.\n // KusionStack Operating keeps this prefix back-compatible,\n // so that it can be hard code to decouple with KusionStack Operating.\n finalizerPrefix = operatingapps.PodOperationProtectionFinalizerPrefix\n\n protectionFinalizer = finalizerPrefix + "/" + "unique-id"\n)\n\n......\nfunc (r *PodResourceReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n if k8spod.IsPodReady(pod) {\n // do resource reconcile like add Pod IP to traffic route\n r.trafficOn(pod.status.PodIP)\n // It is important to add a unique finalizer on this Pod\n return reconcile.Result{}, r.addFinalizer(ctx, pod, protectionFinalizer)\n }\n\n if !k8spod.IsPodReady(pod) {\n // do resource reconcile like remove Pod IP from traffic route\n r.trafficOff(pod.status.PodIP)\n // It is important to remove the unique finalizer from this Pod\n return reconcile.Result{}, r.removeFinalizer(ctx, pod, protectionFinalizer)\n }\n}\n\nfunc (r *PodResourceReconciler) addFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.AddFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n\nfunc (r *PodResourceReconciler) removeFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if !controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.RemoveFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n')),(0,r.kt)("h2",{id:"key-features"},"Key Features"),(0,r.kt)("h3",{id:"concurrency-support"},"Concurrency Support"),(0,r.kt)("p",null,"PodOpsLifecycle in KusionStack Operating supports concurrency.\nIt means PodOpsLifecycle is able to organize and track multi controllers operating the same pod at the same time.\nFor example, when a controller is going to update Pod, other controllers are allowed to do other operations at the same time, like delete, restart, recreate it,\nalthough the result may not be meaningful."))}d.isMDXComponent=!0},57590:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-sequence-diagram-47bc9fbcab1c539cb11e8bc5f3987cf5.png"},79164:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-6ed0948e3faaf60bcd3ddb5c572038cf.png"}}]); \ No newline at end of file diff --git a/assets/js/837fd906.6bd427c4.js b/assets/js/837fd906.6bd427c4.js new file mode 100644 index 00000000000..3c5c459c362 --- /dev/null +++ b/assets/js/837fd906.6bd427c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1019],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),d=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=d(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(p,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,o(o({ref:t},s),{},{components:n})):a.createElement(k,o({ref:t},s))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="probe",i={unversionedId:"kusion/reference/model/catalog_models/internal/container/probe/doc_probe",id:"version-v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe",title:"probe",description:"Schema Probe",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe.md",sourceDirName:"kusion/reference/model/catalog_models/internal/container/probe",slug:"/kusion/reference/model/catalog_models/internal/container/probe/doc_probe",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"lifecycle",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle"},next:{title:"common",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common"}},p={},d=[{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3}],s={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"probe"},"probe"),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/837fd906.86c0be46.js b/assets/js/837fd906.86c0be46.js deleted file mode 100644 index 336e9d07c42..00000000000 --- a/assets/js/837fd906.86c0be46.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1019],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),d=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=d(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(p,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,o(o({ref:t},s),{},{components:n})):a.createElement(k,o({ref:t},s))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},o="probe",i={unversionedId:"kusion/reference/model/catalog_models/internal/container/probe/doc_probe",id:"version-v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe",title:"probe",description:"Schema Probe",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe.md",sourceDirName:"kusion/reference/model/catalog_models/internal/container/probe",slug:"/kusion/reference/model/catalog_models/internal/container/probe/doc_probe",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"lifecycle",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle"},next:{title:"common",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common"}},p={},d=[{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3}],s={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"probe"},"probe"),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/83e1f194.98952125.js b/assets/js/83e1f194.98952125.js deleted file mode 100644 index 8afd3424953..00000000000 --- a/assets/js/83e1f194.98952125.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6447],{3905:(e,a,t)=>{t.d(a,{Zo:()=>c,kt:()=>m});var n=t(67294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function o(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);a&&(n=n.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var a=1;a=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=n.createContext({}),u=function(e){var a=n.useContext(l),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},c=function(e){var a=u(e.components);return n.createElement(l.Provider,{value:a},e.children)},p={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},d=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(t),m=r,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||o;return t?n.createElement(h,i(i({ref:a},c),{},{components:t})):n.createElement(h,i({ref:a},c))}));function m(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var s={};for(var l in a)hasOwnProperty.call(a,l)&&(s[l]=a[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var u=2;u{t.d(a,{Z:()=>i});var n=t(67294),r=t(86010);const o="tabItem_Ymn6";function i(e){let{children:a,hidden:t,className:i}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,i),hidden:t},a)}},74866:(e,a,t)=>{t.d(a,{Z:()=>S});var n=t(87462),r=t(67294),o=t(86010),i=t(12466),s=t(76775),l=t(91980),u=t(67392),c=t(50012);function p(e){return function(e){var a;return(null==(a=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:a}=e;return!!a&&"object"==typeof a&&"value"in a}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:a.filter(Boolean))??[]}(e).map((e=>{let{props:{value:a,label:t,attributes:n,default:r}}=e;return{value:a,label:t,attributes:n,default:r}}))}function d(e){const{values:a,children:t}=e;return(0,r.useMemo)((()=>{const e=a??p(t);return function(e){const a=(0,u.l)(e,((e,a)=>e.value===a.value));if(a.length>0)throw new Error(`Docusaurus error: Duplicate values "${a.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[a,t])}function m(e){let{value:a,tabValues:t}=e;return t.some((e=>e.value===a))}function h(e){let{queryString:a=!1,groupId:t}=e;const n=(0,s.k6)(),o=function(e){let{queryString:a=!1,groupId:t}=e;if("string"==typeof a)return a;if(!1===a)return null;if(!0===a&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:a,groupId:t});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const a=new URLSearchParams(n.location.search);a.set(o,e),n.replace({...n.location,search:a.toString()})}),[o,n])]}function f(e){const{defaultValue:a,queryString:t=!1,groupId:n}=e,o=d(e),[i,s]=(0,r.useState)((()=>function(e){let{defaultValue:a,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(a){if(!m({value:a,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${a}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return a}const n=t.find((e=>e.default))??t[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:a,tabValues:o}))),[l,u]=h({queryString:t,groupId:n}),[p,f]=function(e){let{groupId:a}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(a),[n,o]=(0,c.Nk)(t);return[n,(0,r.useCallback)((e=>{t&&o.set(e)}),[t,o])]}({groupId:n}),k=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{k&&s(k)}),[k]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,o]),tabValues:o}}var k=t(72389);const g="tabList__CuJ",b="tabItem_LNqP";function y(e){let{className:a,block:t,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const a=e.currentTarget,t=c.indexOf(a),n=u[t].value;n!==s&&(p(a),l(n))},m=e=>{var a;let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const a=c.indexOf(e.currentTarget)+1;t=c[a]??c[0];break}case"ArrowLeft":{const a=c.indexOf(e.currentTarget)-1;t=c[a]??c[c.length-1];break}}null==(a=t)||a.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":t},a)},u.map((e=>{let{value:a,label:t,attributes:i}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===a?0:-1,"aria-selected":s===a,key:a,ref:e=>c.push(e),onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",b,null==i?void 0:i.className,{"tabs__item--active":s===a})}),t??a)})))}function v(e){let{lazy:a,children:t,selectedValue:n}=e;const o=(Array.isArray(t)?t:[t]).filter(Boolean);if(a){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,a)=>(0,r.cloneElement)(e,{key:a,hidden:e.props.value!==n}))))}function w(e){const a=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(y,(0,n.Z)({},e,a)),r.createElement(v,(0,n.Z)({},e,a)))}function S(e){const a=(0,k.Z)();return r.createElement(w,(0,n.Z)({key:String(a)},e))}},45855:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>u,toc:()=>p});var n=t(87462),r=(t(67294),t(3905)),o=t(74866),i=t(85162);const s={id:"databse"},l="Managed Databases",u={unversionedId:"kusion/configuration-walkthrough/databse",id:"version-v0.10/kusion/configuration-walkthrough/databse",title:"Managed Databases",description:"The database attribute in the AppConfiguration instance is used to describe the specification for any databases needed for the application.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/6-database.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/databse",permalink:"/docs/kusion/configuration-walkthrough/databse",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/6-database.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"databse"},sidebar:"kusion",previous:{title:"Application Networking",permalink:"/docs/kusion/configuration-walkthrough/networking"},next:{title:"Secrets",permalink:"/docs/kusion/configuration-walkthrough/secret"}},c={},p=[{value:"Import",id:"import",level:2},{value:"Types of Database offerings",id:"types-of-database-offerings",level:2},{value:"Cloud Credentials and Permissions",id:"cloud-credentials-and-permissions",level:2},{value:"Configure Database",id:"configure-database",level:2},{value:"Provision a Cloud Database",id:"provision-a-cloud-database",level:3},{value:"AWS RDS Instance",id:"aws-rds-instance",level:4},{value:"AliCloud RDS Instance",id:"alicloud-rds-instance",level:4},{value:"Local Database",id:"local-database",level:3},{value:"Database Credentials",id:"database-credentials",level:2},{value:"Configure Network Access",id:"configure-network-access",level:2},{value:"Subnet ID",id:"subnet-id",level:3},{value:"Private Routing",id:"private-routing",level:3}],d={toc:p};function m(e){let{components:a,...t}=e;return(0,r.kt)("wrapper",(0,n.Z)({},d,t,{components:a,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"managed-databases"},"Managed Databases"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"database")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for any databases needed for the application."),(0,r.kt)("p",null,"You can currently have several databases with ",(0,r.kt)("strong",{parentName:"p"},"different database names")," for an application at the same time."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/configuration-walkthrough/overview#configuration-file-overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.accessories.mysql\nimport catalog.models.schema.v1.accessories.postgres\n")),(0,r.kt)("h2",{id:"types-of-database-offerings"},"Types of Database offerings"),(0,r.kt)("p",null,"As of version 0.10.0, Kusion supports the following database offerings on the cloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://aws.amazon.com/rds/"},"AWS")),(0,r.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/databases"},"AliCloud"))),(0,r.kt)("p",null,"More database types on more cloud vendors will be added in the future."),(0,r.kt)("p",null,"Alternatively, Kusion also supports creating a database at ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost")," for local testing needs. A local database is quicker to stand up and easier to manage. It also eliminates the need for an account and any relevant costs with the cloud providers in the case that a local testing environment is sufficient."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"You do need a local Kubernetes cluster to run the local database workloads. You can refer to ",(0,r.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/start/"},"Minikube")," or ",(0,r.kt)("a",{parentName:"p",href:"https://kind.sigs.k8s.io/docs/user/quick-start/"},"Kind")," to get started.\nTo see an end-to-end use case for standing up a local testing environment including a local database, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/getting-started/deliver-wordpress"},"Kusion Quickstart"),".")),(0,r.kt)("h2",{id:"cloud-credentials-and-permissions"},"Cloud Credentials and Permissions"),(0,r.kt)("p",null,"Kusion provisions databases on the cloud via ",(0,r.kt)("a",{parentName:"p",href:"https://www.terraform.io/"},"terraform")," providers. For it to create ",(0,r.kt)("em",{parentName:"p"},"any")," cloud resources, it requires a set of credentials that belongs to an account that has the appropriate write access so the terraform provider can be initialized properly."),(0,r.kt)("p",null,"For AWS, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export AWS_ACCESS_KEY_ID="xxxxxxxxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="xxxxxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,"For AliCloud, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export ALICLOUD_ACCESS_KEY="xxxxxxxxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="xxxxxxxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,"The user account that owns these credentials would need to have the proper permission policies attached to create databases and security groups. If you are using the cloud-managed policies, the policies needed to provision a database and configure firewall rules are listed below."),(0,r.kt)("p",null,"For AWS:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"For AliCloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"Alternatively, you can use customer managed policies if the cloud provider built-in policies don't meet your needs. The list of permissions needed are in the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonRDSFullAccess.html#AmazonRDSFullAccess-json"},"AmazonRDSFullAccess Policy Document")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonVPCFullAccess.html"},"AmazonVPCFullAccess Policy Document"),". It will most likely be a subset of the permissions in the policy documents."),(0,r.kt)("h2",{id:"configure-database"},"Configure Database"),(0,r.kt)("h3",{id:"provision-a-cloud-database"},"Provision a Cloud Database"),(0,r.kt)("p",null,"Assuming the steps in the ",(0,r.kt)("a",{parentName:"p",href:"#cloud-credentials-and-permissions"},"Cloud Credentials and Permissions")," section is setup properly, you can now provision cloud databases via Kusion."),(0,r.kt)("h4",{id:"aws-rds-instance"},"AWS RDS Instance"),(0,r.kt)("p",null,"To provision an AWS RDS instance with MySQL v8.0 or PostgreSQL v14.0, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# MySQL configurations for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# PostgreSQL configurations for AWS RDS\nmodules: \n postgres: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,r.kt)("p",null,"For KCL configuration file declarations: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n database: {\n pgadmin: postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,r.kt)("p",null,"It's highly recommended to replace ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," and closely manage the whitelist of IPs that can access the database for security purposes. The ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," in the example above or if ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," is omitted altogether will allow connections from anywhere which would typically be a security bad practice."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," field determines the computation and memory capacity of the RDS instance. The ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.micro")," instance type in the example above represents the ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance class with a size of ",(0,r.kt)("inlineCode",{parentName:"p"},"micro"),". In the same ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance family there are also ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.small"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.medium"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.2xlarge"),", etc."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Support"},"here"),"."),(0,r.kt)("p",null,"You can also adjust the storage capacity for the database instance by changing the ",(0,r.kt)("inlineCode",{parentName:"p"},"size")," field which is storage size measured in gigabytes. The minimum is 20. More details can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#Concepts.Storage.GeneralSSD"},"here"),"."),(0,r.kt)("h4",{id:"alicloud-rds-instance"},"AliCloud RDS Instance"),(0,r.kt)("p",null,"To provision an Alicloud RDS instance with MySQL or PostgreSQL, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". Note that AliCloud RDS has several additional fields such as ",(0,r.kt)("inlineCode",{parentName:"p"},"category"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting"),":"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# MySQL configurations for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# PostgreSQL configurations for Alicloud RDS\nmodules: \n postgres:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,r.kt)("p",null,"For KCL configuration file declarations: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n database: {\n pgadmin: postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,r.kt)("p",null,"We will walkthrough ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," in the ",(0,r.kt)("a",{parentName:"p",href:"#configure-network-access"},"Configure Network Access")," section."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/primary-apsaradb-rds-for-mysql-instance-types#concept-2096487"},"MySQL instance types(x86)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/primary-apsaradb-rds-for-postgresql-instance-types#concept-2096578"},"PostgreSQL instance types"))),(0,r.kt)("h3",{id:"local-database"},"Local Database"),(0,r.kt)("p",null,"To deploy a local database with MySQL v8.0 or PostgreSQL v14.0:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n database: {\n wordpress: mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n database: {\n pgadmin: postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n }\n }\n}\n')))),(0,r.kt)("h2",{id:"database-credentials"},"Database Credentials"),(0,r.kt)("p",null,"There is no need to manage the database credentials manually. Kusion will automatically generate a random password, set it as the credential when creating the database, and then inject the hostname, username and password into the application runtime."),(0,r.kt)("p",null,"You have the option to BYO (Bring Your Own) username for the database credential by specifying the ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n mysql:\n default:\n # ...\n username: "my_username"\n')),(0,r.kt)("p",null,"You ",(0,r.kt)("strong",{parentName:"p"},"cannot")," bring your own password. The password will always be managed by Kusion automatically."),(0,r.kt)("p",null,"The database credentials are injected into the environment variables of the application container. You can access them via the following env vars:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# env | grep KUSION_DB\nKUSION_DB_HOST_WORDPRESS_MYSQL=wordpress.xxxxxxxx.us-east-1.rds.amazonaws.com\nKUSION_DB_USERNAME_WORDPRESS_MYSQL=xxxxxxxxx\nKUSION_DB_PASSWORD_WORDPRESS_MYSQL=xxxxxxxxx\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the environment of database credentials injected by Kusion can be found at ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/postgres#credentials-and-connectivity"},"postgres credentials and connectivity"))),(0,r.kt)("p",null,"You can use these environment variables out of the box. Or most likely, your application might retrieve the connection details from a different set of environment variables. In that case, you can map the kusion environment variables to the ones expected by your application using the ",(0,r.kt)("inlineCode",{parentName:"p"},"$()")," expression. "),(0,r.kt)("p",null,"This example below will assign the value of ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_WORDPRESS_MYSQL")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_HOST"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_USERNAME_WORDPRESS_MYSQL")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER"),", likewise for ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_PASSWORD_WORDPRESS_MYSQL")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_PASSWORD"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3-apache"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n }\n # ...\n }\n }\n # ...\n }\n database: {\n # ...\n }\n}\n')),(0,r.kt)("h2",{id:"configure-network-access"},"Configure Network Access"),(0,r.kt)("p",null,"You can also optionally configure the network access to the database as part of the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". This is highly recommended because it dramatically increases the security posture of your cloud environment in the means of least privilege principle."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"Database")," schema declares the list of network addresses that are allowed to access the database. The network addresses are in the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/what-is/cidr/"},"CIDR notation")," and can be either a private IP range (",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc1918"},"RFC-1918")," and ",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6598"},"RFC-6598")," address) or a public one."),(0,r.kt)("p",null,"If the database need to be accessed from a public location (which should most likely not be the case in a production environment), ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," need to include the public IP address of the traffic source (For instance, if the RDS database needs to be accessed from your computer)."),(0,r.kt)("p",null,"To configure AWS RDS to restrict network access from a VPC with a CIDR of ",(0,r.kt)("inlineCode",{parentName:"p"},"10.0.1.0/24")," and a public IP of ",(0,r.kt)("inlineCode",{parentName:"p"},"103.192.227.125"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n mysql: \n default: \n cloud: aws\n # ...\n securityIPs: \n - "10.0.1.0/24"\n - "103.192.227.125/32"\n')),(0,r.kt)("p",null,"Depending on the cloud provider, the default behavior of the database firewall settings may differ if omitted."),(0,r.kt)("h3",{id:"subnet-id"},"Subnet ID"),(0,r.kt)("p",null,"On AWS, you have the option to launch the RDS instance inside a specific VPC if a ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is present in the application configuration. By default, if ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is not provided, the RDS will be created in the default VPC for that account. However, the recommendation is to self-manage your VPCs to provider better isolation from a network security perspective."),(0,r.kt)("p",null,"On AliCloud, the ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is required. The concept of subnet maps to VSwitch in AliCloud."),(0,r.kt)("p",null,"To place the RDS instance into a specific VPC on Alicloud:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n mysql: \n default: \n cloud: alicloud\n # ...\n subnetID: "subnet-xxxxxxxxxxxxxxxx"\n')),(0,r.kt)("h3",{id:"private-routing"},"Private Routing"),(0,r.kt)("p",null,"There is an option to enforce private routing on certain cloud providers if both the workload and the database are running on the cloud."),(0,r.kt)("p",null,"On AliCloud, you can set the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". The database host generated will be a private FQDN that is only resolvable and accessible from within the AliCloud VPCs. Setting ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when ",(0,r.kt)("inlineCode",{parentName:"p"},"type")," is ",(0,r.kt)("inlineCode",{parentName:"p"},"aws")," is a no-op."),(0,r.kt)("p",null,"To enforce private routing on AliCloud:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules: \n mysql: \n default: \n cloud: alicloud\n # ...\n privateRouting: true\n")),(0,r.kt)("p",null,"Kusion will then generate a private FQDN and inject it into the application runtime as the environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_")," for the application to use. A complete list of Kusion-managed environment variables for mysql database can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"here"),"."),(0,r.kt)("p",null,"Otherwise when using the public FQDN to connect to a database from the workload, the route will depend on cloud provider's routing preference. The options are generally either:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Travel as far as possible on the cloud provider's global backbone network, or also referred to as cold potato routing, or"),(0,r.kt)("li",{parentName:"ul"},"Egress as early as possible to the public Internet and re-enter the cloud provider's datacenter later, or also referred to as hot potato routing")),(0,r.kt)("p",null,"The prior generally has better performance but is also more expensive."),(0,r.kt)("p",null,"You can find a good read on the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/blogs/architecture/internet-routing-and-traffic-engineering/"},"AWS Blog")," or the ",(0,r.kt)("a",{parentName:"p",href:"https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/routing-preference-overview"},"Microsoft Learn"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/83e1f194.ad69af40.js b/assets/js/83e1f194.ad69af40.js new file mode 100644 index 00000000000..cdb25525c99 --- /dev/null +++ b/assets/js/83e1f194.ad69af40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6447],{3905:(e,a,t)=>{t.d(a,{Zo:()=>c,kt:()=>m});var n=t(67294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function o(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);a&&(n=n.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var a=1;a=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=n.createContext({}),u=function(e){var a=n.useContext(l),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},c=function(e){var a=u(e.components);return n.createElement(l.Provider,{value:a},e.children)},p={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},d=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(t),m=r,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||o;return t?n.createElement(h,i(i({ref:a},c),{},{components:t})):n.createElement(h,i({ref:a},c))}));function m(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var s={};for(var l in a)hasOwnProperty.call(a,l)&&(s[l]=a[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var u=2;u{t.d(a,{Z:()=>i});var n=t(67294),r=t(86010);const o="tabItem_Ymn6";function i(e){let{children:a,hidden:t,className:i}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,i),hidden:t},a)}},74866:(e,a,t)=>{t.d(a,{Z:()=>S});var n=t(87462),r=t(67294),o=t(86010),i=t(12466),s=t(76775),l=t(91980),u=t(67392),c=t(50012);function p(e){return function(e){var a;return(null==(a=r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:a}=e;return!!a&&"object"==typeof a&&"value"in a}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:a.filter(Boolean))??[]}(e).map((e=>{let{props:{value:a,label:t,attributes:n,default:r}}=e;return{value:a,label:t,attributes:n,default:r}}))}function d(e){const{values:a,children:t}=e;return(0,r.useMemo)((()=>{const e=a??p(t);return function(e){const a=(0,u.l)(e,((e,a)=>e.value===a.value));if(a.length>0)throw new Error(`Docusaurus error: Duplicate values "${a.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[a,t])}function m(e){let{value:a,tabValues:t}=e;return t.some((e=>e.value===a))}function h(e){let{queryString:a=!1,groupId:t}=e;const n=(0,s.k6)(),o=function(e){let{queryString:a=!1,groupId:t}=e;if("string"==typeof a)return a;if(!1===a)return null;if(!0===a&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:a,groupId:t});return[(0,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const a=new URLSearchParams(n.location.search);a.set(o,e),n.replace({...n.location,search:a.toString()})}),[o,n])]}function f(e){const{defaultValue:a,queryString:t=!1,groupId:n}=e,o=d(e),[i,s]=(0,r.useState)((()=>function(e){let{defaultValue:a,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(a){if(!m({value:a,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${a}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return a}const n=t.find((e=>e.default))??t[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:a,tabValues:o}))),[l,u]=h({queryString:t,groupId:n}),[p,f]=function(e){let{groupId:a}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(a),[n,o]=(0,c.Nk)(t);return[n,(0,r.useCallback)((e=>{t&&o.set(e)}),[t,o])]}({groupId:n}),k=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{k&&s(k)}),[k]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,o]),tabValues:o}}var k=t(72389);const g="tabList__CuJ",b="tabItem_LNqP";function y(e){let{className:a,block:t,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const a=e.currentTarget,t=c.indexOf(a),n=u[t].value;n!==s&&(p(a),l(n))},m=e=>{var a;let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const a=c.indexOf(e.currentTarget)+1;t=c[a]??c[0];break}case"ArrowLeft":{const a=c.indexOf(e.currentTarget)-1;t=c[a]??c[c.length-1];break}}null==(a=t)||a.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":t},a)},u.map((e=>{let{value:a,label:t,attributes:i}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===a?0:-1,"aria-selected":s===a,key:a,ref:e=>c.push(e),onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",b,null==i?void 0:i.className,{"tabs__item--active":s===a})}),t??a)})))}function v(e){let{lazy:a,children:t,selectedValue:n}=e;const o=(Array.isArray(t)?t:[t]).filter(Boolean);if(a){const e=o.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,a)=>(0,r.cloneElement)(e,{key:a,hidden:e.props.value!==n}))))}function w(e){const a=f(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g)},r.createElement(y,(0,n.Z)({},e,a)),r.createElement(v,(0,n.Z)({},e,a)))}function S(e){const a=(0,k.Z)();return r.createElement(w,(0,n.Z)({key:String(a)},e))}},45855:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>u,toc:()=>p});var n=t(87462),r=(t(67294),t(3905)),o=t(74866),i=t(85162);const s={id:"databse"},l="Managed Databases",u={unversionedId:"kusion/configuration-walkthrough/databse",id:"version-v0.10/kusion/configuration-walkthrough/databse",title:"Managed Databases",description:"The database attribute in the AppConfiguration instance is used to describe the specification for any databases needed for the application.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/6-database.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/databse",permalink:"/docs/kusion/configuration-walkthrough/databse",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/6-database.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"databse"},sidebar:"kusion",previous:{title:"Application Networking",permalink:"/docs/kusion/configuration-walkthrough/networking"},next:{title:"Secrets",permalink:"/docs/kusion/configuration-walkthrough/secret"}},c={},p=[{value:"Import",id:"import",level:2},{value:"Types of Database offerings",id:"types-of-database-offerings",level:2},{value:"Cloud Credentials and Permissions",id:"cloud-credentials-and-permissions",level:2},{value:"Configure Database",id:"configure-database",level:2},{value:"Provision a Cloud Database",id:"provision-a-cloud-database",level:3},{value:"AWS RDS Instance",id:"aws-rds-instance",level:4},{value:"AliCloud RDS Instance",id:"alicloud-rds-instance",level:4},{value:"Local Database",id:"local-database",level:3},{value:"Database Credentials",id:"database-credentials",level:2},{value:"Configure Network Access",id:"configure-network-access",level:2},{value:"Subnet ID",id:"subnet-id",level:3},{value:"Private Routing",id:"private-routing",level:3}],d={toc:p};function m(e){let{components:a,...t}=e;return(0,r.kt)("wrapper",(0,n.Z)({},d,t,{components:a,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"managed-databases"},"Managed Databases"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"database")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for any databases needed for the application."),(0,r.kt)("p",null,"You can currently have several databases with ",(0,r.kt)("strong",{parentName:"p"},"different database names")," for an application at the same time."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/configuration-walkthrough/overview#configuration-file-overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.accessories.mysql\nimport catalog.models.schema.v1.accessories.postgres\n")),(0,r.kt)("h2",{id:"types-of-database-offerings"},"Types of Database offerings"),(0,r.kt)("p",null,"As of version 0.10.0, Kusion supports the following database offerings on the cloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://aws.amazon.com/rds/"},"AWS")),(0,r.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/databases"},"AliCloud"))),(0,r.kt)("p",null,"More database types on more cloud vendors will be added in the future."),(0,r.kt)("p",null,"Alternatively, Kusion also supports creating a database at ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost")," for local testing needs. A local database is quicker to stand up and easier to manage. It also eliminates the need for an account and any relevant costs with the cloud providers in the case that a local testing environment is sufficient."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"You do need a local Kubernetes cluster to run the local database workloads. You can refer to ",(0,r.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/start/"},"Minikube")," or ",(0,r.kt)("a",{parentName:"p",href:"https://kind.sigs.k8s.io/docs/user/quick-start/"},"Kind")," to get started.\nTo see an end-to-end use case for standing up a local testing environment including a local database, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/getting-started/deliver-wordpress"},"Kusion Quickstart"),".")),(0,r.kt)("h2",{id:"cloud-credentials-and-permissions"},"Cloud Credentials and Permissions"),(0,r.kt)("p",null,"Kusion provisions databases on the cloud via ",(0,r.kt)("a",{parentName:"p",href:"https://www.terraform.io/"},"terraform")," providers. For it to create ",(0,r.kt)("em",{parentName:"p"},"any")," cloud resources, it requires a set of credentials that belongs to an account that has the appropriate write access so the terraform provider can be initialized properly."),(0,r.kt)("p",null,"For AWS, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export AWS_ACCESS_KEY_ID="xxxxxxxxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="xxxxxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,"For AliCloud, the environment variables needed:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'export ALICLOUD_ACCESS_KEY="xxxxxxxxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="xxxxxxxxx" # replace it with your SecretKey\n')),(0,r.kt)("p",null,"The user account that owns these credentials would need to have the proper permission policies attached to create databases and security groups. If you are using the cloud-managed policies, the policies needed to provision a database and configure firewall rules are listed below."),(0,r.kt)("p",null,"For AWS:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AmazonRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"For AliCloud:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"AliyunRDSFullAccess")," for creating and managing RDS instances")),(0,r.kt)("p",null,"Alternatively, you can use customer managed policies if the cloud provider built-in policies don't meet your needs. The list of permissions needed are in the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonRDSFullAccess.html#AmazonRDSFullAccess-json"},"AmazonRDSFullAccess Policy Document")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonVPCFullAccess.html"},"AmazonVPCFullAccess Policy Document"),". It will most likely be a subset of the permissions in the policy documents."),(0,r.kt)("h2",{id:"configure-database"},"Configure Database"),(0,r.kt)("h3",{id:"provision-a-cloud-database"},"Provision a Cloud Database"),(0,r.kt)("p",null,"Assuming the steps in the ",(0,r.kt)("a",{parentName:"p",href:"#cloud-credentials-and-permissions"},"Cloud Credentials and Permissions")," section is setup properly, you can now provision cloud databases via Kusion."),(0,r.kt)("h4",{id:"aws-rds-instance"},"AWS RDS Instance"),(0,r.kt)("p",null,"To provision an AWS RDS instance with MySQL v8.0 or PostgreSQL v14.0, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# MySQL configurations for AWS RDS\nmodules: \n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# PostgreSQL configurations for AWS RDS\nmodules: \n postgres: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,r.kt)("p",null,"For KCL configuration file declarations: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n database: {\n pgadmin: postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,r.kt)("p",null,"It's highly recommended to replace ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," and closely manage the whitelist of IPs that can access the database for security purposes. The ",(0,r.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," in the example above or if ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," is omitted altogether will allow connections from anywhere which would typically be a security bad practice."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," field determines the computation and memory capacity of the RDS instance. The ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.micro")," instance type in the example above represents the ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance class with a size of ",(0,r.kt)("inlineCode",{parentName:"p"},"micro"),". In the same ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3")," instance family there are also ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.small"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.medium"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"db.t3.2xlarge"),", etc."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Support"},"here"),"."),(0,r.kt)("p",null,"You can also adjust the storage capacity for the database instance by changing the ",(0,r.kt)("inlineCode",{parentName:"p"},"size")," field which is storage size measured in gigabytes. The minimum is 20. More details can be found ",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#Concepts.Storage.GeneralSSD"},"here"),"."),(0,r.kt)("h4",{id:"alicloud-rds-instance"},"AliCloud RDS Instance"),(0,r.kt)("p",null,"To provision an Alicloud RDS instance with MySQL or PostgreSQL, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". Note that AliCloud RDS has several additional fields such as ",(0,r.kt)("inlineCode",{parentName:"p"},"category"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting"),":"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# MySQL configurations for Alicloud RDS\nmodules: \n mysql: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# PostgreSQL configurations for Alicloud RDS\nmodules: \n postgres:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,r.kt)("p",null,"For KCL configuration file declarations: "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n database: {\n pgadmin: postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,r.kt)("p",null,"We will walkthrough ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," in the ",(0,r.kt)("a",{parentName:"p",href:"#configure-network-access"},"Configure Network Access")," section."),(0,r.kt)("p",null,"The full list of supported ",(0,r.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found in:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/primary-apsaradb-rds-for-mysql-instance-types#concept-2096487"},"MySQL instance types(x86)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/primary-apsaradb-rds-for-postgresql-instance-types#concept-2096578"},"PostgreSQL instance types"))),(0,r.kt)("h3",{id:"local-database"},"Local Database"),(0,r.kt)("p",null,"To deploy a local database with MySQL v8.0 or PostgreSQL v14.0:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n database: {\n wordpress: mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n'))),(0,r.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n database: {\n pgadmin: postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n }\n }\n}\n')))),(0,r.kt)("h2",{id:"database-credentials"},"Database Credentials"),(0,r.kt)("p",null,"There is no need to manage the database credentials manually. Kusion will automatically generate a random password, set it as the credential when creating the database, and then inject the hostname, username and password into the application runtime."),(0,r.kt)("p",null,"You have the option to BYO (Bring Your Own) username for the database credential by specifying the ",(0,r.kt)("inlineCode",{parentName:"p"},"username")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n mysql:\n default:\n # ...\n username: "my_username"\n')),(0,r.kt)("p",null,"You ",(0,r.kt)("strong",{parentName:"p"},"cannot")," bring your own password. The password will always be managed by Kusion automatically."),(0,r.kt)("p",null,"The database credentials are injected into the environment variables of the application container. You can access them via the following env vars:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"# env | grep KUSION_DB\nKUSION_DB_HOST_WORDPRESS_MYSQL=wordpress.xxxxxxxx.us-east-1.rds.amazonaws.com\nKUSION_DB_USERNAME_WORDPRESS_MYSQL=xxxxxxxxx\nKUSION_DB_PASSWORD_WORDPRESS_MYSQL=xxxxxxxxx\n")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"More details about the environment of database credentials injected by Kusion can be found at ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/postgres#credentials-and-connectivity"},"postgres credentials and connectivity"))),(0,r.kt)("p",null,"You can use these environment variables out of the box. Or most likely, your application might retrieve the connection details from a different set of environment variables. In that case, you can map the kusion environment variables to the ones expected by your application using the ",(0,r.kt)("inlineCode",{parentName:"p"},"$()")," expression. "),(0,r.kt)("p",null,"This example below will assign the value of ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_WORDPRESS_MYSQL")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_HOST"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_USERNAME_WORDPRESS_MYSQL")," into ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER"),", likewise for ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_PASSWORD_WORDPRESS_MYSQL")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_PASSWORD"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3-apache"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n }\n # ...\n }\n }\n # ...\n }\n database: {\n # ...\n }\n}\n')),(0,r.kt)("h2",{id:"configure-network-access"},"Configure Network Access"),(0,r.kt)("p",null,"You can also optionally configure the network access to the database as part of the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". This is highly recommended because it dramatically increases the security posture of your cloud environment in the means of least privilege principle."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"Database")," schema declares the list of network addresses that are allowed to access the database. The network addresses are in the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/what-is/cidr/"},"CIDR notation")," and can be either a private IP range (",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc1918"},"RFC-1918")," and ",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6598"},"RFC-6598")," address) or a public one."),(0,r.kt)("p",null,"If the database need to be accessed from a public location (which should most likely not be the case in a production environment), ",(0,r.kt)("inlineCode",{parentName:"p"},"securityIPs")," need to include the public IP address of the traffic source (For instance, if the RDS database needs to be accessed from your computer)."),(0,r.kt)("p",null,"To configure AWS RDS to restrict network access from a VPC with a CIDR of ",(0,r.kt)("inlineCode",{parentName:"p"},"10.0.1.0/24")," and a public IP of ",(0,r.kt)("inlineCode",{parentName:"p"},"103.192.227.125"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n mysql: \n default: \n cloud: aws\n # ...\n securityIPs: \n - "10.0.1.0/24"\n - "103.192.227.125/32"\n')),(0,r.kt)("p",null,"Depending on the cloud provider, the default behavior of the database firewall settings may differ if omitted."),(0,r.kt)("h3",{id:"subnet-id"},"Subnet ID"),(0,r.kt)("p",null,"On AWS, you have the option to launch the RDS instance inside a specific VPC if a ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is present in the application configuration. By default, if ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is not provided, the RDS will be created in the default VPC for that account. However, the recommendation is to self-manage your VPCs to provider better isolation from a network security perspective."),(0,r.kt)("p",null,"On AliCloud, the ",(0,r.kt)("inlineCode",{parentName:"p"},"subnetID")," is required. The concept of subnet maps to VSwitch in AliCloud."),(0,r.kt)("p",null,"To place the RDS instance into a specific VPC on Alicloud:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n mysql: \n default: \n cloud: alicloud\n # ...\n subnetID: "subnet-xxxxxxxxxxxxxxxx"\n')),(0,r.kt)("h3",{id:"private-routing"},"Private Routing"),(0,r.kt)("p",null,"There is an option to enforce private routing on certain cloud providers if both the workload and the database are running on the cloud."),(0,r.kt)("p",null,"On AliCloud, you can set the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". The database host generated will be a private FQDN that is only resolvable and accessible from within the AliCloud VPCs. Setting ",(0,r.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when ",(0,r.kt)("inlineCode",{parentName:"p"},"type")," is ",(0,r.kt)("inlineCode",{parentName:"p"},"aws")," is a no-op."),(0,r.kt)("p",null,"To enforce private routing on AliCloud:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules: \n mysql: \n default: \n cloud: alicloud\n # ...\n privateRouting: true\n")),(0,r.kt)("p",null,"Kusion will then generate a private FQDN and inject it into the application runtime as the environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_")," for the application to use. A complete list of Kusion-managed environment variables for mysql database can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"here"),"."),(0,r.kt)("p",null,"Otherwise when using the public FQDN to connect to a database from the workload, the route will depend on cloud provider's routing preference. The options are generally either:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Travel as far as possible on the cloud provider's global backbone network, or also referred to as cold potato routing, or"),(0,r.kt)("li",{parentName:"ul"},"Egress as early as possible to the public Internet and re-enter the cloud provider's datacenter later, or also referred to as hot potato routing")),(0,r.kt)("p",null,"The prior generally has better performance but is also more expensive."),(0,r.kt)("p",null,"You can find a good read on the ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/blogs/architecture/internet-routing-and-traffic-engineering/"},"AWS Blog")," or the ",(0,r.kt)("a",{parentName:"p",href:"https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/routing-preference-overview"},"Microsoft Learn"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8619d2de.06f3901b.js b/assets/js/8619d2de.06f3901b.js new file mode 100644 index 00000000000..df60344a31d --- /dev/null +++ b/assets/js/8619d2de.06f3901b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2527],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),s=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},p=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=s(n),m=o,f=p["".concat(c,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(f,r(r({ref:t},d),{},{components:n})):a.createElement(f,r({ref:t},d))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=p;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:o,r[1]=l;for(var s=2;s{n.d(t,{Z:()=>f});var a=n(87462),o=n(67294),i=n(86668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...o}=e;n>=0?t[n].children.push(o):a.push(o)})),a}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function s(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function u(e){const t=(0,o.useRef)(void 0),n=d();(0,o.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:o,minHeadingLevel:i,maxHeadingLevel:r}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let o=t;o<=n;o+=1)a.push(`h${o}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:i,maxHeadingLevel:r}),c=s(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(o),e.classList.add(o),t.current=e):e.classList.remove(o)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}function p(e){let{toc:t,className:n,linkClassName:a,isChild:i}=e;return t.length?o.createElement("ul",{className:i?void 0:n},t.map((e=>o.createElement("li",{key:e.id},o.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),o.createElement(p,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const m=o.memo(p);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:s,minHeadingLevel:d,maxHeadingLevel:p,...f}=e;const h=(0,i.L)(),v=d??h.tableOfContents.minHeadingLevel,g=p??h.tableOfContents.maxHeadingLevel,y=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,o.useMemo)((()=>l({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:v,maxHeadingLevel:g});return u((0,o.useMemo)((()=>{if(c&&s)return{linkClassName:c,linkActiveClassName:s,minHeadingLevel:v,maxHeadingLevel:g}}),[c,s,v,g])),o.createElement(m,(0,a.Z)({toc:y,className:n,linkClassName:c},f))}},76433:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>d,default:()=>h,frontMatter:()=>s,metadata:()=>u,toc:()=>m});var a=n(87462),o=n(67294),i=n(3905),r=n(93743);const l="tableOfContentsInline_prmo";function c(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return o.createElement("div",{className:l},o.createElement(r.Z,{toc:t,minHeadingLevel:n,maxHeadingLevel:a,className:"table-of-contents",linkClassName:null}))}const s={sidebar_position:2},d="Glossary",u={unversionedId:"kusion/concepts/glossary",id:"version-v0.9/kusion/concepts/glossary",title:"Glossary",description:"This page lists and defines technical terms that are widely used across KusionStack. Words such as Project, Stack, etc. can be overloaded in the technical community, so this page attempts to clarify their meaning in the context of KusionStack.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/glossary.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/glossary",permalink:"/docs/v0.9/kusion/concepts/glossary",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/glossary.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Architecture",permalink:"/docs/v0.9/kusion/concepts/arch"},next:{title:"How Kusion Works",permalink:"/docs/v0.9/kusion/concepts/kusion"}},p={},m=[{value:"Project",id:"project",level:2},{value:"Stack",id:"stack",level:2},{value:"Application",id:"application",level:2},{value:"High Level Schema",id:"high-level-schema",level:2}],f={toc:m};function h(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,a.Z)({},f,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"glossary"},"Glossary"),(0,i.kt)("p",null,"This page lists and defines technical terms that are widely used across KusionStack. Words such as ",(0,i.kt)("inlineCode",{parentName:"p"},"Project"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Stack"),", etc. can be overloaded in the technical community, so this page attempts to clarify their meaning in the context of KusionStack."),(0,i.kt)(c,{toc:m.filter((e=>2===e.level||4===e.level)),minHeadingLevel:2,maxHeadingLevel:4,mdxType:"TOCInline"}),(0,i.kt)("h2",{id:"project"},"Project"),(0,i.kt)("p",null,"A project in Kusion is any folder which contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file and is linked to a Git repository. Usually the mapping between project and repository is 1:1, also you can have multiple projects connected to a single repository (for example, a monorepo). And a project is composed of one or more applications."),(0,i.kt)("p",null,'The purpose of the "project" is to bundle application configurations and a refer to Git repository. Specifically, it includes logical configurations for internal pieces to orchestrate the application, and it bundles these configurations in a way to fit different roles, e.g. developer, SRE, to cover the whole life-cycle of application development.'),(0,i.kt)("p",null,"From the perspective of the application development life cycle, the configuration described by the project is decoupled from the application code, takes the immutable image as input, and users could conduct the operation, and maintenance of the application in an independent configuration code base."),(0,i.kt)("h2",{id:"stack"},"Stack"),(0,i.kt)("p",null,"A stack in Kusion is any folder which contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"stack.yaml")," file under belonging project directory. Stack provides a mechanism to isolate multiple deploys of same application, it's the target workspace that an application will be deployed to, also the the smallest operation unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of software development lifecycle e.g. development, staging, and production."),(0,i.kt)("p",null,"A project can have as many stacks as you need. By default, Kusion creates a default stack for you when you start a new project using the kusion init command."),(0,i.kt)("p",null,"Stacks let's you chose on which cluster your applications will be deployed to."),(0,i.kt)("h2",{id:"application"},"Application"),(0,i.kt)("p",null,"An application in Kusion is declared using the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," schema and represents a basic unit that is deployed. "),(0,i.kt)("p",null,"You can create multiple applications within a single project so they can share common configurations. This can be useful if you have several applications that are closely related, such as a backend system for content management and a frontend system for content delivery and display."),(0,i.kt)("h2",{id:"high-level-schema"},"High Level Schema"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"High_Level_Schema",src:n(4994).Z,width:"2390",height:"1487"})))}h.isMDXComponent=!0},4994:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/high-level-schema-ba34668ea6879003a582f15496c3ab6e.png"}}]); \ No newline at end of file diff --git a/assets/js/8619d2de.761efd9a.js b/assets/js/8619d2de.761efd9a.js deleted file mode 100644 index 13cd1dc84e6..00000000000 --- a/assets/js/8619d2de.761efd9a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2527],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},p=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(n),m=o,f=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(f,r(r({ref:t},d),{},{components:n})):a.createElement(f,r({ref:t},d))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=p;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,r[1]=l;for(var c=2;c{n.d(t,{Z:()=>f});var a=n(87462),o=n(67294),i=n(86668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...o}=e;n>=0?t[n].children.push(o):a.push(o)})),a}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function s(e){const t=e.getBoundingClientRect();return t.top===t.bottom?s(e.parentNode):t}function c(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>s(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function u(e){const t=(0,o.useRef)(void 0),n=d();(0,o.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:o,minHeadingLevel:i,maxHeadingLevel:r}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let o=t;o<=n;o+=1)a.push(`h${o}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:i,maxHeadingLevel:r}),s=c(l,{anchorTopOffset:n.current}),d=e.find((e=>s&&s.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(o),e.classList.add(o),t.current=e):e.classList.remove(o)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}function p(e){let{toc:t,className:n,linkClassName:a,isChild:i}=e;return t.length?o.createElement("ul",{className:i?void 0:n},t.map((e=>o.createElement("li",{key:e.id},o.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),o.createElement(p,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const m=o.memo(p);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:s="table-of-contents__link",linkActiveClassName:c,minHeadingLevel:d,maxHeadingLevel:p,...f}=e;const h=(0,i.L)(),v=d??h.tableOfContents.minHeadingLevel,g=p??h.tableOfContents.maxHeadingLevel,y=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,o.useMemo)((()=>l({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:v,maxHeadingLevel:g});return u((0,o.useMemo)((()=>{if(s&&c)return{linkClassName:s,linkActiveClassName:c,minHeadingLevel:v,maxHeadingLevel:g}}),[s,c,v,g])),o.createElement(m,(0,a.Z)({toc:y,className:n,linkClassName:s},f))}},76433:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>d,default:()=>h,frontMatter:()=>c,metadata:()=>u,toc:()=>m});var a=n(87462),o=n(67294),i=n(3905),r=n(93743);const l="tableOfContentsInline_prmo";function s(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return o.createElement("div",{className:l},o.createElement(r.Z,{toc:t,minHeadingLevel:n,maxHeadingLevel:a,className:"table-of-contents",linkClassName:null}))}const c={sidebar_position:2},d="Glossary",u={unversionedId:"kusion/concepts/glossary",id:"version-v0.9/kusion/concepts/glossary",title:"Glossary",description:"This page lists and defines technical terms that are widely used across KusionStack. Words such as Project, Stack, etc. can be overloaded in the technical community, so this page attempts to clarify their meaning in the context of KusionStack.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/glossary.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/glossary",permalink:"/docs/v0.9/kusion/concepts/glossary",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/glossary.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Architecture",permalink:"/docs/v0.9/kusion/concepts/arch"},next:{title:"How Kusion Works",permalink:"/docs/v0.9/kusion/concepts/kusion"}},p={},m=[{value:"Project",id:"project",level:2},{value:"Stack",id:"stack",level:2},{value:"Application",id:"application",level:2},{value:"High Level Schema",id:"high-level-schema",level:2}],f={toc:m};function h(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,a.Z)({},f,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"glossary"},"Glossary"),(0,i.kt)("p",null,"This page lists and defines technical terms that are widely used across KusionStack. Words such as ",(0,i.kt)("inlineCode",{parentName:"p"},"Project"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Stack"),", etc. can be overloaded in the technical community, so this page attempts to clarify their meaning in the context of KusionStack."),(0,i.kt)(s,{toc:m.filter((e=>2===e.level||4===e.level)),minHeadingLevel:2,maxHeadingLevel:4,mdxType:"TOCInline"}),(0,i.kt)("h2",{id:"project"},"Project"),(0,i.kt)("p",null,"A project in Kusion is any folder which contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file and is linked to a Git repository. Usually the mapping between project and repository is 1:1, also you can have multiple projects connected to a single repository (for example, a monorepo). And a project is composed of one or more applications."),(0,i.kt)("p",null,'The purpose of the "project" is to bundle application configurations and a refer to Git repository. Specifically, it includes logical configurations for internal pieces to orchestrate the application, and it bundles these configurations in a way to fit different roles, e.g. developer, SRE, to cover the whole life-cycle of application development.'),(0,i.kt)("p",null,"From the perspective of the application development life cycle, the configuration described by the project is decoupled from the application code, takes the immutable image as input, and users could conduct the operation, and maintenance of the application in an independent configuration code base."),(0,i.kt)("h2",{id:"stack"},"Stack"),(0,i.kt)("p",null,"A stack in Kusion is any folder which contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"stack.yaml")," file under belonging project directory. Stack provides a mechanism to isolate multiple deploys of same application, it's the target workspace that an application will be deployed to, also the the smallest operation unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of software development lifecycle e.g. development, staging, and production."),(0,i.kt)("p",null,"A project can have as many stacks as you need. By default, Kusion creates a default stack for you when you start a new project using the kusion init command."),(0,i.kt)("p",null,"Stacks let's you chose on which cluster your applications will be deployed to."),(0,i.kt)("h2",{id:"application"},"Application"),(0,i.kt)("p",null,"An application in Kusion is declared using the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," schema and represents a basic unit that is deployed. "),(0,i.kt)("p",null,"You can create multiple applications within a single project so they can share common configurations. This can be useful if you have several applications that are closely related, such as a backend system for content management and a frontend system for content delivery and display."),(0,i.kt)("h2",{id:"high-level-schema"},"High Level Schema"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"High_Level_Schema",src:n(4994).Z,width:"2390",height:"1487"})))}h.isMDXComponent=!0},4994:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/high-level-schema-ba34668ea6879003a582f15496c3ab6e.png"}}]); \ No newline at end of file diff --git a/assets/js/86764c80.a8f97a1b.js b/assets/js/86764c80.55f9b4ab.js similarity index 58% rename from assets/js/86764c80.a8f97a1b.js rename to assets/js/86764c80.55f9b4ab.js index 54bbbc73f11..9302c59ff84 100644 --- a/assets/js/86764c80.a8f97a1b.js +++ b/assets/js/86764c80.55f9b4ab.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4974],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={},i="Controller Mesh",l={unversionedId:"ctrlmesh/intro/intro",id:"version-v0.9/ctrlmesh/intro/intro",title:"Controller Mesh",description:"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.",source:"@site/versioned_docs/version-v0.9/ctrlmesh/intro/intro.md",sourceDirName:"ctrlmesh/intro",slug:"/ctrlmesh/intro/",permalink:"/docs/v0.9/ctrlmesh/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/intro/intro.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",next:{title:"Concepts",permalink:"/docs/v0.9/ctrlmesh/concepts/"}},s={},c=[{value:"Key Features",id:"key-features",level:2},{value:"Architecture",id:"architecture",level:2}],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"controller-mesh"},"Controller Mesh"),(0,o.kt)("p",null,"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better."),(0,o.kt)("h2",{id:"key-features"},"Key Features"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Sharding"),": Through relevant configurations, Kubernetes single-point deployed operator applications can be flexibly shard deployed."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Canary upgrade"),": Depends on sharding, the controller instances can be updated in canary progress instead of updated in one time."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Circuit breaker and rate limiter"),": Not only Kubernetes operation requests, but also other external operation requests."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Multicluster routing and sharding")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"And more"),": Fault injection and Observability (Todo).")),(0,o.kt)("h2",{id:"architecture"},"Architecture"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"800",src:r(29871).Z})),(0,o.kt)("p",null,"Visit ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/ctrlmesh/started/install"},"Installation")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/ctrlmesh/started/try"},"Quick Start"),"."))}u.isMDXComponent=!0},29871:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/mesh-arch-2-d82d2166bfeff6b5e56364fda483e9c2.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4974],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,f=d["".concat(s,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={},i="Controller Mesh",l={unversionedId:"ctrlmesh/intro/intro",id:"version-v0.9/ctrlmesh/intro/intro",title:"Controller Mesh",description:"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.",source:"@site/versioned_docs/version-v0.9/ctrlmesh/intro/intro.md",sourceDirName:"ctrlmesh/intro",slug:"/ctrlmesh/intro/",permalink:"/docs/v0.9/ctrlmesh/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/intro/intro.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",next:{title:"Concepts",permalink:"/docs/v0.9/ctrlmesh/concepts/"}},s={},c=[{value:"Key Features",id:"key-features",level:2},{value:"Architecture",id:"architecture",level:2}],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"controller-mesh"},"Controller Mesh"),(0,o.kt)("p",null,"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better."),(0,o.kt)("h2",{id:"key-features"},"Key Features"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Sharding"),": Through relevant configurations, Kubernetes single-point deployed operator applications can be flexibly shard deployed."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Canary upgrade"),": Depends on sharding, the controller instances can be updated in canary progress instead of updated in one time."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Circuit breaker and rate limiter"),": Not only Kubernetes operation requests, but also other external operation requests."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Multicluster routing and sharding")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"And more"),": Fault injection and Observability (Todo).")),(0,o.kt)("h2",{id:"architecture"},"Architecture"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"800",src:r(29871).Z})),(0,o.kt)("p",null,"Visit ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/ctrlmesh/started/install"},"Installation")," or ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/ctrlmesh/started/try"},"Quick Start"),"."))}u.isMDXComponent=!0},29871:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/mesh-arch-2-d82d2166bfeff6b5e56364fda483e9c2.png"}}]); \ No newline at end of file diff --git a/assets/js/87668920.4aa96a90.js b/assets/js/87668920.4aa96a90.js new file mode 100644 index 00000000000..de496018c2c --- /dev/null +++ b/assets/js/87668920.4aa96a90.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9243],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return n?o.createElement(h,a(a({ref:t},p),{},{components:n})):o.createElement(h,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:2},a="PodOpsLifecycle",l={unversionedId:"operating/concepts/podopslifecycle",id:"operating/concepts/podopslifecycle",title:"PodOpsLifecycle",description:"Background",source:"@site/docs/operating/concepts/podopslifecycle.md",sourceDirName:"operating/concepts",slug:"/operating/concepts/podopslifecycle",permalink:"/docs/next/operating/concepts/podopslifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/concepts/podopslifecycle.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/next/operating/started/demo-graceful-operation"},next:{title:"CollaSet",permalink:"/docs/next/operating/manuals/collaset"}},c={},s=[{value:"Background",id:"background",level:2},{value:"Introduction",id:"introduction",level:2},{value:"Developer's Guide",id:"developers-guide",level:2},{value:"Operation Controller",id:"operation-controller",level:3},{value:"Pod Cooperation Controller",id:"pod-cooperation-controller",level:3},{value:"Key Features",id:"key-features",level:2},{value:"Concurrency Support",id:"concurrency-support",level:3}],p={toc:s};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"podopslifecycle"},"PodOpsLifecycle"),(0,r.kt)("h2",{id:"background"},"Background"),(0,r.kt)("p",null,"Kubernetes provides a set of default controllers for workload management, such as StatefulSet, Deployment, and DaemonSet, which are responsible for Pod operations.\nMeanwhile, application users may also have some services outside the Kubernetes cluster that are closely related to the Pod Lifecycle, including traffic routing, service discovery, or alert monitoring.\nHowever, they face challenges in participating in the operational lifecycle of a Pod, even if they are connected to Kubernetes by developing a controller that watches the Pods."),(0,r.kt)("p",null,"PodOpsLifecycle aims to offer Kubernetes administrators and developers finer-grained control over the entire lifecycle of a Pod.\nIt enables developers to execute necessary actions before, during, and after specific phases of a Pod operation.\nFor instance, removing the Pod's IP from the traffic route before initiating the Pod operation, performing the actual Pod operations, and adding it back after the Pod operation is completed to achieve a smooth and graceful Pod operation, and prevent any traffic loss."),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"In PodOpsLifecycle, participants are classified into two roles: ",(0,r.kt)("inlineCode",{parentName:"p"},"operation controllers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"cooperation controllers"),"."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operation controllers")," are responsible for operating Pods, such as Deployments and StatefulSets from Kubernetes, and CollaSets from Operating which intend to scale, update, or recreate Pods."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Cooperation controllers")," are sensitive with Pod status. They handle resources or configurations around Pods, which may include traffic controller, alert monitoring controller, etc. These controllers typically reconcile Kubernetes resources around Pods with external services, such as sync Pod IPs with the LB provider, or maintaining Pods' metadata with application monitoring system.")),(0,r.kt)("p",null,"The two types of controllers do not need to be aware of each other. All controllers are organized by PodOpsLifecycle. Additionally, KusionStack Operating introduces extra phases around the native Kubernetes Pod Lifecycle: ServiceAvailable, Preparing, and Completing."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle",src:n(79164).Z,width:"1500",height:"978"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Completing"),": After a Pod is created or updated and becomes ready, Operating marks its PodOpsLifecycle as the ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing")," phase. During this phase, the Pod is in a ready condition, prompting cooperation controllers to perform actions such as registering the Pod IP in the traffic route. Once all cooperation controllers complete their tasks, Operating sets the PodOpsLifecycle to the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"ServiceAvailable"),": This phase indicates that the Pod is in a normal state and ready to serve. If everything goes smoothly, the Pod remains in the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase until the next operation."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Preparing"),": When an operation controller needs to operate the Pod, it triggers a new PodOpsLifecycle. The Pod then transitions from the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase to the ",(0,r.kt)("inlineCode",{parentName:"li"},"Preparing")," phase. During this phase, the Pod is initially marked as Unready by setting ReadinessGate to false. All cooperation controllers then begin preparing tasks, such as removing the Pod's IP from the traffic route. After completing these tasks, the Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operating"),": If a Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase, it is expected to accept any kind of operation without any damage, including recreation, scaling-in, upgrading, etc. Operation controllers are permitted to apply any changes to this Pod. Once all these operations are completed, the Pod advances to the next phase \u2014 ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing"),", and the PodOpsLifecycle continues.")),(0,r.kt)("p",null,"The PodOpsLifecycle detail and the relationship with Kubernetes native Pod Lifecycle is showed by following sequence diagram."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle-sequence-diagram",src:n(57590).Z,width:"1500",height:"694"})),(0,r.kt)("h2",{id:"developers-guide"},"Developer's Guide"),(0,r.kt)("p",null,"This section introduces how to develop operation controllers and cooperation controllers to interact with PodOpsLifecycle."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The operation controller is responsible for a set of Pod operation tasks. KusionStack Operating has already provided various types of operation controllers. Users only need to develop a new operation controller if a new kind of Pod operation needs to be added."),(0,r.kt)("li",{parentName:"ul"},"The cooperation controller participates in PodOpsLifecycle before and after operating on a Pod, such as the Traffic controller, alert monitoring controller, and other controllers responsible for maintaining the Pod and application status. Users should develop a new cooperation controller only when there is a new type of service or status around the Pod that needs to be maintained, such as integrating with a new traffic provider.")),(0,r.kt)("h3",{id:"operation-controller"},"Operation Controller"),(0,r.kt)("p",null,"The operation controller is responsible for Pod operations. The tasks that an operation controller needs to perform during PodOpsLifecycle include triggering a PodOpsLifecycle, checking whether the Pod has entered the Operating phase, performing Pod operations, and marking Pod operations as finished. These actions interacting with PodOpsLifecycle are provided in the package ",(0,r.kt)("inlineCode",{parentName:"p"},"kusionstack.io/operating/pkg/controllers/utils/podopslifecycle/utils.go"),"."),(0,r.kt)("p",null,"A simple operation controller reconcile method would look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n "sigs.k8s.io/controller-runtime/pkg/client"\n \n "kusionstack.io/operating/pkg/controllers/utils/podopslifecycle"\n)\n\nvar operationAdapter = &OperationOpsLifecycleAdapter{}\n\ntype OperationOpsLifecycleAdapter struct {\n}\n\n// GetID indicates ID of the PodOpsLifecycle\nfunc (a *OperationOpsLifecycleAdapter) GetID() string {\n return "new-id"\n}\n\n// GetType indicates type for this Operation Controller\nfunc (a *OperationOpsLifecycleAdapter) GetType() podopslifecycle.OperationType {\n return "new-type"\n}\n\n// AllowMultiType indicates whether multiple IDs which have the same Type are allowed\nfunc (a *OperationOpsLifecycleAdapter) AllowMultiType() bool {\n return true\n}\n\n// WhenBegin is a hook, which will be executed when begin a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenBegin(pod client.Object) (bool, error) {\n return false, nil\n}\n\n// WhenFinish is a hook, which will be executed when finish a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenFinish(pod client.Object) (bool, error) {\n return false, nil\n}\n\n......\nfunc (r *PodOperationReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n // check if the Pod needs operation\n if !r.needOperation(pod) {\n return reconcile.Result{}, nil\n }\n\n // if PodOpsLifecycle has not been triggered, trigger it\n if !podopslifecycle.IsDuringOps(OpsLifecycleAdapter, pod) {\n if updated, err := podopslifecycle.Begin(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n } else if updated {\n return reconcile.Result{}, nil\n }\n }\n\n // waiting until Pod enters operating phase\n if _, allowed := podopslifecycle.AllowOps(operationAdapter, 0, pod); !allowed {\n return reconcile.Result{}, nil\n }\n\n // do operation works\n if completed := r.doPodOperation(pod); !completed {\n return reconcile.Result{}, nil\n }\n\n // after operation works completed, finish operating phase to continue PodOpsLifecycle\n if _, err := podopslifecycle.Finish(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n }\n}\n')),(0,r.kt)("h3",{id:"pod-cooperation-controller"},"Pod Cooperation Controller"),(0,r.kt)("p",null,"There are two ways to develop a cooperation controller.\nOne way is to develop a controller using the controller runtime and adhering to some conventions of PodOpsLifecycle and Kubernetes.\nAnother way is to take the use of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist"},"ResourceConsist")," framework provided by KusionStack, which can be referenced from its ",(0,r.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/resourceconsist"},"documentation"),"."),(0,r.kt)("p",null,"The following outlines the first approach."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "k8s.io/apimachinery/pkg/api/errors"\n k8spod "k8s.io/kubernetes/pkg/api/v1/pod/util.go"\n "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n\n operatingapps "kusionstack.io/operating/apis/apps/v1alpha1"\n)\n\nconst (\n // Finalizer needs to have prefix: `prot.podopslifecycle.kusionstack.io`.\n // KusionStack Operating keeps this prefix back-compatible,\n // so that it can be hard code to decouple with KusionStack Operating.\n finalizerPrefix = operatingapps.PodOperationProtectionFinalizerPrefix\n\n protectionFinalizer = finalizerPrefix + "/" + "unique-id"\n)\n\n......\nfunc (r *PodResourceReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n if k8spod.IsPodReady(pod) {\n // do resource reconcile like add Pod IP to traffic route\n r.trafficOn(pod.status.PodIP)\n // It is important to add a unique finalizer on this Pod\n return reconcile.Result{}, r.addFinalizer(ctx, pod, protectionFinalizer)\n }\n\n if !k8spod.IsPodReady(pod) {\n // do resource reconcile like remove Pod IP from traffic route\n r.trafficOff(pod.status.PodIP)\n // It is important to remove the unique finalizer from this Pod\n return reconcile.Result{}, r.removeFinalizer(ctx, pod, protectionFinalizer)\n }\n}\n\nfunc (r *PodResourceReconciler) addFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.AddFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n\nfunc (r *PodResourceReconciler) removeFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if !controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.RemoveFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n')),(0,r.kt)("h2",{id:"key-features"},"Key Features"),(0,r.kt)("h3",{id:"concurrency-support"},"Concurrency Support"),(0,r.kt)("p",null,"PodOpsLifecycle in KusionStack Operating supports concurrency.\nIt means PodOpsLifecycle is able to organize and track multi controllers operating the same pod at the same time.\nFor example, when a controller is going to update Pod, other controllers are allowed to do other operations at the same time, like delete, restart, recreate it,\nalthough the result may not be meaningful."))}d.isMDXComponent=!0},57590:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-sequence-diagram-47bc9fbcab1c539cb11e8bc5f3987cf5.png"},79164:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-6ed0948e3faaf60bcd3ddb5c572038cf.png"}}]); \ No newline at end of file diff --git a/assets/js/87668920.57da924c.js b/assets/js/87668920.57da924c.js deleted file mode 100644 index ab96b445490..00000000000 --- a/assets/js/87668920.57da924c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9243],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(n),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return n?o.createElement(h,a(a({ref:t},p),{},{components:n})):o.createElement(h,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:2},a="PodOpsLifecycle",l={unversionedId:"operating/concepts/podopslifecycle",id:"operating/concepts/podopslifecycle",title:"PodOpsLifecycle",description:"Background",source:"@site/docs/operating/concepts/podopslifecycle.md",sourceDirName:"operating/concepts",slug:"/operating/concepts/podopslifecycle",permalink:"/docs/next/operating/concepts/podopslifecycle",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/concepts/podopslifecycle.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"Using KusionStack Operating to operate Pods gracefully",permalink:"/docs/next/operating/started/demo-graceful-operation"},next:{title:"CollaSet",permalink:"/docs/next/operating/manuals/collaset"}},c={},s=[{value:"Background",id:"background",level:2},{value:"Introduction",id:"introduction",level:2},{value:"Developer's Guide",id:"developers-guide",level:2},{value:"Operation Controller",id:"operation-controller",level:3},{value:"Pod Cooperation Controller",id:"pod-cooperation-controller",level:3},{value:"Key Features",id:"key-features",level:2},{value:"Concurrency Support",id:"concurrency-support",level:3}],p={toc:s};function d(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"podopslifecycle"},"PodOpsLifecycle"),(0,r.kt)("h2",{id:"background"},"Background"),(0,r.kt)("p",null,"Kubernetes provides a set of default controllers for workload management, such as StatefulSet, Deployment, and DaemonSet, which are responsible for Pod operations.\nMeanwhile, application users may also have some services outside the Kubernetes cluster that are closely related to the Pod Lifecycle, including traffic routing, service discovery, or alert monitoring.\nHowever, they face challenges in participating in the operational lifecycle of a Pod, even if they are connected to Kubernetes by developing a controller that watches the Pods."),(0,r.kt)("p",null,"PodOpsLifecycle aims to offer Kubernetes administrators and developers finer-grained control over the entire lifecycle of a Pod.\nIt enables developers to execute necessary actions before, during, and after specific phases of a Pod operation.\nFor instance, removing the Pod's IP from the traffic route before initiating the Pod operation, performing the actual Pod operations, and adding it back after the Pod operation is completed to achieve a smooth and graceful Pod operation, and prevent any traffic loss."),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"In PodOpsLifecycle, participants are classified into two roles: ",(0,r.kt)("inlineCode",{parentName:"p"},"operation controllers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"cooperation controllers"),"."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operation controllers")," are responsible for operating Pods, such as Deployments and StatefulSets from Kubernetes, and CollaSets from Operating which intend to scale, update, or recreate Pods."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Cooperation controllers")," are sensitive with Pod status. They handle resources or configurations around Pods, which may include traffic controller, alert monitoring controller, etc. These controllers typically reconcile Kubernetes resources around Pods with external services, such as sync Pod IPs with the LB provider, or maintaining Pods' metadata with application monitoring system.")),(0,r.kt)("p",null,"The two types of controllers do not need to be aware of each other. All controllers are organized by PodOpsLifecycle. Additionally, KusionStack Operating introduces extra phases around the native Kubernetes Pod Lifecycle: ServiceAvailable, Preparing, and Completing."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle",src:n(79164).Z,width:"1500",height:"978"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Completing"),": After a Pod is created or updated and becomes ready, Operating marks its PodOpsLifecycle as the ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing")," phase. During this phase, the Pod is in a ready condition, prompting cooperation controllers to perform actions such as registering the Pod IP in the traffic route. Once all cooperation controllers complete their tasks, Operating sets the PodOpsLifecycle to the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"ServiceAvailable"),": This phase indicates that the Pod is in a normal state and ready to serve. If everything goes smoothly, the Pod remains in the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase until the next operation."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Preparing"),": When an operation controller needs to operate the Pod, it triggers a new PodOpsLifecycle. The Pod then transitions from the ",(0,r.kt)("inlineCode",{parentName:"li"},"ServiceAvailable")," phase to the ",(0,r.kt)("inlineCode",{parentName:"li"},"Preparing")," phase. During this phase, the Pod is initially marked as Unready by setting ReadinessGate to false. All cooperation controllers then begin preparing tasks, such as removing the Pod's IP from the traffic route. After completing these tasks, the Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Operating"),": If a Pod enters the ",(0,r.kt)("inlineCode",{parentName:"li"},"Operating")," phase, it is expected to accept any kind of operation without any damage, including recreation, scaling-in, upgrading, etc. Operation controllers are permitted to apply any changes to this Pod. Once all these operations are completed, the Pod advances to the next phase \u2014 ",(0,r.kt)("inlineCode",{parentName:"li"},"Completing"),", and the PodOpsLifecycle continues.")),(0,r.kt)("p",null,"The PodOpsLifecycle detail and the relationship with Kubernetes native Pod Lifecycle is showed by following sequence diagram."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"pod-ops-lifecycle-sequence-diagram",src:n(57590).Z,width:"1500",height:"694"})),(0,r.kt)("h2",{id:"developers-guide"},"Developer's Guide"),(0,r.kt)("p",null,"This section introduces how to develop operation controllers and cooperation controllers to interact with PodOpsLifecycle."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The operation controller is responsible for a set of Pod operation tasks. KusionStack Operating has already provided various types of operation controllers. Users only need to develop a new operation controller if a new kind of Pod operation needs to be added."),(0,r.kt)("li",{parentName:"ul"},"The cooperation controller participates in PodOpsLifecycle before and after operating on a Pod, such as the Traffic controller, alert monitoring controller, and other controllers responsible for maintaining the Pod and application status. Users should develop a new cooperation controller only when there is a new type of service or status around the Pod that needs to be maintained, such as integrating with a new traffic provider.")),(0,r.kt)("h3",{id:"operation-controller"},"Operation Controller"),(0,r.kt)("p",null,"The operation controller is responsible for Pod operations. The tasks that an operation controller needs to perform during PodOpsLifecycle include triggering a PodOpsLifecycle, checking whether the Pod has entered the Operating phase, performing Pod operations, and marking Pod operations as finished. These actions interacting with PodOpsLifecycle are provided in the package ",(0,r.kt)("inlineCode",{parentName:"p"},"kusionstack.io/operating/pkg/controllers/utils/podopslifecycle/utils.go"),"."),(0,r.kt)("p",null,"A simple operation controller reconcile method would look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n "sigs.k8s.io/controller-runtime/pkg/client"\n \n "kusionstack.io/operating/pkg/controllers/utils/podopslifecycle"\n)\n\nvar operationAdapter = &OperationOpsLifecycleAdapter{}\n\ntype OperationOpsLifecycleAdapter struct {\n}\n\n// GetID indicates ID of the PodOpsLifecycle\nfunc (a *OperationOpsLifecycleAdapter) GetID() string {\n return "new-id"\n}\n\n// GetType indicates type for this Operation Controller\nfunc (a *OperationOpsLifecycleAdapter) GetType() podopslifecycle.OperationType {\n return "new-type"\n}\n\n// AllowMultiType indicates whether multiple IDs which have the same Type are allowed\nfunc (a *OperationOpsLifecycleAdapter) AllowMultiType() bool {\n return true\n}\n\n// WhenBegin is a hook, which will be executed when begin a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenBegin(pod client.Object) (bool, error) {\n return false, nil\n}\n\n// WhenFinish is a hook, which will be executed when finish a lifecycle\nfunc (a *OperationOpsLifecycleAdapter) WhenFinish(pod client.Object) (bool, error) {\n return false, nil\n}\n\n......\nfunc (r *PodOperationReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n // check if the Pod needs operation\n if !r.needOperation(pod) {\n return reconcile.Result{}, nil\n }\n\n // if PodOpsLifecycle has not been triggered, trigger it\n if !podopslifecycle.IsDuringOps(OpsLifecycleAdapter, pod) {\n if updated, err := podopslifecycle.Begin(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n } else if updated {\n return reconcile.Result{}, nil\n }\n }\n\n // waiting until Pod enters operating phase\n if _, allowed := podopslifecycle.AllowOps(operationAdapter, 0, pod); !allowed {\n return reconcile.Result{}, nil\n }\n\n // do operation works\n if completed := r.doPodOperation(pod); !completed {\n return reconcile.Result{}, nil\n }\n\n // after operation works completed, finish operating phase to continue PodOpsLifecycle\n if _, err := podopslifecycle.Finish(r, operationAdapter, pod); err != nil {\n return reconcile.Result{}, err\n }\n}\n')),(0,r.kt)("h3",{id:"pod-cooperation-controller"},"Pod Cooperation Controller"),(0,r.kt)("p",null,"There are two ways to develop a cooperation controller.\nOne way is to develop a controller using the controller runtime and adhering to some conventions of PodOpsLifecycle and Kubernetes.\nAnother way is to take the use of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist"},"ResourceConsist")," framework provided by KusionStack, which can be referenced from its ",(0,r.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/resourceconsist"},"documentation"),"."),(0,r.kt)("p",null,"The following outlines the first approach."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "context"\n\n corev1 "k8s.io/api/core/v1"\n "k8s.io/apimachinery/pkg/api/errors"\n k8spod "k8s.io/kubernetes/pkg/api/v1/pod/util.go"\n "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"\n "sigs.k8s.io/controller-runtime/pkg/reconcile"\n\n operatingapps "kusionstack.io/operating/apis/apps/v1alpha1"\n)\n\nconst (\n // Finalizer needs to have prefix: `prot.podopslifecycle.kusionstack.io`.\n // KusionStack Operating keeps this prefix back-compatible,\n // so that it can be hard code to decouple with KusionStack Operating.\n finalizerPrefix = operatingapps.PodOperationProtectionFinalizerPrefix\n\n protectionFinalizer = finalizerPrefix + "/" + "unique-id"\n)\n\n......\nfunc (r *PodResourceReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n // get the Pod\n pod := &corev1.Pod{}\n if err := r.Get(ctx, req.NamespacedName, pod); err != nil {\n if !errors.IsNotFound(err) {\n return reconcile.Result{}, err\n }\n return reconcile.Result{}, nil\n }\n\n if k8spod.IsPodReady(pod) {\n // do resource reconcile like add Pod IP to traffic route\n r.trafficOn(pod.status.PodIP)\n // It is important to add a unique finalizer on this Pod\n return reconcile.Result{}, r.addFinalizer(ctx, pod, protectionFinalizer)\n }\n\n if !k8spod.IsPodReady(pod) {\n // do resource reconcile like remove Pod IP from traffic route\n r.trafficOff(pod.status.PodIP)\n // It is important to remove the unique finalizer from this Pod\n return reconcile.Result{}, r.removeFinalizer(ctx, pod, protectionFinalizer)\n }\n}\n\nfunc (r *PodResourceReconciler) addFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.AddFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n\nfunc (r *PodResourceReconciler) removeFinalizer(ctx context.Context, pod *corev1.Pod, finalizer string) error {\n if !controllerutil.ContainsFinalizer(pod, finalizer) {\n return nil\n }\n\n controllerutil.RemoveFinalizer(pod, finalizer)\n return r.Update(ctx, pod)\n}\n')),(0,r.kt)("h2",{id:"key-features"},"Key Features"),(0,r.kt)("h3",{id:"concurrency-support"},"Concurrency Support"),(0,r.kt)("p",null,"PodOpsLifecycle in KusionStack Operating supports concurrency.\nIt means PodOpsLifecycle is able to organize and track multi controllers operating the same pod at the same time.\nFor example, when a controller is going to update Pod, other controllers are allowed to do other operations at the same time, like delete, restart, recreate it,\nalthough the result may not be meaningful."))}d.isMDXComponent=!0},57590:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-sequence-diagram-47bc9fbcab1c539cb11e8bc5f3987cf5.png"},79164:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/pod-ops-lifecycle-6ed0948e3faaf60bcd3ddb5c572038cf.png"}}]); \ No newline at end of file diff --git a/assets/js/87ed36d5.0da94ca9.js b/assets/js/87ed36d5.0da94ca9.js deleted file mode 100644 index 56f4ba8d81b..00000000000 --- a/assets/js/87ed36d5.0da94ca9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7494],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,r(r({ref:t},d),{},{components:n})):a.createElement(k,r({ref:t},d))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(87462),i=(n(67294),n(3905));const o={sidebar_position:2},r="KCL Basics",l={unversionedId:"kusion/config-walkthrough/kcl_basics",id:"version-v0.9/kusion/config-walkthrough/kcl_basics",title:"KCL Basics",description:"Table of Content",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/kcl_basics.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/kcl_basics",permalink:"/docs/v0.9/kusion/config-walkthrough/kcl_basics",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/kcl_basics.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Configuration File Overview",permalink:"/docs/v0.9/kusion/config-walkthrough/overview"},next:{title:"Base and Override",permalink:"/docs/v0.9/kusion/config-walkthrough/base_override"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Variable assignments",id:"variable-assignments",level:2},{value:"Common built-in types",id:"common-built-in-types",level:2},{value:"Lists and maps",id:"lists-and-maps",level:2},{value:"Conditional statements",id:"conditional-statements",level:2},{value:"The : and = operator",id:"the--and--operator",level:2},{value:"Advanced KCL capabilities",id:"advanced-kcl-capabilities",level:2}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kcl-basics"},"KCL Basics"),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#variable-assignments"},"Variable assignments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#common-built-in-types"},"Common built-in types")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#lists-and-maps"},"Lists and maps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#conditional-statements"},"Conditional statements")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#the--and--operator"},"The : and = operator")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#advanced-kcl-capabilities"},"Advanced KCL capabilities"))),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h2",{id:"variable-assignments"},"Variable assignments"),(0,i.kt)("p",null,"There are two ways to initialize a variable in KCL. You can either use the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," operator or the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss the difference between them in ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},"this section later"),"."),(0,i.kt)("p",null,"Here are the two ways to create a variable and initialize it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'foo = "Foo" # Declare a variable named `foo` and its value is a string literal "Foo"\nbar: "Bar" # Declare a variable named `bar` and its value is a string literal "Bar"\n')),(0,i.kt)("p",null,"You will be able to override a variable assignment via the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss this in depth in the ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},(0,i.kt)("inlineCode",{parentName:"a"},":")," and ",(0,i.kt)("inlineCode",{parentName:"a"},"=")," operator section"),"."),(0,i.kt)("h2",{id:"common-built-in-types"},"Common built-in types"),(0,i.kt)("p",null,"KCL supports ",(0,i.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"float"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"bool")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"string")," as the built-in types."),(0,i.kt)("p",null,"Other types are defined in the packages that are imported into the application configuration files. One such example would be the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object (or ",(0,i.kt)("inlineCode",{parentName:"p"},"Container"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Probe"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," object, etc) that are defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," repository."),(0,i.kt)("h2",{id:"lists-and-maps"},"Lists and maps"),(0,i.kt)("p",null,"Lists are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"[]")," notation.\nAn example of lists:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"list0 = [1, 2, 3]\nlist1 = [4, 5, 6]\njoined_list = list0 + list1 # [1, 2, 3, 4, 5, 6]\n")),(0,i.kt)("p",null,"Maps are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," notation.\nAn example of maps:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"a = {\"one\" = 1, \"two\" = 2, \"three\" = 3}\nb = {'one' = 1, 'two' = 2, 'three' = 3}\nassert a == b # True\nassert len(a) == 3 # True\n")),(0,i.kt)("h2",{id:"conditional-statements"},"Conditional statements"),(0,i.kt)("p",null,"You can also use basic control flow statements when writing the configuration file."),(0,i.kt)("p",null,"An example that sets the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," conditionally based on the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"containers.myapp.resources.cpu"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1 if containers.myapp.resources.cpu == "500m" else 2\n }\n}\n')),(0,i.kt)("p",null,"For more details on KCL's control flow statements, please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#control-flow-statements"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"the--and--operator"},"The ",(0,i.kt)("inlineCode",{parentName:"h2"},":")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"=")," operator"),(0,i.kt)("p",null,"You might have noticed there is a mixed usage of the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," in the samples above."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"TLDR: The recommendation is to use ",(0,i.kt)("inlineCode",{parentName:"strong"},":")," in the common configurations, and ",(0,i.kt)("inlineCode",{parentName:"strong"},"=")," for override in the environment-specific configurations."))),(0,i.kt)("p",null,"In KCL:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},":")," represents a union-ed value assignment. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: T E"),", the value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will be merged and union-ed into the element value."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"=")," represents a value override. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = T E"),", The value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will override the ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier")," attribute value.")),(0,i.kt)("p",null,"Let's take a look at an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is one configuration that will be merged.\nconfig: Config {\n data.d1 = 1\n}\n# This is another configuration that will be merged.\nconfig: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The above is equivalent to the snippet below since the two expressions for ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," get merged/union-ed into one:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d1 = 1\n data.d2 = 1\n}\n")),(0,i.kt)("p",null,"whereas using the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operators will result in a different outcome:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is first configuration.\nconfig = Config {\n data.d1 = 1\n}\n# This is second configuration that will override the prior one.\nconfig = Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The config above results in:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict with each other."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"data0 = {id: 1} | {id: 2} # Error\uff1aconflicting values between {'id': 2} and {'id': 1}\ndata1 = {id: 1} | {id = 2} # Ok, the value of `data` is {\"id\": 2}\n")),(0,i.kt)("p",null,"More about ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator can be found in the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#config-operations"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"advanced-kcl-capabilities"},"Advanced KCL capabilities"),(0,i.kt)("p",null,"For more advanced KCL capabilities, please visit the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/87ed36d5.53343c6e.js b/assets/js/87ed36d5.53343c6e.js new file mode 100644 index 00000000000..532bca5e5ab --- /dev/null +++ b/assets/js/87ed36d5.53343c6e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7494],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,r(r({ref:t},d),{},{components:n})):a.createElement(k,r({ref:t},d))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(87462),i=(n(67294),n(3905));const o={sidebar_position:2},r="KCL Basics",l={unversionedId:"kusion/config-walkthrough/kcl_basics",id:"version-v0.9/kusion/config-walkthrough/kcl_basics",title:"KCL Basics",description:"Table of Content",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/kcl_basics.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/kcl_basics",permalink:"/docs/v0.9/kusion/config-walkthrough/kcl_basics",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/kcl_basics.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Configuration File Overview",permalink:"/docs/v0.9/kusion/config-walkthrough/overview"},next:{title:"Base and Override",permalink:"/docs/v0.9/kusion/config-walkthrough/base_override"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Variable assignments",id:"variable-assignments",level:2},{value:"Common built-in types",id:"common-built-in-types",level:2},{value:"Lists and maps",id:"lists-and-maps",level:2},{value:"Conditional statements",id:"conditional-statements",level:2},{value:"The : and = operator",id:"the--and--operator",level:2},{value:"Advanced KCL capabilities",id:"advanced-kcl-capabilities",level:2}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kcl-basics"},"KCL Basics"),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#variable-assignments"},"Variable assignments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#common-built-in-types"},"Common built-in types")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#lists-and-maps"},"Lists and maps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#conditional-statements"},"Conditional statements")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#the--and--operator"},"The : and = operator")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#advanced-kcl-capabilities"},"Advanced KCL capabilities"))),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h2",{id:"variable-assignments"},"Variable assignments"),(0,i.kt)("p",null,"There are two ways to initialize a variable in KCL. You can either use the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," operator or the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss the difference between them in ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},"this section later"),"."),(0,i.kt)("p",null,"Here are the two ways to create a variable and initialize it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'foo = "Foo" # Declare a variable named `foo` and its value is a string literal "Foo"\nbar: "Bar" # Declare a variable named `bar` and its value is a string literal "Bar"\n')),(0,i.kt)("p",null,"You will be able to override a variable assignment via the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss this in depth in the ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},(0,i.kt)("inlineCode",{parentName:"a"},":")," and ",(0,i.kt)("inlineCode",{parentName:"a"},"=")," operator section"),"."),(0,i.kt)("h2",{id:"common-built-in-types"},"Common built-in types"),(0,i.kt)("p",null,"KCL supports ",(0,i.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"float"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"bool")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"string")," as the built-in types."),(0,i.kt)("p",null,"Other types are defined in the packages that are imported into the application configuration files. One such example would be the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object (or ",(0,i.kt)("inlineCode",{parentName:"p"},"Container"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Probe"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," object, etc) that are defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," repository."),(0,i.kt)("h2",{id:"lists-and-maps"},"Lists and maps"),(0,i.kt)("p",null,"Lists are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"[]")," notation.\nAn example of lists:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"list0 = [1, 2, 3]\nlist1 = [4, 5, 6]\njoined_list = list0 + list1 # [1, 2, 3, 4, 5, 6]\n")),(0,i.kt)("p",null,"Maps are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," notation.\nAn example of maps:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"a = {\"one\" = 1, \"two\" = 2, \"three\" = 3}\nb = {'one' = 1, 'two' = 2, 'three' = 3}\nassert a == b # True\nassert len(a) == 3 # True\n")),(0,i.kt)("h2",{id:"conditional-statements"},"Conditional statements"),(0,i.kt)("p",null,"You can also use basic control flow statements when writing the configuration file."),(0,i.kt)("p",null,"An example that sets the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," conditionally based on the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"containers.myapp.resources.cpu"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1 if containers.myapp.resources.cpu == "500m" else 2\n }\n}\n')),(0,i.kt)("p",null,"For more details on KCL's control flow statements, please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#control-flow-statements"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"the--and--operator"},"The ",(0,i.kt)("inlineCode",{parentName:"h2"},":")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"=")," operator"),(0,i.kt)("p",null,"You might have noticed there is a mixed usage of the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," in the samples above."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"TLDR: The recommendation is to use ",(0,i.kt)("inlineCode",{parentName:"strong"},":")," in the common configurations, and ",(0,i.kt)("inlineCode",{parentName:"strong"},"=")," for override in the environment-specific configurations."))),(0,i.kt)("p",null,"In KCL:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},":")," represents a union-ed value assignment. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: T E"),", the value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will be merged and union-ed into the element value."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"=")," represents a value override. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = T E"),", The value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will override the ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier")," attribute value.")),(0,i.kt)("p",null,"Let's take a look at an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is one configuration that will be merged.\nconfig: Config {\n data.d1 = 1\n}\n# This is another configuration that will be merged.\nconfig: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The above is equivalent to the snippet below since the two expressions for ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," get merged/union-ed into one:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d1 = 1\n data.d2 = 1\n}\n")),(0,i.kt)("p",null,"whereas using the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operators will result in a different outcome:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is first configuration.\nconfig = Config {\n data.d1 = 1\n}\n# This is second configuration that will override the prior one.\nconfig = Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The config above results in:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict with each other."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"data0 = {id: 1} | {id: 2} # Error\uff1aconflicting values between {'id': 2} and {'id': 1}\ndata1 = {id: 1} | {id = 2} # Ok, the value of `data` is {\"id\": 2}\n")),(0,i.kt)("p",null,"More about ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator can be found in the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#config-operations"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"advanced-kcl-capabilities"},"Advanced KCL capabilities"),(0,i.kt)("p",null,"For more advanced KCL capabilities, please visit the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8827e5e6.3a01b91b.js b/assets/js/8827e5e6.3a01b91b.js new file mode 100644 index 00000000000..70fc6f87cd6 --- /dev/null +++ b/assets/js/8827e5e6.3a01b91b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6631],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>m});var t=a(67294);function i(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function o(e){for(var n=1;n=0||(i[a]=e[a]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=t.createContext({}),p=function(e){var n=t.useContext(s),a=n;return e&&(a="function"==typeof e?e(n):o(o({},n),e)),a},d=function(e){var n=p(e.components);return t.createElement(s.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(a),m=i,h=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return a?t.createElement(h,o(o({ref:n},d),{},{components:a})):t.createElement(h,o({ref:n},d))}));function m(e,n){var a=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{a.r(n),a.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),i=(a(67294),a(3905));const r={sidebar_position:3},o="PodTransitionRule",l={unversionedId:"operating/manuals/podtransitionrule",id:"version-v0.9/operating/manuals/podtransitionrule",title:"PodTransitionRule",description:"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.",source:"@site/versioned_docs/version-v0.9/operating/manuals/podtransitionrule.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/podtransitionrule",permalink:"/docs/v0.9/operating/manuals/podtransitionrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/podtransitionrule.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"operating",previous:{title:"ResourceConsist",permalink:"/docs/v0.9/operating/manuals/resourceconsist"},next:{title:"PodDecoration",permalink:"/docs/v0.9/operating/manuals/poddecoration"}},s={},p=[{value:"Rule Definition",id:"rule-definition",level:2},{value:"Available Policy",id:"available-policy",level:3},{value:"maxUnavailable",id:"maxunavailable",level:4},{value:"minAvailable",id:"minavailable",level:4},{value:"Label Check",id:"label-check",level:3},{value:"Webhook",id:"webhook",level:3}],d={toc:p};function c(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"podtransitionrule"},"PodTransitionRule"),(0,i.kt)("p",null,"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pending")," phase, moving through ",(0,i.kt)("inlineCode",{parentName:"p"},"Running")," if at least one of its primary containers starts ",(0,i.kt)("inlineCode",{parentName:"p"},"OK"),", and then through either the ",(0,i.kt)("inlineCode",{parentName:"p"},"Succeeded")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"Failed")," phases depending on whether any container in the Pod terminated in failure."),(0,i.kt)("p",null,"These phase definitions can fulfill basic Pod change scenarios, but it are ambiguous.\nActually, before pod upgrade or ready, it is necessary to have some check mechanisms in place to ensure the safety of pod changes. Fortunately, ",(0,i.kt)("a",{parentName:"p",href:"/docs/v0.9/operating/concepts/podopslifecycle"},"PodOpsLifecycle")," extends and supports some check stages: ",(0,i.kt)("inlineCode",{parentName:"p"},"PreCheck")," before pod upgrade and ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," before pod ready."),(0,i.kt)("p",null,"To ensure a more fine-grained and controlled change process for Pods, we introduce custom rules or perform additional tasks as prerequisites for state transitions before the desired state of a Pod is achieved. Similar to the Pod ",(0,i.kt)("inlineCode",{parentName:"p"},"readinessGates"),", where certain conditions must be met for a Pod to be considered readiness. For example, we consider a Pod ready for the ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," phase only if it has specific labels. For this purpose, we introduce the ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," as a prerequisite for the state transition of a Pod."),(0,i.kt)("h2",{id:"rule-definition"},"Rule Definition"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," to define a set of transition rules for your workload pods.\nEach rule will be executed at the corresponding stage, and it will be blocked if the conditions are not met."),(0,i.kt)("p",null,"Here is an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n name: podtransitionrule-sample\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n - stage: PreCheck # stages are supported by PodOpsLifecycle. Defaults to PreCheck.\n labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n name: labelCheck\n - stage: PostCheck\n webhook:\n clientConfig:\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id # URL parameter key to carry trace ID when fetching result. Defaults to task-id in form 'QueryUrl=URL?rawQueryKey='\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef: \n fieldPath: status.podIP\n name: webhookCheck\n selector: # select pods in effect\n matchLabels:\n app: foo\n")),(0,i.kt)("h3",{id:"available-policy"},"Available Policy"),(0,i.kt)("p",null,"An ",(0,i.kt)("inlineCode",{parentName:"p"},"availablePolicy")," rule defines the availability strategy during the Pod update process."),(0,i.kt)("h4",{id:"maxunavailable"},"maxUnavailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n maxUnavailable: \n value: 50% # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailableValue")," is the maximum number of pods that can be unavailable during the update.\nValue can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).\nAbsolute number is calculated from percentage by rounding down.\nThis can not be 0."),(0,i.kt)("h4",{id:"minavailable"},"minAvailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n minAvailable:\n value: 5 # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"minAvailableValue")," is the minimum number of pods that should be available during the update."),(0,i.kt)("h3",{id:"label-check"},"Label Check"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"labelCheck")," rule is used to check if labels are satisfied.\nYou can define your own labels as change check conditions and modify the labels according to your needs."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n matchExpressions:\n - key: app.custom/forbidden \n operator: DoesNotExist\n")),(0,i.kt)("h3",{id:"webhook"},"Webhook"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"webhook")," is an HTTP callback, based on which a external web application can determine whether a pod can pass this check."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"An HTTP POST occurs first when pods entries the configured stage which defaults PreCheck."),(0,i.kt)("li",{parentName:"ul"},"If ",(0,i.kt)("inlineCode",{parentName:"li"},"poll")," is provided, this rule then keeps calling polling url to fetch a long running job result. This job can be located by ",(0,i.kt)("inlineCode",{parentName:"li"},"task-id")," returned from the response of the first request. ")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"webhook:\n clientConfig: # custom server config\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol without poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": false,\n "message": "msg", \n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating all pods approved or not. If it's ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", the ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," field can be used to approve partial pods."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol with poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "poll": true, // required to indicate polling calls is necessary\n "taskId": , // required to to fetch polling result\n "message": "msg"\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating whether the first request is success or not. If true and field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true")," (or field ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),"), PodTransisionRule will then begin to keep calling poll URL to fetch process result.\nField ",(0,i.kt)("inlineCode",{parentName:"p"},"taskId")," is required for polling. "),(0,i.kt)("p",null,"The request for polling is GET method and in form of ",(0,i.kt)("inlineCode",{parentName:"p"},"QueryUrl=URL?task-id="),". The parameter key in this URL defaults ",(0,i.kt)("inlineCode",{parentName:"p"},"task-id"),", if using ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in above response. It would be ",(0,i.kt)("inlineCode",{parentName:"p"},"trace-id")," if using ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in above response.\nUsers can also indicate the key by field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll.rawQueryKey"),"."),(0,i.kt)("p",null,"The response from polling call is expected like following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "message": "msg",\n "finished": false,\n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"success")," is supposed to be true, if there is no error. If all pods is approved, ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," should be ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),".\nIf ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," can be used to allow partial pods to be approved."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8827e5e6.41c4aebf.js b/assets/js/8827e5e6.41c4aebf.js deleted file mode 100644 index 09957584036..00000000000 --- a/assets/js/8827e5e6.41c4aebf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6631],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>m});var t=a(67294);function i(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function o(e){for(var n=1;n=0||(i[a]=e[a]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=t.createContext({}),p=function(e){var n=t.useContext(s),a=n;return e&&(a="function"==typeof e?e(n):o(o({},n),e)),a},d=function(e){var n=p(e.components);return t.createElement(s.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(a),m=i,h=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return a?t.createElement(h,o(o({ref:n},d),{},{components:a})):t.createElement(h,o({ref:n},d))}));function m(e,n){var a=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{a.r(n),a.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),i=(a(67294),a(3905));const r={sidebar_position:3},o="PodTransitionRule",l={unversionedId:"operating/manuals/podtransitionrule",id:"version-v0.9/operating/manuals/podtransitionrule",title:"PodTransitionRule",description:"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.",source:"@site/versioned_docs/version-v0.9/operating/manuals/podtransitionrule.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/podtransitionrule",permalink:"/docs/v0.9/operating/manuals/podtransitionrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/podtransitionrule.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"operating",previous:{title:"ResourceConsist",permalink:"/docs/v0.9/operating/manuals/resourceconsist"},next:{title:"PodDecoration",permalink:"/docs/v0.9/operating/manuals/poddecoration"}},s={},p=[{value:"Rule Definition",id:"rule-definition",level:2},{value:"Available Policy",id:"available-policy",level:3},{value:"maxUnavailable",id:"maxunavailable",level:4},{value:"minAvailable",id:"minavailable",level:4},{value:"Label Check",id:"label-check",level:3},{value:"Webhook",id:"webhook",level:3}],d={toc:p};function c(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"podtransitionrule"},"PodTransitionRule"),(0,i.kt)("p",null,"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pending")," phase, moving through ",(0,i.kt)("inlineCode",{parentName:"p"},"Running")," if at least one of its primary containers starts ",(0,i.kt)("inlineCode",{parentName:"p"},"OK"),", and then through either the ",(0,i.kt)("inlineCode",{parentName:"p"},"Succeeded")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"Failed")," phases depending on whether any container in the Pod terminated in failure."),(0,i.kt)("p",null,"These phase definitions can fulfill basic Pod change scenarios, but it are ambiguous.\nActually, before pod upgrade or ready, it is necessary to have some check mechanisms in place to ensure the safety of pod changes. Fortunately, ",(0,i.kt)("a",{parentName:"p",href:"/docs/v0.9/operating/concepts/podopslifecycle"},"PodOpsLifecycle")," extends and supports some check stages: ",(0,i.kt)("inlineCode",{parentName:"p"},"PreCheck")," before pod upgrade and ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," before pod ready."),(0,i.kt)("p",null,"To ensure a more fine-grained and controlled change process for Pods, we introduce custom rules or perform additional tasks as prerequisites for state transitions before the desired state of a Pod is achieved. Similar to the Pod ",(0,i.kt)("inlineCode",{parentName:"p"},"readinessGates"),", where certain conditions must be met for a Pod to be considered readiness. For example, we consider a Pod ready for the ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," phase only if it has specific labels. For this purpose, we introduce the ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," as a prerequisite for the state transition of a Pod."),(0,i.kt)("h2",{id:"rule-definition"},"Rule Definition"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," to define a set of transition rules for your workload pods.\nEach rule will be executed at the corresponding stage, and it will be blocked if the conditions are not met."),(0,i.kt)("p",null,"Here is an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n name: podtransitionrule-sample\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n - stage: PreCheck # stages are supported by PodOpsLifecycle. Defaults to PreCheck.\n labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n name: labelCheck\n - stage: PostCheck\n webhook:\n clientConfig:\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id # URL parameter key to carry trace ID when fetching result. Defaults to task-id in form 'QueryUrl=URL?rawQueryKey='\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef: \n fieldPath: status.podIP\n name: webhookCheck\n selector: # select pods in effect\n matchLabels:\n app: foo\n")),(0,i.kt)("h3",{id:"available-policy"},"Available Policy"),(0,i.kt)("p",null,"An ",(0,i.kt)("inlineCode",{parentName:"p"},"availablePolicy")," rule defines the availability strategy during the Pod update process."),(0,i.kt)("h4",{id:"maxunavailable"},"maxUnavailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n maxUnavailable: \n value: 50% # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailableValue")," is the maximum number of pods that can be unavailable during the update.\nValue can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).\nAbsolute number is calculated from percentage by rounding down.\nThis can not be 0."),(0,i.kt)("h4",{id:"minavailable"},"minAvailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n minAvailable:\n value: 5 # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"minAvailableValue")," is the minimum number of pods that should be available during the update."),(0,i.kt)("h3",{id:"label-check"},"Label Check"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"labelCheck")," rule is used to check if labels are satisfied.\nYou can define your own labels as change check conditions and modify the labels according to your needs."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n matchExpressions:\n - key: app.custom/forbidden \n operator: DoesNotExist\n")),(0,i.kt)("h3",{id:"webhook"},"Webhook"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"webhook")," is an HTTP callback, based on which a external web application can determine whether a pod can pass this check."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"An HTTP POST occurs first when pods entries the configured stage which defaults PreCheck."),(0,i.kt)("li",{parentName:"ul"},"If ",(0,i.kt)("inlineCode",{parentName:"li"},"poll")," is provided, this rule then keeps calling polling url to fetch a long running job result. This job can be located by ",(0,i.kt)("inlineCode",{parentName:"li"},"task-id")," returned from the response of the first request. ")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"webhook:\n clientConfig: # custom server config\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol without poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": false,\n "message": "msg", \n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating all pods approved or not. If it's ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", the ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," field can be used to approve partial pods."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol with poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "poll": true, // required to indicate polling calls is necessary\n "taskId": , // required to to fetch polling result\n "message": "msg"\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating whether the first request is success or not. If true and field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true")," (or field ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),"), PodTransisionRule will then begin to keep calling poll URL to fetch process result.\nField ",(0,i.kt)("inlineCode",{parentName:"p"},"taskId")," is required for polling. "),(0,i.kt)("p",null,"The request for polling is GET method and in form of ",(0,i.kt)("inlineCode",{parentName:"p"},"QueryUrl=URL?task-id="),". The parameter key in this URL defaults ",(0,i.kt)("inlineCode",{parentName:"p"},"task-id"),", if using ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in above response. It would be ",(0,i.kt)("inlineCode",{parentName:"p"},"trace-id")," if using ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in above response.\nUsers can also indicate the key by field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll.rawQueryKey"),"."),(0,i.kt)("p",null,"The response from polling call is expected like following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "message": "msg",\n "finished": false,\n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"success")," is supposed to be true, if there is no error. If all pods is approved, ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," should be ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),".\nIf ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," can be used to allow partial pods to be approved."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8a2c5ffd.71805797.js b/assets/js/8a2c5ffd.71805797.js deleted file mode 100644 index e2011b099f3..00000000000 --- a/assets/js/8a2c5ffd.71805797.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2634],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),k=p(n),d=o,m=k["".concat(c,".").concat(d)]||k[d]||u[d]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=k;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace",i={unversionedId:"kusion/reference/commands/kusion-workspace",id:"version-v0.10/kusion/reference/commands/kusion-workspace",title:"kusion workspace",description:"Workspace is a logical concept representing a target that stacks will be deployed to",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace",permalink:"/docs/kusion/reference/commands/kusion-workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace update",permalink:"/docs/kusion/reference/commands/kusion-workspace-update"},next:{title:"Kusion Modules",permalink:"/docs/kusion/reference/modules/"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace"},"kusion workspace"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to."),(0,o.kt)("p",null," Workspace is managed by platform engineers, which contains a set of configurations that application developers do not want or should not concern, and is reused by multiple stacks belonging to different projects."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for workspace\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-create"},"kusion workspace create"),"\t - Create a new workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-delete"},"kusion workspace delete"),"\t - Delete a workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-list"},"kusion workspace list"),"\t - List all workspace names"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-show"},"kusion workspace show"),"\t - Show a workspace configuration"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-update"},"kusion workspace update"),"\t - Update a workspace configuration")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8a2c5ffd.a2f6d36d.js b/assets/js/8a2c5ffd.a2f6d36d.js new file mode 100644 index 00000000000..44c2bc01ea4 --- /dev/null +++ b/assets/js/8a2c5ffd.a2f6d36d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2634],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),k=p(n),d=o,m=k["".concat(c,".").concat(d)]||k[d]||u[d]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=k;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace",i={unversionedId:"kusion/reference/commands/kusion-workspace",id:"version-v0.10/kusion/reference/commands/kusion-workspace",title:"kusion workspace",description:"Workspace is a logical concept representing a target that stacks will be deployed to",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace",permalink:"/docs/kusion/reference/commands/kusion-workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace update",permalink:"/docs/kusion/reference/commands/kusion-workspace-update"},next:{title:"Kusion Modules",permalink:"/docs/kusion/reference/modules/"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace"},"kusion workspace"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to."),(0,o.kt)("p",null," Workspace is managed by platform engineers, which contains a set of configurations that application developers do not want or should not concern, and is reused by multiple stacks belonging to different projects."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for workspace\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-create"},"kusion workspace create"),"\t - Create a new workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-delete"},"kusion workspace delete"),"\t - Delete a workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-list"},"kusion workspace list"),"\t - List all workspace names"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-show"},"kusion workspace show"),"\t - Show a workspace configuration"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace-update"},"kusion workspace update"),"\t - Update a workspace configuration")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b19a93e.8496eafd.js b/assets/js/8b19a93e.8496eafd.js deleted file mode 100644 index efec83f8bde..00000000000 --- a/assets/js/8b19a93e.8496eafd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8622],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var i=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function o(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),s=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=s(e.components);return i.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},u=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=s(t),m=r,g=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return t?i.createElement(g,o(o({ref:n},c),{},{components:t})):i.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,o=new Array(a);o[0]=u;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,o[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var i=t(87462),r=(t(67294),t(3905));const a={},o="Upgrade Image",p={unversionedId:"kusion/user-guides/working-with-k8s/image-upgrade",id:"version-v0.10/kusion/user-guides/working-with-k8s/image-upgrade",title:"Upgrade Image",description:"You can declare the application's container image via image field of the Container schema.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/image-upgrade",permalink:"/docs/kusion/user-guides/working-with-k8s/image-upgrade",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Service",permalink:"/docs/kusion/user-guides/working-with-k8s/service"},next:{title:"Configure Resource Specification",permalink:"/docs/kusion/user-guides/working-with-k8s/resource-spec"}},l={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,i.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"upgrade-image"},"Upgrade Image"),(0,r.kt)("p",null,"You can declare the application's container image via ",(0,r.kt)("inlineCode",{parentName:"p"},"image")," field of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,r.kt)("p",null,"For the full ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,r.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,r.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,r.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,r.kt)("h2",{id:"example"},"Example"),(0,r.kt)("p",null,"Update the image value in ",(0,r.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.nginx: {\n ...\n # before: \n # image = "gcr.io/google-samples/gb-frontend:v4"\n # after: \n image = "gcr.io/google-samples/gb-frontend:v5"\n ...\n }\n}\n')),(0,r.kt)("p",null,"Everything else in ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,r.kt)("h2",{id:"applying"},"Applying"),(0,r.kt)("p",null,"Re-run steps in ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", update image is completed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,r.kt)("h2",{id:"validation"},"Validation"),(0,r.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated image (v5) as defined in the container configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b19a93e.8979ef6f.js b/assets/js/8b19a93e.8979ef6f.js new file mode 100644 index 00000000000..b3a89907c4b --- /dev/null +++ b/assets/js/8b19a93e.8979ef6f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8622],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var i=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function o(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),s=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=s(e.components);return i.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},u=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=s(t),m=r,g=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return t?i.createElement(g,o(o({ref:n},c),{},{components:t})):i.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,o=new Array(a);o[0]=u;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,o[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var i=t(87462),r=(t(67294),t(3905));const a={},o="Upgrade Image",p={unversionedId:"kusion/user-guides/working-with-k8s/image-upgrade",id:"version-v0.10/kusion/user-guides/working-with-k8s/image-upgrade",title:"Upgrade Image",description:"You can declare the application's container image via image field of the Container schema.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/image-upgrade",permalink:"/docs/kusion/user-guides/working-with-k8s/image-upgrade",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Service",permalink:"/docs/kusion/user-guides/working-with-k8s/service"},next:{title:"Configure Resource Specification",permalink:"/docs/kusion/user-guides/working-with-k8s/resource-spec"}},l={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,i.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"upgrade-image"},"Upgrade Image"),(0,r.kt)("p",null,"You can declare the application's container image via ",(0,r.kt)("inlineCode",{parentName:"p"},"image")," field of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,r.kt)("p",null,"For the full ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,r.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,r.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,r.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,r.kt)("h2",{id:"example"},"Example"),(0,r.kt)("p",null,"Update the image value in ",(0,r.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.nginx: {\n ...\n # before: \n # image = "gcr.io/google-samples/gb-frontend:v4"\n # after: \n image = "gcr.io/google-samples/gb-frontend:v5"\n ...\n }\n}\n')),(0,r.kt)("p",null,"Everything else in ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,r.kt)("h2",{id:"applying"},"Applying"),(0,r.kt)("p",null,"Re-run steps in ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", update image is completed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,r.kt)("h2",{id:"validation"},"Validation"),(0,r.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated image (v5) as defined in the container configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b810823.3ca25134.js b/assets/js/8b810823.3ca25134.js deleted file mode 100644 index 3d7a99b04e6..00000000000 --- a/assets/js/8b810823.3ca25134.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5160],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=i,h=d["".concat(c,".").concat(f)]||d[f]||p[f]||r;return n?o.createElement(h,a(a({ref:t},u),{},{components:n})):o.createElement(h,a({ref:t},u))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=n(87462),i=(n(67294),n(3905));const r={id:"intent",sidebar_label:"Intent"},a="Intent",s={unversionedId:"kusion/concepts/intent",id:"kusion/concepts/intent",title:"Intent",description:"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.",source:"@site/docs/kusion/3-concepts/6-intent.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/intent",permalink:"/docs/next/kusion/concepts/intent",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/6-intent.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"intent",sidebar_label:"Intent"},sidebar:"kusion",previous:{title:"AppConfiguration",permalink:"/docs/next/kusion/concepts/app-configuration"},next:{title:"Backend Configuration",permalink:"/docs/next/kusion/concepts/backend-configuration"}},c={},l=[{value:"Purpose",id:"purpose",level:2},{value:"Single Source of Truth",id:"single-source-of-truth",level:3},{value:"Consistency",id:"consistency",level:3},{value:"Rollback and Disaster Recovery",id:"rollback-and-disaster-recovery",level:3}],u={toc:l};function p(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"intent"},"Intent"),(0,i.kt)("p",null,"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent."),(0,i.kt)("h2",{id:"purpose"},"Purpose"),(0,i.kt)("h3",{id:"single-source-of-truth"},"Single Source of Truth"),(0,i.kt)("p",null,"In Kusion's workflow, the platform engineer builds Kusion modules and provides environment configurations, application developers choose Kusion modules they need and deploy operational intentions to an environment with related environment configurations. They can also input dynamic parameters like the container image when executing the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," command. So the final operational intentions include configurations written by application developers, environment configurations and dynamic inputs. Due to this reason, we introduce ",(0,i.kt)("strong",{parentName:"p"},"Intent")," to represent the SSoT(Single Source of Truth) of Kusion. It is the result of ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," which contains all operational intentions from different sources."),(0,i.kt)("h3",{id:"consistency"},"Consistency"),(0,i.kt)("p",null,"Delivering an application to different environments with identical configurations is a common practice, especially for applications that require scalable distribution. In such cases, an immutable configuration package is helpful. By utilizing the Intent, all configurations and changes are stored in a single file. As the Intent is the input of Kusion, it ensures consistency across different environments whenever you execute Kusion with the same Intent file."),(0,i.kt)("h3",{id:"rollback-and-disaster-recovery"},"Rollback and Disaster Recovery"),(0,i.kt)("p",null,"The ability to roll back is crucial in reducing incident duration. Rolling back the system to a previously validated version is much faster compared to attempting to fix it during an outage. We regard a validated Intent as a snapshot of the system and recommend storing the Intent in a version control system like Git. This enables better change management practices and makes it simpler to roll back to previous versions if needed. In case of a failure or outage, having a validated Intent simplifies the rollback process, ensuring that the system can be quickly recovered."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b810823.f6490f68.js b/assets/js/8b810823.f6490f68.js new file mode 100644 index 00000000000..e65f1122f13 --- /dev/null +++ b/assets/js/8b810823.f6490f68.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5160],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=i,h=d["".concat(c,".").concat(f)]||d[f]||p[f]||r;return n?o.createElement(h,a(a({ref:t},u),{},{components:n})):o.createElement(h,a({ref:t},u))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=n(87462),i=(n(67294),n(3905));const r={id:"intent",sidebar_label:"Intent"},a="Intent",s={unversionedId:"kusion/concepts/intent",id:"kusion/concepts/intent",title:"Intent",description:"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.",source:"@site/docs/kusion/3-concepts/6-intent.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/intent",permalink:"/docs/next/kusion/concepts/intent",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/6-intent.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"intent",sidebar_label:"Intent"},sidebar:"kusion",previous:{title:"AppConfiguration",permalink:"/docs/next/kusion/concepts/app-configuration"},next:{title:"Backend",permalink:"/docs/next/kusion/concepts/backend"}},c={},l=[{value:"Purpose",id:"purpose",level:2},{value:"Single Source of Truth",id:"single-source-of-truth",level:3},{value:"Consistency",id:"consistency",level:3},{value:"Rollback and Disaster Recovery",id:"rollback-and-disaster-recovery",level:3}],u={toc:l};function p(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"intent"},"Intent"),(0,i.kt)("p",null,"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent."),(0,i.kt)("h2",{id:"purpose"},"Purpose"),(0,i.kt)("h3",{id:"single-source-of-truth"},"Single Source of Truth"),(0,i.kt)("p",null,"In Kusion's workflow, the platform engineer builds Kusion modules and provides environment configurations, application developers choose Kusion modules they need and deploy operational intentions to an environment with related environment configurations. They can also input dynamic parameters like the container image when executing the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," command. So the final operational intentions include configurations written by application developers, environment configurations and dynamic inputs. Due to this reason, we introduce ",(0,i.kt)("strong",{parentName:"p"},"Intent")," to represent the SSoT(Single Source of Truth) of Kusion. It is the result of ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," which contains all operational intentions from different sources."),(0,i.kt)("h3",{id:"consistency"},"Consistency"),(0,i.kt)("p",null,"Delivering an application to different environments with identical configurations is a common practice, especially for applications that require scalable distribution. In such cases, an immutable configuration package is helpful. By utilizing the Intent, all configurations and changes are stored in a single file. As the Intent is the input of Kusion, it ensures consistency across different environments whenever you execute Kusion with the same Intent file."),(0,i.kt)("h3",{id:"rollback-and-disaster-recovery"},"Rollback and Disaster Recovery"),(0,i.kt)("p",null,"The ability to roll back is crucial in reducing incident duration. Rolling back the system to a previously validated version is much faster compared to attempting to fix it during an outage. We regard a validated Intent as a snapshot of the system and recommend storing the Intent in a version control system like Git. This enables better change management practices and makes it simpler to roll back to previous versions if needed. In case of a failure or outage, having a validated Intent simplifies the rollback process, ensuring that the system can be quickly recovered."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8d59c070.00f6a67d.js b/assets/js/8d59c070.00f6a67d.js new file mode 100644 index 00000000000..f27007ad2da --- /dev/null +++ b/assets/js/8d59c070.00f6a67d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7555],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(t),m=r,k=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return t?a.createElement(k,i(i({ref:n},p),{},{components:t})):a.createElement(k,i({ref:n},p))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var a=t(87462),r=(t(67294),t(3905));const o={id:"backend-configuration",sidebar_label:"Backend Configuration"},i="Backend Configuration",s={unversionedId:"kusion/concepts/backend-configuration",id:"version-v0.10/kusion/concepts/backend-configuration",title:"Backend Configuration",description:"The backend configuration defines the place where Kusion stores its state data file. By default, Kusion uses the local type of backend to store the state on the local disk. While for team collaboration projects, the state can be stored on a remote backend, such as mysql, oss and s3 to allow multiple users access it.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/7-backend-configuration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/backend-configuration",permalink:"/docs/kusion/concepts/backend-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/7-backend-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"backend-configuration",sidebar_label:"Backend Configuration"},sidebar:"kusion",previous:{title:"Intent",permalink:"/docs/kusion/concepts/intent"},next:{title:"How Kusion Works?",permalink:"/docs/kusion/concepts/how-kusion-works"}},l={},c=[{value:"Configuring State Backend",id:"configuring-state-backend",level:2},{value:"Workspace Configuration File",id:"workspace-configuration-file",level:3},{value:"Environment Variables",id:"environment-variables",level:3},{value:"Command Line Parameters",id:"command-line-parameters",level:3},{value:"Configuration Combination",id:"configuration-combination",level:3},{value:"Available Backend",id:"available-backend",level:2},{value:"local",id:"local",level:3},{value:"mysql",id:"mysql",level:3},{value:"oss",id:"oss",level:3},{value:"s3",id:"s3",level:3}],p={toc:c};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"backend-configuration"},"Backend Configuration"),(0,r.kt)("p",null,"The backend configuration defines the place where Kusion stores its ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," data file. By default, Kusion uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," type of backend to store the state on the local disk. While for team collaboration projects, the state can be stored on a remote backend, such as ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"oss")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"s3")," to allow multiple users access it. "),(0,r.kt)("h2",{id:"configuring-state-backend"},"Configuring State Backend"),(0,r.kt)("p",null,"There are three ways to configure the backend:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"workspace configuration file"),(0,r.kt)("li",{parentName:"ul"},"environment variables"),(0,r.kt)("li",{parentName:"ul"},"command line parameters")),(0,r.kt)("h3",{id:"workspace-configuration-file"},"Workspace Configuration File"),(0,r.kt)("p",null,"Users can configure the storage of the state with the ",(0,r.kt)("inlineCode",{parentName:"p"},"backends")," block in the workspace file, where a map with the backend type as the key and the corresponding config items as the value to declare the backend configuration. Be attention, only one kind of backend type is allowed, more than one backend types are illegal."),(0,r.kt)("p",null,"The following gives an example of the backend configuration of ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"backends:\n mysql:\n dbName: \n user: \n password: \n host: \n port: \n")),(0,r.kt)("h3",{id:"environment-variables"},"Environment Variables"),(0,r.kt)("p",null,"For the sensitive information, Kusion supports configuring them by environment variables. Not all the configuration items are enabled, and the items differ from backend type. For example, users can configure mysql password by environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_BACKEND_MYSQL_PASSWORD"),"."),(0,r.kt)("h3",{id:"command-line-parameters"},"Command Line Parameters"),(0,r.kt)("p",null,"Users can specify the type of backend with the option ",(0,r.kt)("inlineCode",{parentName:"p"},"--backend-type"),", and configure the detailed information with ",(0,r.kt)("inlineCode",{parentName:"p"},"--backend-config")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"-C"),", for instance: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --backend-type mysql -C dbName= -C user= -C password= -C host= -C port=\n")),(0,r.kt)("h3",{id:"configuration-combination"},"Configuration Combination"),(0,r.kt)("p",null,"When more than one configuration methods are in use, Kusion will merge them to generate the whole backend configuration. Workspace configuration file, environment variables, command line parameter: the priority of these three configuration methods increases gradually. If there is no conflict of backend type, the latter will overlay the former by configuration items. If there is conflict of backend type, which only occurs between workspace configuration file and command line parameters, use the backend type specified by command line, and the configuration items from workspace are deprecated."),(0,r.kt)("h2",{id:"available-backend"},"Available Backend"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"local"),(0,r.kt)("li",{parentName:"ul"},"mysql"),(0,r.kt)("li",{parentName:"ul"},"oss"),(0,r.kt)("li",{parentName:"ul"},"s3")),(0,r.kt)("h3",{id:"local"},"local"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the local file system, which is suitable for local operations while not ideal for multi-user collaboration. "),(0,r.kt)("p",null,"There is no configuration items for ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," backend. When neither the workspace configuration file nor the command line parameters declare the backend configuration, Kusion by default uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"local"),"."),(0,r.kt)("h3",{id:"mysql"},"mysql"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," into a ",(0,r.kt)("strong",{parentName:"p"},"mysql database"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackends:\n mysql:\n dbName: \n user: \n password: \n host: \n port: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport KUSION_BACKEND_MYSQL_PASSWORD=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type mysql -C dbName= -C user= -C password= -C host= -C port=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"dbName - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the name of the database"),(0,r.kt)("li",{parentName:"ul"},"user - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the username of the database"),(0,r.kt)("li",{parentName:"ul"},"password - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the password of the database, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"KUSION_BACKEND_MYSQL_PASSWORD")),(0,r.kt)("li",{parentName:"ul"},"host - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the access address for the database"),(0,r.kt)("li",{parentName:"ul"},"port - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the port of the database")),(0,r.kt)("p",null,"Note that the table name in the database used by Kusion is ",(0,r.kt)("strong",{parentName:"p"},"state"),". Below is an example SQL statement for creating this table:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"CREATE TABLE `state` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',\n `tenant` varchar(100) DEFAULT NULL COMMENT 'tenant',\n `project` varchar(100) NOT NULL COMMENT 'project',\n `kusion_version` varchar(50) DEFAULT NULL COMMENT 'kusion version',\n `version` int(10) unsigned NOT NULL COMMENT 'current state format version\uff0cmay upgrade in the future',\n `serial` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'modification times for state\uff0ccan be used in concurrent control',\n `operator` varchar(100) DEFAULT NULL COMMENT 'last modifier',\n `resources` longtext DEFAULT NULL COMMENT 'state of the resources\uff0cjson array',\n `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'creation time',\n `modified_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'update time',\n `stack` varchar(100) DEFAULT NULL COMMENT 'stack',\n `cluster` varchar(100) DEFAULT NULL COMMENT 'logical isolation in a stack\uff0cusually clustername__cellname',\n PRIMARY KEY (`id`),\n UNIQUE KEY `uk_state_latest` (`tenant`, `project`, `stack`, `serial`, `cluster`),\n KEY `idx_tenant` (`tenant`),\n KEY `idx_project` (`project`),\n KEY `idx_kusion_version` (`kusion_version`),\n KEY `idx_version` (`version`),\n KEY `idx_create_time` (`create_time`),\n KEY `idx_modified_time` (`modified_time`),\n KEY `idx_stack` (`stack`),\n KEY `idx_cluster` (`cluster`)\n);\n")),(0,r.kt)("h3",{id:"oss"},"oss"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"oss")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,r.kt)("strong",{parentName:"p"},"Alicloud Object Storage Service (OSS)"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackends:\n oss:\n endpoint: \n bucket: \n accessKeyID: \n access-key-secret: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport OSS_ACCESS_KEY_ID=\nexport OSS_ACCESS_KEY_SECRET=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type oss -C endpoint= -C bucket= -C accessKeyID= -C accessKeySecret=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"endpoint - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the access endpoint for alicloud oss bucket"),(0,r.kt)("li",{parentName:"ul"},"bucket - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the alicloud oss bucket"),(0,r.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeyID, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_ID")),(0,r.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeySecret, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_SECRET"))),(0,r.kt)("h3",{id:"s3"},"s3"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"s3")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,r.kt)("strong",{parentName:"p"},"AWS Simple Storage Service (S3)"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackend: \n s3:\n endpoint: \n bucket: \n accessKeyID: \n access-key-secret: \n region: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport AWS_ACCESS_KEY_ID=\nexport AWS_SECRET_ACCESS_KEY=\nexport AWS_REGION=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type s3 -C endpoint= -C bucket= -C accessKeyID= -C accessKeySecret= -C region=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"endpoint - ",(0,r.kt)("inlineCode",{parentName:"li"},"optional")," specify the access endpoint for aws s3 bucket"),(0,r.kt)("li",{parentName:"ul"},"bucket - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the aws s3 bucket"),(0,r.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeyID, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_ACCESS_KEY_ID")),(0,r.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeySecret, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_SECRET_ACCESS_KEY")),(0,r.kt)("li",{parentName:"ul"},"region - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the region of aws s3 bucket, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_DEFAULT_REGION")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_REGION"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8d59c070.2ce7053f.js b/assets/js/8d59c070.2ce7053f.js deleted file mode 100644 index aa0d1f01731..00000000000 --- a/assets/js/8d59c070.2ce7053f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7555],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(t),m=r,k=d["".concat(l,".").concat(m)]||d[m]||u[m]||o;return t?a.createElement(k,i(i({ref:n},p),{},{components:t})):a.createElement(k,i({ref:n},p))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var a=t(87462),r=(t(67294),t(3905));const o={id:"backend-configuration",sidebar_label:"Backend Configuration"},i="Backend Configuration",s={unversionedId:"kusion/concepts/backend-configuration",id:"version-v0.10/kusion/concepts/backend-configuration",title:"Backend Configuration",description:"The backend configuration defines the place where Kusion stores its state data file. By default, Kusion uses the local type of backend to store the state on the local disk. While for team collaboration projects, the state can be stored on a remote backend, such as mysql, oss and s3 to allow multiple users access it.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/7-backend-configuration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/backend-configuration",permalink:"/docs/kusion/concepts/backend-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/7-backend-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{id:"backend-configuration",sidebar_label:"Backend Configuration"},sidebar:"kusion",previous:{title:"Intent",permalink:"/docs/kusion/concepts/intent"},next:{title:"How Kusion Works?",permalink:"/docs/kusion/concepts/how-kusion-works"}},l={},c=[{value:"Configuring State Backend",id:"configuring-state-backend",level:2},{value:"Workspace Configuration File",id:"workspace-configuration-file",level:3},{value:"Environment Variables",id:"environment-variables",level:3},{value:"Command Line Parameters",id:"command-line-parameters",level:3},{value:"Configuration Combination",id:"configuration-combination",level:3},{value:"Available Backend",id:"available-backend",level:2},{value:"local",id:"local",level:3},{value:"mysql",id:"mysql",level:3},{value:"oss",id:"oss",level:3},{value:"s3",id:"s3",level:3}],p={toc:c};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"backend-configuration"},"Backend Configuration"),(0,r.kt)("p",null,"The backend configuration defines the place where Kusion stores its ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," data file. By default, Kusion uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," type of backend to store the state on the local disk. While for team collaboration projects, the state can be stored on a remote backend, such as ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"oss")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"s3")," to allow multiple users access it. "),(0,r.kt)("h2",{id:"configuring-state-backend"},"Configuring State Backend"),(0,r.kt)("p",null,"There are three ways to configure the backend:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"workspace configuration file"),(0,r.kt)("li",{parentName:"ul"},"environment variables"),(0,r.kt)("li",{parentName:"ul"},"command line parameters")),(0,r.kt)("h3",{id:"workspace-configuration-file"},"Workspace Configuration File"),(0,r.kt)("p",null,"Users can configure the storage of the state with the ",(0,r.kt)("inlineCode",{parentName:"p"},"backends")," block in the workspace file, where a map with the backend type as the key and the corresponding config items as the value to declare the backend configuration. Be attention, only one kind of backend type is allowed, more than one backend types are illegal."),(0,r.kt)("p",null,"The following gives an example of the backend configuration of ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"backends:\n mysql:\n dbName: \n user: \n password: \n host: \n port: \n")),(0,r.kt)("h3",{id:"environment-variables"},"Environment Variables"),(0,r.kt)("p",null,"For the sensitive information, Kusion supports configuring them by environment variables. Not all the configuration items are enabled, and the items differ from backend type. For example, users can configure mysql password by environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"KUSION_BACKEND_MYSQL_PASSWORD"),"."),(0,r.kt)("h3",{id:"command-line-parameters"},"Command Line Parameters"),(0,r.kt)("p",null,"Users can specify the type of backend with the option ",(0,r.kt)("inlineCode",{parentName:"p"},"--backend-type"),", and configure the detailed information with ",(0,r.kt)("inlineCode",{parentName:"p"},"--backend-config")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"-C"),", for instance: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --backend-type mysql -C dbName= -C user= -C password= -C host= -C port=\n")),(0,r.kt)("h3",{id:"configuration-combination"},"Configuration Combination"),(0,r.kt)("p",null,"When more than one configuration methods are in use, Kusion will merge them to generate the whole backend configuration. Workspace configuration file, environment variables, command line parameter: the priority of these three configuration methods increases gradually. If there is no conflict of backend type, the latter will overlay the former by configuration items. If there is conflict of backend type, which only occurs between workspace configuration file and command line parameters, use the backend type specified by command line, and the configuration items from workspace are deprecated."),(0,r.kt)("h2",{id:"available-backend"},"Available Backend"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"local"),(0,r.kt)("li",{parentName:"ul"},"mysql"),(0,r.kt)("li",{parentName:"ul"},"oss"),(0,r.kt)("li",{parentName:"ul"},"s3")),(0,r.kt)("h3",{id:"local"},"local"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the local file system, which is suitable for local operations while not ideal for multi-user collaboration. "),(0,r.kt)("p",null,"There is no configuration items for ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," backend. When neither the workspace configuration file nor the command line parameters declare the backend configuration, Kusion by default uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"local"),"."),(0,r.kt)("h3",{id:"mysql"},"mysql"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," into a ",(0,r.kt)("strong",{parentName:"p"},"mysql database"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackends:\n mysql:\n dbName: \n user: \n password: \n host: \n port: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport KUSION_BACKEND_MYSQL_PASSWORD=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type mysql -C dbName= -C user= -C password= -C host= -C port=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"dbName - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the name of the database"),(0,r.kt)("li",{parentName:"ul"},"user - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the username of the database"),(0,r.kt)("li",{parentName:"ul"},"password - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the password of the database, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"KUSION_BACKEND_MYSQL_PASSWORD")),(0,r.kt)("li",{parentName:"ul"},"host - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the access address for the database"),(0,r.kt)("li",{parentName:"ul"},"port - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," the port of the database")),(0,r.kt)("p",null,"Note that the table name in the database used by Kusion is ",(0,r.kt)("strong",{parentName:"p"},"state"),". Below is an example SQL statement for creating this table:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"CREATE TABLE `state` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',\n `tenant` varchar(100) DEFAULT NULL COMMENT 'tenant',\n `project` varchar(100) NOT NULL COMMENT 'project',\n `kusion_version` varchar(50) DEFAULT NULL COMMENT 'kusion version',\n `version` int(10) unsigned NOT NULL COMMENT 'current state format version\uff0cmay upgrade in the future',\n `serial` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'modification times for state\uff0ccan be used in concurrent control',\n `operator` varchar(100) DEFAULT NULL COMMENT 'last modifier',\n `resources` longtext DEFAULT NULL COMMENT 'state of the resources\uff0cjson array',\n `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'creation time',\n `modified_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'update time',\n `stack` varchar(100) DEFAULT NULL COMMENT 'stack',\n `cluster` varchar(100) DEFAULT NULL COMMENT 'logical isolation in a stack\uff0cusually clustername__cellname',\n PRIMARY KEY (`id`),\n UNIQUE KEY `uk_state_latest` (`tenant`, `project`, `stack`, `serial`, `cluster`),\n KEY `idx_tenant` (`tenant`),\n KEY `idx_project` (`project`),\n KEY `idx_kusion_version` (`kusion_version`),\n KEY `idx_version` (`version`),\n KEY `idx_create_time` (`create_time`),\n KEY `idx_modified_time` (`modified_time`),\n KEY `idx_stack` (`stack`),\n KEY `idx_cluster` (`cluster`)\n);\n")),(0,r.kt)("h3",{id:"oss"},"oss"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"oss")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,r.kt)("strong",{parentName:"p"},"Alicloud Object Storage Service (OSS)"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackends:\n oss:\n endpoint: \n bucket: \n accessKeyID: \n access-key-secret: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport OSS_ACCESS_KEY_ID=\nexport OSS_ACCESS_KEY_SECRET=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type oss -C endpoint= -C bucket= -C accessKeyID= -C accessKeySecret=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"endpoint - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the access endpoint for alicloud oss bucket"),(0,r.kt)("li",{parentName:"ul"},"bucket - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the alicloud oss bucket"),(0,r.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeyID, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_ID")),(0,r.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeySecret, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"OSS_ACCESS_KEY_SECRET"))),(0,r.kt)("h3",{id:"s3"},"s3"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"s3")," storage type stores the ",(0,r.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,r.kt)("strong",{parentName:"p"},"AWS Simple Storage Service (S3)"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"# workspace configuration file\nbackend: \n s3:\n endpoint: \n bucket: \n accessKeyID: \n access-key-secret: \n region: \n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# environment variables\nexport AWS_ACCESS_KEY_ID=\nexport AWS_SECRET_ACCESS_KEY=\nexport AWS_REGION=\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"# command line parameters\nkusion apply --backend-type s3 -C endpoint= -C bucket= -C accessKeyID= -C accessKeySecret= -C region=\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"endpoint - ",(0,r.kt)("inlineCode",{parentName:"li"},"optional")," specify the access endpoint for aws s3 bucket"),(0,r.kt)("li",{parentName:"ul"},"bucket - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the aws s3 bucket"),(0,r.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeyID, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_ACCESS_KEY_ID")),(0,r.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeySecret, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_SECRET_ACCESS_KEY")),(0,r.kt)("li",{parentName:"ul"},"region - ",(0,r.kt)("inlineCode",{parentName:"li"},"required")," specify the region of aws s3 bucket, support declaring by environment variable ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_DEFAULT_REGION")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"AWS_REGION"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8e17bf11.5d8d059f.js b/assets/js/8e17bf11.5d8d059f.js deleted file mode 100644 index 329a8edee26..00000000000 --- a/assets/js/8e17bf11.5d8d059f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1974],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>u});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function l(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var p=t.createContext({}),s=function(e){var n=t.useContext(p),a=n;return e&&(a="function"==typeof e?e(n):l(l({},n),e)),a},d=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},m=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),m=s(a),u=o,f=m["".concat(p,".").concat(u)]||m[u]||c[u]||i;return a?t.createElement(f,l(l({ref:n},d),{},{components:a})):t.createElement(f,l({ref:n},d))}));function u(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=a.length,l=new Array(i);l[0]=m;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r.mdxType="string"==typeof e?e:o,l[1]=r;for(var s=2;s{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>i,metadata:()=>r,toc:()=>s});var t=a(87462),o=(a(67294),a(3905));const i={sidebar_position:4},l="PodDecoration",r={unversionedId:"operating/manuals/poddecoration",id:"version-v0.9/operating/manuals/poddecoration",title:"PodDecoration",description:"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.",source:"@site/versioned_docs/version-v0.9/operating/manuals/poddecoration.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/poddecoration",permalink:"/docs/v0.9/operating/manuals/poddecoration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/poddecoration.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"operating",previous:{title:"PodTransitionRule",permalink:"/docs/v0.9/operating/manuals/podtransitionrule"}},p={},s=[{value:"Create CollaSet",id:"create-collaset",level:2},{value:"Create PodDecoration",id:"create-poddecoration",level:2},{value:"Update PodDecoration",id:"update-poddecoration",level:2},{value:"Rolling update v1",id:"rolling-update-v1",level:3},{value:"Rolling update v1 -> v2",id:"rolling-update-v1---v2",level:3},{value:"Injection",id:"injection",level:2},{value:"Metadata",id:"metadata",level:3},{value:"Primary Container",id:"primary-container",level:3},{value:"Sidecar Container",id:"sidecar-container",level:3},{value:"InitContainer",id:"initcontainer",level:3},{value:"Upgrade strategy",id:"upgrade-strategy",level:2}],d={toc:s};function c(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"poddecoration"},"PodDecoration"),(0,o.kt)("p",null,"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria. "),(0,o.kt)("p",null,"PodDecoration not only allows injecting sidecar containers to Pods but also enables modifying existing container configurations, metadata, and scheduling parameters etc.\nThe PodDecoration controller does not control the upgrade of Pods. The actual upgrade process is fully controlled by the CollaSet controller. This means that the injection upgrade of PodDecoration can also be performed ",(0,o.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible"),"."),(0,o.kt)("p",null,"About ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/operating/manuals/collaset"},"CollaSet"),"."),(0,o.kt)("h1",{id:"example"},"Example"),(0,o.kt)("h2",{id:"create-collaset"},"Create CollaSet"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# collaset.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: foo\n namespace: default\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: foo\n")),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"collaset.yaml")," to create three pods under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," management."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f collaset.yaml\ncollaset.apps.kusionstack.io/foo created\n\n$ kubectl get cls\nNAME DESIRED CURRENT AVAILABLE UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\nfoo 3 3 3 3 3 3 foo-7bdb974bc7 foo-7bdb974bc7 7s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2wnnf 1/1 Running 0 41s\nfoo-hqpx7 1/1 Running 0 41s\nfoo-mqt48 1/1 Running 0 41s\n")),(0,o.kt)("h2",{id:"create-poddecoration"},"Create PodDecoration"),(0,o.kt)("p",null,"The following ",(0,o.kt)("inlineCode",{parentName:"p"},"poddecoration.yaml")," file describes a PodDecoration, which selects the pod under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," and injects the content in ",(0,o.kt)("inlineCode",{parentName:"p"},"template")," into the pod with ",(0,o.kt)("inlineCode",{parentName:"p"},"instance-id=0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nmetadata:\n name: sample-pd\nspec:\n selector: # selected pod range in which PodDecoration takes effect\n matchLabels:\n app: foo\n updateStrategy:\n rollingUpdate:\n selector: # select pod to upgrade in effect range\n matchLabels:\n collaset.kusionstack.io/instance-id: "0"\n template:\n metadata:\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v1"\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n command: ["sleep", "2h"]\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n')),(0,o.kt)("p",null,"Create PodDecoration ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to upgrade selected pod "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f poddecoration.yaml\npoddecoration.apps.kusionstack.io/sample-pd created\n")),(0,o.kt)("p",null,"The status of PodDecoration is updated, and one pod is injected with sidecar through recreate."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 1 1 1 sample-pd-9465f4c84 20s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 15s\nfoo-2wnnf 1/1 Running 0 2m\nfoo-hqpx7 1/1 Running 0 2m\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-2wnnf\n escaped: true\n - name: foo-hqpx7\n escaped: true\n matchedPods: 3\n injectedPods: 1\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h2",{id:"update-poddecoration"},"Update PodDecoration"),(0,o.kt)("h3",{id:"rolling-update-v1"},"Rolling update v1"),(0,o.kt)("p",null,"Edit ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to expand the upgrade scope."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Edit updateStrategy to select instance-id in [0, 1, 2]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector: \n matchExpressions:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n - "1" \n - "2" \n template:\n ...\n')),(0,o.kt)("p",null,"All pods updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 3 3 sample-pd-9465f4c84 sample-pd-9465f4c84 3m\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 3m\nfoo-lftw8 2/2 Running 0 8s\nfoo-n57rr 2/2 Running 0 8s\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n currentRevision: sample-pd-9465f4c84\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 3\n updatedReadyPods: 3\n updatedAvailablePods: 3\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h3",{id:"rolling-update-v1---v2"},"Rolling update v1 -> v2"),(0,o.kt)("p",null,"Update ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd"),"'s sidecar container image and ",(0,o.kt)("inlineCode",{parentName:"p"},"updateStrategy"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Update sidecar-a\'s image with ubuntu:22.10\n# Edit updateStrategy to select instance-id in [0]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n template:\n ...\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.10\n ...\n')),(0,o.kt)("p",null,"Pod ",(0,o.kt)("inlineCode",{parentName:"p"},"foo-2gnnl")," in-place upgrade sidecar container image."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 1 1 sample-pd-9465f4c84 sample-pd-8697d4bf8c 6min\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 1 (12s ago) 6m\nfoo-lftw8 2/2 Running 0 3min\nfoo-n57rr 2/2 Running 0 3min\n\n$ kubectl get pod foo-2gnnl -o yaml | grep "image: ubuntu"\n image: ubuntu:22.10\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-8697d4bf8c\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-8697d4bf8c\n')),(0,o.kt)("h1",{id:"features"},"Features"),(0,o.kt)("h2",{id:"injection"},"Injection"),(0,o.kt)("h3",{id:"metadata"},"Metadata"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n metadata:\n - patchPolicy: MergePatchJson\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"sample-pd","version":"v2"}]\'\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-name: sample-pd\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"patchPolicy")," is the injected policy, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Retain"),": The original value of annotations and labels will be retained."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Overwrite"),": The value of annotations and labels corresponding to the existing key will be overwritten."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MergePatchJson"),": It only takes effect for annotation. If the key does not exist, the value will be written directly. Otherwise, the json value will be merged.")),(0,o.kt)("p",null,"For example\uff1a"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# Old pod metadata\nmetadata:\n labels:\n custom.io/sidecar-version: "v1"\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}]\'\n\n# After metadata injected\nmetadata:\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-type: sample-pd\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}, {"name":"sample-pd","version":"v2"}]\'\n')),(0,o.kt)("h3",{id:"primary-container"},"Primary Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n primaryContainers:\n - targetPolicy: ByName\n name: foo\n image: foo:v2\n env: \n - name: APP_NAME\n value: foo\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n")),(0,o.kt)("p",null,"Injection into the primary containers only supports limited fields: ",(0,o.kt)("inlineCode",{parentName:"p"},"image"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"env")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"volumeMounts"),"."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"targetPolicy")," indicates which existed container these configuration should inject into, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ByName"),": Only inject containers matching ",(0,o.kt)("inlineCode",{parentName:"li"},"name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"All"),": Inject all primary containers."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"First"),": Inject into first primary container."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Last"),": Inject into last primary container.")),(0,o.kt)("h3",{id:"sidecar-container"},"Sidecar Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n containers:\n - injectPolicy: AfterPrimaryContainer # Container injected policy, AfterPrimaryContainer or BeforePrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n ...\n")),(0,o.kt)("p",null,"Inject a new sidecar container. Optional, it can be placed in front or behind the primary container."),(0,o.kt)("h3",{id:"initcontainer"},"InitContainer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n initContainers:\n - name: init\n image: custom-init-image:v1\n ...\n")),(0,o.kt)("h2",{id:"upgrade-strategy"},"Upgrade strategy"),(0,o.kt)("p",null,"Coming soon..."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8e17bf11.c4f869d6.js b/assets/js/8e17bf11.c4f869d6.js new file mode 100644 index 00000000000..431b68ea230 --- /dev/null +++ b/assets/js/8e17bf11.c4f869d6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1974],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>u});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function l(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var p=t.createContext({}),s=function(e){var n=t.useContext(p),a=n;return e&&(a="function"==typeof e?e(n):l(l({},n),e)),a},d=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},m=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),m=s(a),u=o,f=m["".concat(p,".").concat(u)]||m[u]||c[u]||i;return a?t.createElement(f,l(l({ref:n},d),{},{components:a})):t.createElement(f,l({ref:n},d))}));function u(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=a.length,l=new Array(i);l[0]=m;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r.mdxType="string"==typeof e?e:o,l[1]=r;for(var s=2;s{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>i,metadata:()=>r,toc:()=>s});var t=a(87462),o=(a(67294),a(3905));const i={sidebar_position:4},l="PodDecoration",r={unversionedId:"operating/manuals/poddecoration",id:"version-v0.9/operating/manuals/poddecoration",title:"PodDecoration",description:"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.",source:"@site/versioned_docs/version-v0.9/operating/manuals/poddecoration.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/poddecoration",permalink:"/docs/v0.9/operating/manuals/poddecoration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/poddecoration.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"operating",previous:{title:"PodTransitionRule",permalink:"/docs/v0.9/operating/manuals/podtransitionrule"}},p={},s=[{value:"Create CollaSet",id:"create-collaset",level:2},{value:"Create PodDecoration",id:"create-poddecoration",level:2},{value:"Update PodDecoration",id:"update-poddecoration",level:2},{value:"Rolling update v1",id:"rolling-update-v1",level:3},{value:"Rolling update v1 -> v2",id:"rolling-update-v1---v2",level:3},{value:"Injection",id:"injection",level:2},{value:"Metadata",id:"metadata",level:3},{value:"Primary Container",id:"primary-container",level:3},{value:"Sidecar Container",id:"sidecar-container",level:3},{value:"InitContainer",id:"initcontainer",level:3},{value:"Upgrade strategy",id:"upgrade-strategy",level:2}],d={toc:s};function c(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"poddecoration"},"PodDecoration"),(0,o.kt)("p",null,"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria. "),(0,o.kt)("p",null,"PodDecoration not only allows injecting sidecar containers to Pods but also enables modifying existing container configurations, metadata, and scheduling parameters etc.\nThe PodDecoration controller does not control the upgrade of Pods. The actual upgrade process is fully controlled by the CollaSet controller. This means that the injection upgrade of PodDecoration can also be performed ",(0,o.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible"),"."),(0,o.kt)("p",null,"About ",(0,o.kt)("a",{parentName:"p",href:"/docs/v0.9/operating/manuals/collaset"},"CollaSet"),"."),(0,o.kt)("h1",{id:"example"},"Example"),(0,o.kt)("h2",{id:"create-collaset"},"Create CollaSet"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# collaset.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: foo\n namespace: default\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: foo\n")),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"collaset.yaml")," to create three pods under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," management."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f collaset.yaml\ncollaset.apps.kusionstack.io/foo created\n\n$ kubectl get cls\nNAME DESIRED CURRENT AVAILABLE UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\nfoo 3 3 3 3 3 3 foo-7bdb974bc7 foo-7bdb974bc7 7s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2wnnf 1/1 Running 0 41s\nfoo-hqpx7 1/1 Running 0 41s\nfoo-mqt48 1/1 Running 0 41s\n")),(0,o.kt)("h2",{id:"create-poddecoration"},"Create PodDecoration"),(0,o.kt)("p",null,"The following ",(0,o.kt)("inlineCode",{parentName:"p"},"poddecoration.yaml")," file describes a PodDecoration, which selects the pod under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," and injects the content in ",(0,o.kt)("inlineCode",{parentName:"p"},"template")," into the pod with ",(0,o.kt)("inlineCode",{parentName:"p"},"instance-id=0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nmetadata:\n name: sample-pd\nspec:\n selector: # selected pod range in which PodDecoration takes effect\n matchLabels:\n app: foo\n updateStrategy:\n rollingUpdate:\n selector: # select pod to upgrade in effect range\n matchLabels:\n collaset.kusionstack.io/instance-id: "0"\n template:\n metadata:\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v1"\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n command: ["sleep", "2h"]\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n')),(0,o.kt)("p",null,"Create PodDecoration ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to upgrade selected pod "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f poddecoration.yaml\npoddecoration.apps.kusionstack.io/sample-pd created\n")),(0,o.kt)("p",null,"The status of PodDecoration is updated, and one pod is injected with sidecar through recreate."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 1 1 1 sample-pd-9465f4c84 20s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 15s\nfoo-2wnnf 1/1 Running 0 2m\nfoo-hqpx7 1/1 Running 0 2m\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-2wnnf\n escaped: true\n - name: foo-hqpx7\n escaped: true\n matchedPods: 3\n injectedPods: 1\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h2",{id:"update-poddecoration"},"Update PodDecoration"),(0,o.kt)("h3",{id:"rolling-update-v1"},"Rolling update v1"),(0,o.kt)("p",null,"Edit ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to expand the upgrade scope."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Edit updateStrategy to select instance-id in [0, 1, 2]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector: \n matchExpressions:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n - "1" \n - "2" \n template:\n ...\n')),(0,o.kt)("p",null,"All pods updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 3 3 sample-pd-9465f4c84 sample-pd-9465f4c84 3m\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 3m\nfoo-lftw8 2/2 Running 0 8s\nfoo-n57rr 2/2 Running 0 8s\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n currentRevision: sample-pd-9465f4c84\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 3\n updatedReadyPods: 3\n updatedAvailablePods: 3\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h3",{id:"rolling-update-v1---v2"},"Rolling update v1 -> v2"),(0,o.kt)("p",null,"Update ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd"),"'s sidecar container image and ",(0,o.kt)("inlineCode",{parentName:"p"},"updateStrategy"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Update sidecar-a\'s image with ubuntu:22.10\n# Edit updateStrategy to select instance-id in [0]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n template:\n ...\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.10\n ...\n')),(0,o.kt)("p",null,"Pod ",(0,o.kt)("inlineCode",{parentName:"p"},"foo-2gnnl")," in-place upgrade sidecar container image."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 1 1 sample-pd-9465f4c84 sample-pd-8697d4bf8c 6min\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 1 (12s ago) 6m\nfoo-lftw8 2/2 Running 0 3min\nfoo-n57rr 2/2 Running 0 3min\n\n$ kubectl get pod foo-2gnnl -o yaml | grep "image: ubuntu"\n image: ubuntu:22.10\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-8697d4bf8c\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-8697d4bf8c\n')),(0,o.kt)("h1",{id:"features"},"Features"),(0,o.kt)("h2",{id:"injection"},"Injection"),(0,o.kt)("h3",{id:"metadata"},"Metadata"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n metadata:\n - patchPolicy: MergePatchJson\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"sample-pd","version":"v2"}]\'\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-name: sample-pd\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"patchPolicy")," is the injected policy, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Retain"),": The original value of annotations and labels will be retained."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Overwrite"),": The value of annotations and labels corresponding to the existing key will be overwritten."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MergePatchJson"),": It only takes effect for annotation. If the key does not exist, the value will be written directly. Otherwise, the json value will be merged.")),(0,o.kt)("p",null,"For example\uff1a"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# Old pod metadata\nmetadata:\n labels:\n custom.io/sidecar-version: "v1"\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}]\'\n\n# After metadata injected\nmetadata:\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-type: sample-pd\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}, {"name":"sample-pd","version":"v2"}]\'\n')),(0,o.kt)("h3",{id:"primary-container"},"Primary Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n primaryContainers:\n - targetPolicy: ByName\n name: foo\n image: foo:v2\n env: \n - name: APP_NAME\n value: foo\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n")),(0,o.kt)("p",null,"Injection into the primary containers only supports limited fields: ",(0,o.kt)("inlineCode",{parentName:"p"},"image"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"env")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"volumeMounts"),"."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"targetPolicy")," indicates which existed container these configuration should inject into, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ByName"),": Only inject containers matching ",(0,o.kt)("inlineCode",{parentName:"li"},"name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"All"),": Inject all primary containers."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"First"),": Inject into first primary container."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Last"),": Inject into last primary container.")),(0,o.kt)("h3",{id:"sidecar-container"},"Sidecar Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n containers:\n - injectPolicy: AfterPrimaryContainer # Container injected policy, AfterPrimaryContainer or BeforePrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n ...\n")),(0,o.kt)("p",null,"Inject a new sidecar container. Optional, it can be placed in front or behind the primary container."),(0,o.kt)("h3",{id:"initcontainer"},"InitContainer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n initContainers:\n - name: init\n image: custom-init-image:v1\n ...\n")),(0,o.kt)("h2",{id:"upgrade-strategy"},"Upgrade strategy"),(0,o.kt)("p",null,"Coming soon..."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8ebb0243.1fa866ba.js b/assets/js/8ebb0243.5d1db1a5.js similarity index 51% rename from assets/js/8ebb0243.1fa866ba.js rename to assets/js/8ebb0243.5d1db1a5.js index 3cc1041b301..a4d1a6e3eb7 100644 --- a/assets/js/8ebb0243.1fa866ba.js +++ b/assets/js/8ebb0243.5d1db1a5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2009],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=i(r),m=a,f=u["".concat(s,".").concat(m)]||u[m]||p[m]||o;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var i=2;i{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var n=r(87462),a=(r(67294),r(3905));const o={},l="secret",c={unversionedId:"kusion/reference/model/catalog_models/internal/secret/doc_secret",id:"version-v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret",title:"secret",description:"Schema Secret",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret.md",sourceDirName:"kusion/reference/model/catalog_models/internal/secret",slug:"/kusion/reference/model/catalog_models/internal/secret/doc_secret",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port"},next:{title:"Naming Conventions",permalink:"/docs/v0.9/kusion/reference/model/naming-conventions"}},s={},i=[{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:i};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secret"},"secret"),(0,a.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,a.kt)("p",null,"Secret can be used to store sensitive data."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,a.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,a.kt)("td",{parentName:"tr",align:null},"opaque"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"data"),(0,a.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"immutable"),(0,a.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2009],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=i(r),m=a,f=u["".concat(s,".").concat(m)]||u[m]||p[m]||o;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var i=2;i{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var n=r(87462),a=(r(67294),r(3905));const o={},l="secret",c={unversionedId:"kusion/reference/model/catalog_models/internal/secret/doc_secret",id:"version-v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret",title:"secret",description:"Schema Secret",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret.md",sourceDirName:"kusion/reference/model/catalog_models/internal/secret",slug:"/kusion/reference/model/catalog_models/internal/secret/doc_secret",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"port",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port"},next:{title:"Naming Conventions",permalink:"/docs/v0.9/kusion/reference/model/naming-conventions"}},s={},i=[{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:i};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"secret"},"secret"),(0,a.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,a.kt)("p",null,"Secret can be used to store sensitive data."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,a.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,a.kt)("td",{parentName:"tr",align:null},"opaque"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"data"),(0,a.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"immutable"),(0,a.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8f5adede.82d08ed6.js b/assets/js/8f5adede.89b38597.js similarity index 54% rename from assets/js/8f5adede.82d08ed6.js rename to assets/js/8f5adede.89b38597.js index 35abdbde6b2..e2ed7772ebd 100644 --- a/assets/js/8f5adede.82d08ed6.js +++ b/assets/js/8f5adede.89b38597.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5825],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=l(n),f=o,d=m["".concat(c,".").concat(f)]||m[f]||u[f]||i;return n?r.createElement(d,a(a({ref:t},s),{},{components:n})):r.createElement(d,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p.mdxType="string"==typeof e?e:o,a[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={id:"configuration",sidebar_label:"Project Configuration"},a="Project Configuration",p={unversionedId:"kusion/concepts/project/configuration",id:"version-v0.10/kusion/concepts/project/configuration",title:"Project Configuration",description:"Users can add config items of the project in project.yaml, such as the project name, generator type, Prometheus monitoring, etc.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/1-project/2-configuration.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/configuration",permalink:"/docs/kusion/concepts/project/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/1-project/2-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Project Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/kusion/concepts/project/overview"},next:{title:"Overview",permalink:"/docs/kusion/concepts/stack/overview"}},c={},l=[],s={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"project-configuration"},"Project Configuration"),(0,o.kt)("p",null,"Users can add config items of the project in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),", such as the project name, generator type, Prometheus monitoring, etc."),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The project basic info\nname: helloworld\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," are explained below."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"name"),": The name of the project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"generator"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"type"),": The type of the module generator, supports ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"KCL"),", default is ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration"),". If using the schema AppConfiguration, set type as AppConfiguration"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"prometheus"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"operatorMode"),": Decides whether Kusion runs Prometheus in ",(0,o.kt)("inlineCode",{parentName:"li"},"Operator")," mode. Kusion will generate a ",(0,o.kt)("inlineCode",{parentName:"li"},"Custom Resource")," if it is true, while generate some annotations if it is false"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"monitorType"),": The type of the monitored resource, which can be one of ",(0,o.kt)("inlineCode",{parentName:"li"},"Service")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"Pod"))))))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5825],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=l(n),f=o,d=m["".concat(c,".").concat(f)]||m[f]||u[f]||i;return n?r.createElement(d,a(a({ref:t},s),{},{components:n})):r.createElement(d,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p.mdxType="string"==typeof e?e:o,a[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={id:"configuration",sidebar_label:"Project Configuration"},a="Project Configuration",p={unversionedId:"kusion/concepts/project/configuration",id:"version-v0.10/kusion/concepts/project/configuration",title:"Project Configuration",description:"Users can add config items of the project in project.yaml, such as the project name, generator type, Prometheus monitoring, etc.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/1-project/2-configuration.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/configuration",permalink:"/docs/kusion/concepts/project/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/1-project/2-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Project Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/kusion/concepts/project/overview"},next:{title:"Overview",permalink:"/docs/kusion/concepts/stack/overview"}},c={},l=[],s={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"project-configuration"},"Project Configuration"),(0,o.kt)("p",null,"Users can add config items of the project in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),", such as the project name, generator type, Prometheus monitoring, etc."),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The project basic info\nname: helloworld\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," are explained below."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"name"),": The name of the project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"generator"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"type"),": The type of the module generator, supports ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"KCL"),", default is ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration"),". If using the schema AppConfiguration, set type as AppConfiguration"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"prometheus"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"operatorMode"),": Decides whether Kusion runs Prometheus in ",(0,o.kt)("inlineCode",{parentName:"li"},"Operator")," mode. Kusion will generate a ",(0,o.kt)("inlineCode",{parentName:"li"},"Custom Resource")," if it is true, while generate some annotations if it is false"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"monitorType"),": The type of the monitored resource, which can be one of ",(0,o.kt)("inlineCode",{parentName:"li"},"Service")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"Pod"))))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8fcded8c.0579ecc9.js b/assets/js/8fcded8c.0579ecc9.js deleted file mode 100644 index fd725e131db..00000000000 --- a/assets/js/8fcded8c.0579ecc9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9803],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=i,k=d["".concat(p,".").concat(m)]||d[m]||c[m]||r;return n?a.createElement(k,o(o({ref:t},u),{},{components:n})):a.createElement(k,o({ref:t},u))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var a=n(87462),i=(n(67294),n(3905));const r={},o="Set up Operational Rules",l={unversionedId:"kusion/user-guides/working-with-k8s/set-up-operational-rules",id:"kusion/user-guides/working-with-k8s/set-up-operational-rules",title:"Set up Operational Rules",description:"You can set up operational rules in the AppConfiguration model via the opsRule field and corresponding platform configurations in the workspace directory. The opsRule is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/set-up-operational-rules",permalink:"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Resource Specification",permalink:"/docs/next/kusion/user-guides/working-with-k8s/resource-spec"},next:{title:"Schedule a Job",permalink:"/docs/next/kusion/user-guides/working-with-k8s/job"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"set-up-operational-rules"},"Set up Operational Rules"),(0,i.kt)("p",null,"You can set up operational rules in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," field and corresponding platform configurations in the workspace directory. The ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the opsRule to standardize the behavior of applications, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"If the platform engineers have set the default workload to ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"Kusion Operation")," and installed the Kusion Operation controllers properly, the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRules")," module will generate a ",(0,i.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/podtransitionrule"},"PodTransitionRule")," instead of updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," value in the deployment")),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"Add the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," snippet to the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," in ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.trait as t\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n ...\n }\n # Configure the maxUnavailable rule\n opsRule = t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the application deployment strategy now has the updated attributes ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable: 30%")," in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl get deployment -n simple-service -o yaml\n...\napiVersion: apps/v1\n kind: Deployment\n...\n spec:\n strategy:\n rollingUpdate:\n maxUnavailable: 30%\n type: RollingUpdate\n\n...\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8fcded8c.63397745.js b/assets/js/8fcded8c.63397745.js new file mode 100644 index 00000000000..fec2f5cfe21 --- /dev/null +++ b/assets/js/8fcded8c.63397745.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9803],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=i,k=d["".concat(p,".").concat(m)]||d[m]||c[m]||r;return n?a.createElement(k,o(o({ref:t},u),{},{components:n})):a.createElement(k,o({ref:t},u))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var a=n(87462),i=(n(67294),n(3905));const r={},o="Set up Operational Rules",l={unversionedId:"kusion/user-guides/working-with-k8s/set-up-operational-rules",id:"kusion/user-guides/working-with-k8s/set-up-operational-rules",title:"Set up Operational Rules",description:"You can set up operational rules in the AppConfiguration model via the opsRule field and corresponding platform configurations in the workspace directory. The opsRule is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/set-up-operational-rules",permalink:"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Resource Specification",permalink:"/docs/next/kusion/user-guides/working-with-k8s/resource-spec"},next:{title:"Schedule a Job",permalink:"/docs/next/kusion/user-guides/working-with-k8s/job"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"set-up-operational-rules"},"Set up Operational Rules"),(0,i.kt)("p",null,"You can set up operational rules in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," field and corresponding platform configurations in the workspace directory. The ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the opsRule to standardize the behavior of applications, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"If the platform engineers have set the default workload to ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"Kusion Operation")," and installed the Kusion Operation controllers properly, the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRules")," module will generate a ",(0,i.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/podtransitionrule"},"PodTransitionRule")," instead of updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," value in the deployment")),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"Add the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," snippet to the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," in ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.trait as t\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n ...\n }\n # Configure the maxUnavailable rule\n opsRule = t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the application deployment strategy now has the updated attributes ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable: 30%")," in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl get deployment -n simple-service -o yaml\n...\napiVersion: apps/v1\n kind: Deployment\n...\n spec:\n strategy:\n rollingUpdate:\n maxUnavailable: 30%\n type: RollingUpdate\n\n...\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/92e7585f.fd59f9f3.js b/assets/js/92e7585f.af0bf984.js similarity index 51% rename from assets/js/92e7585f.fd59f9f3.js rename to assets/js/92e7585f.af0bf984.js index 1013741e220..ddf0f67809a 100644 --- a/assets/js/92e7585f.fd59f9f3.js +++ b/assets/js/92e7585f.af0bf984.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[549],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,k=d["".concat(c,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(k,s(s({ref:t},u),{},{components:n})):r.createElement(k,s({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,s=new Array(i);s[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},s="kusion destroy",a={unversionedId:"kusion/reference/cli/kusion/kusion_destroy",id:"version-v0.9/kusion/reference/cli/kusion/kusion_destroy",title:"kusion destroy",description:"Delete the specified resources in runtime",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_destroy.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_destroy",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_destroy.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion compile",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile"},next:{title:"kusion init",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init"}},c={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],u={toc:l};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-destroy"},"kusion destroy"),(0,o.kt)("p",null,"Delete the specified resources in runtime"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Delete resources by resource spec."),(0,o.kt)("p",null," Only KCL files are accepted. Only one type of arguments may be specified: filenames, resources and names, or resources and label selector."),(0,o.kt)("p",null," Note that the destroy command does NOT do resource version checks, so if someone submits an update to a resource right when you submit a destroy, their update will be lost along with the rest of the resource."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion destroy [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete the configuration of current stack\n kusion destroy\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details after previewing it\n -h, --help help for destroy\n --operator string Specify the operator\n -O, --overrides strings Specify the configuration override path and value\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[549],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=l(n),f=o,k=d["".concat(c,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(k,s(s({ref:t},u),{},{components:n})):r.createElement(k,s({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,s=new Array(i);s[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},s="kusion destroy",a={unversionedId:"kusion/reference/cli/kusion/kusion_destroy",id:"version-v0.9/kusion/reference/cli/kusion/kusion_destroy",title:"kusion destroy",description:"Delete the specified resources in runtime",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_destroy.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_destroy",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_destroy.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion compile",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile"},next:{title:"kusion init",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init"}},c={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],u={toc:l};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-destroy"},"kusion destroy"),(0,o.kt)("p",null,"Delete the specified resources in runtime"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Delete resources by resource spec."),(0,o.kt)("p",null," Only KCL files are accepted. Only one type of arguments may be specified: filenames, resources and names, or resources and label selector."),(0,o.kt)("p",null," Note that the destroy command does NOT do resource version checks, so if someone submits an update to a resource right when you submit a destroy, their update will be lost along with the rest of the resource."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion destroy [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete the configuration of current stack\n kusion destroy\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details after previewing it\n -h, --help help for destroy\n --operator string Specify the operator\n -O, --overrides strings Specify the configuration override path and value\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.009b227a.js b/assets/js/935f2afb.009b227a.js new file mode 100644 index 00000000000..02693c934f5 --- /dev/null +++ b/assets/js/935f2afb.009b227a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"v0.11 \ud83d\udea7","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"docs":[{"type":"category","label":"community","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Community","href":"/docs/next/community/intro/","docId":"community/intro/intro"}]},{"type":"category","label":"ctrlmesh","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/docs/next/ctrlmesh/intro/","docId":"ctrlmesh/intro/intro"},{"type":"link","label":"Concepts","href":"/docs/next/ctrlmesh/concepts/","docId":"ctrlmesh/concepts/concepts"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/ctrlmesh/started/install","docId":"ctrlmesh/started/install"},{"type":"link","label":"Try a Sample","href":"/docs/next/ctrlmesh/started/try","docId":"ctrlmesh/started/try"}]},{"type":"link","label":"FAQ","href":"/docs/next/ctrlmesh/faq/","docId":"ctrlmesh/faq/faq"}]},{"type":"category","label":"kusion","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"What is Kusion?","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/","docId":"kusion/what-is-kusion/overview"},{"type":"link","label":"Kusion vs Other Software","href":"/docs/next/kusion/what-is-kusion/kusion-vs-x","docId":"kusion/what-is-kusion/kusion-vs-x"}]},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Install Kusion","href":"/docs/next/kusion/getting-started/install-kusion","docId":"kusion/getting-started/install-kusion"},{"type":"link","label":"Deliver the WordPress Application on Kubernetes","href":"/docs/next/kusion/getting-started/deliver-wordpress","docId":"kusion/getting-started/deliver-wordpress"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Project","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/project/overview","docId":"kusion/concepts/project/overview"},{"type":"link","label":"Project Configuration","href":"/docs/next/kusion/concepts/project/configuration","docId":"kusion/concepts/project/configuration"}]},{"type":"category","label":"Stack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/stack/overview","docId":"kusion/concepts/stack/overview"},{"type":"link","label":"Stack Configuration","href":"/docs/next/kusion/concepts/stack/configuration","docId":"kusion/concepts/stack/configuration"}]},{"type":"link","label":"Kusion Module","href":"/docs/next/kusion/concepts/kusion-module","docId":"kusion/concepts/kusion-module"},{"type":"link","label":"Workspace","href":"/docs/next/kusion/concepts/workspace","docId":"kusion/concepts/workspace"},{"type":"link","label":"AppConfiguration","href":"/docs/next/kusion/concepts/app-configuration","docId":"kusion/concepts/app-configuration"},{"type":"link","label":"Intent","href":"/docs/next/kusion/concepts/intent","docId":"kusion/concepts/intent"},{"type":"link","label":"Backend","href":"/docs/next/kusion/concepts/backend","docId":"kusion/concepts/backend"},{"type":"link","label":"Configuration","href":"/docs/next/kusion/concepts/configuration","docId":"kusion/concepts/configuration"},{"type":"link","label":"How Kusion Works?","href":"/docs/next/kusion/concepts/how-kusion-works","docId":"kusion/concepts/how-kusion-works"}]},{"type":"category","label":"Configuration Walkthrough","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration File Overview","href":"/docs/next/kusion/configuration-walkthrough/overview","docId":"kusion/configuration-walkthrough/overview"},{"type":"link","label":"KCL Basics","href":"/docs/next/kusion/configuration-walkthrough/kcl-basics","docId":"kusion/configuration-walkthrough/kcl-basics"},{"type":"link","label":"Base and Override","href":"/docs/next/kusion/configuration-walkthrough/base-override","docId":"kusion/configuration-walkthrough/base-override"},{"type":"link","label":"Workload","href":"/docs/next/kusion/configuration-walkthrough/workload","docId":"kusion/configuration-walkthrough/workload"},{"type":"link","label":"Application Networking","href":"/docs/next/kusion/configuration-walkthrough/networking","docId":"kusion/configuration-walkthrough/networking"},{"type":"link","label":"Managed Databases","href":"/docs/next/kusion/configuration-walkthrough/databse","docId":"kusion/configuration-walkthrough/databse"},{"type":"link","label":"Secrets","href":"/docs/next/kusion/configuration-walkthrough/secret","docId":"kusion/configuration-walkthrough/secret"},{"type":"link","label":"Application Monitoring","href":"/docs/next/kusion/configuration-walkthrough/monitoring","docId":"kusion/configuration-walkthrough/monitoring"},{"type":"link","label":"Operational Rules","href":"/docs/next/kusion/configuration-walkthrough/operational-rules","docId":"kusion/configuration-walkthrough/operational-rules"}]},{"type":"category","label":"User Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Cloud Resources","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deliver the WordPress Application with Cloud RDS","href":"/docs/next/kusion/user-guides/cloud-resources/database","docId":"kusion/user-guides/cloud-resources/database"},{"type":"link","label":"Expose Application Service Deployed on CSP Kubernetes","href":"/docs/next/kusion/user-guides/cloud-resources/expose-service","docId":"kusion/user-guides/cloud-resources/expose-service"}]},{"type":"category","label":"Kubernetes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application","href":"/docs/next/kusion/user-guides/working-with-k8s/deploy-application","docId":"kusion/user-guides/working-with-k8s/deploy-application"},{"type":"link","label":"Configure Containers","href":"/docs/next/kusion/user-guides/working-with-k8s/container","docId":"kusion/user-guides/working-with-k8s/container"},{"type":"link","label":"Expose Service","href":"/docs/next/kusion/user-guides/working-with-k8s/service","docId":"kusion/user-guides/working-with-k8s/service"},{"type":"link","label":"Upgrade Image","href":"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade","docId":"kusion/user-guides/working-with-k8s/image-upgrade"},{"type":"link","label":"Configure Resource Specification","href":"/docs/next/kusion/user-guides/working-with-k8s/resource-spec","docId":"kusion/user-guides/working-with-k8s/resource-spec"},{"type":"link","label":"Set up Operational Rules","href":"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules","docId":"kusion/user-guides/working-with-k8s/set-up-operational-rules"},{"type":"link","label":"Schedule a Job","href":"/docs/next/kusion/user-guides/working-with-k8s/job","docId":"kusion/user-guides/working-with-k8s/job"}]},{"type":"category","label":"Automated Observability","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configure Monitoring Behavior With Prometheus","href":"/docs/next/kusion/user-guides/observability/prometheus","docId":"kusion/user-guides/observability/prometheus"}]},{"type":"category","label":"GitHub Actions","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application Securely and Efficiently via GitHub Actions","href":"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions","docId":"kusion/user-guides/github-actions/deploy-application-via-github-actions"}]},{"type":"category","label":"Secrets Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Using Cloud Secrets Manager","href":"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets","docId":"kusion/user-guides/secrets-management/using-cloud-secrets"}]}]},{"type":"category","label":"Reference","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Kusion Commands","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"kusion apply","href":"/docs/next/kusion/reference/commands/kusion-apply","docId":"kusion/reference/commands/kusion-apply"},{"type":"link","label":"kusion build","href":"/docs/next/kusion/reference/commands/kusion-build","docId":"kusion/reference/commands/kusion-build"},{"type":"link","label":"kusion compile","href":"/docs/next/kusion/reference/commands/kusion-compile","docId":"kusion/reference/commands/kusion-compile"},{"type":"link","label":"kusion destroy","href":"/docs/next/kusion/reference/commands/kusion-destroy","docId":"kusion/reference/commands/kusion-destroy"},{"type":"link","label":"kusion init","href":"/docs/next/kusion/reference/commands/kusion-init","docId":"kusion/reference/commands/kusion-init"},{"type":"link","label":"kusion preview","href":"/docs/next/kusion/reference/commands/kusion-preview","docId":"kusion/reference/commands/kusion-preview"},{"type":"link","label":"kusion version","href":"/docs/next/kusion/reference/commands/kusion-version","docId":"kusion/reference/commands/kusion-version"},{"type":"link","label":"kusion workspace create","href":"/docs/next/kusion/reference/commands/kusion-workspace-create","docId":"kusion/reference/commands/kusion-workspace-create"},{"type":"link","label":"kusion workspace delete","href":"/docs/next/kusion/reference/commands/kusion-workspace-delete","docId":"kusion/reference/commands/kusion-workspace-delete"},{"type":"link","label":"kusion workspace list","href":"/docs/next/kusion/reference/commands/kusion-workspace-list","docId":"kusion/reference/commands/kusion-workspace-list"},{"type":"link","label":"kusion workspace show","href":"/docs/next/kusion/reference/commands/kusion-workspace-show","docId":"kusion/reference/commands/kusion-workspace-show"},{"type":"link","label":"kusion workspace update","href":"/docs/next/kusion/reference/commands/kusion-workspace-update","docId":"kusion/reference/commands/kusion-workspace-update"},{"type":"link","label":"kusion workspace","href":"/docs/next/kusion/reference/commands/kusion-workspace","docId":"kusion/reference/commands/kusion-workspace"}],"href":"/docs/next/kusion/reference/commands/"},{"type":"category","label":"Kusion Modules","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Catalog Models","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"appconfiguration","href":"/docs/next/kusion/reference/modules/catalog-models/app-configuration","docId":"kusion/reference/modules/catalog-models/app-configuration"},{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/catalog-models/database/mysql","docId":"kusion/reference/modules/catalog-models/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/catalog-models/database/postgres","docId":"kusion/reference/modules/catalog-models/database/postgres"}]},{"type":"category","label":"internal","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"common","href":"/docs/next/kusion/reference/modules/catalog-models/internal/common","docId":"kusion/reference/modules/catalog-models/internal/common"},{"type":"category","label":"container","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"lifecycle","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/","docId":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle"},{"type":"link","label":"probe","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/","docId":"kusion/reference/modules/catalog-models/internal/container/probe/probe"}],"href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/"},{"type":"category","label":"network","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/catalog-models/internal/network/port","docId":"kusion/reference/modules/catalog-models/internal/network/port"}]},{"type":"link","label":"secret","href":"/docs/next/kusion/reference/modules/catalog-models/internal/secret/","docId":"kusion/reference/modules/catalog-models/internal/secret/secret"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"prometheus","href":"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus","docId":"kusion/reference/modules/catalog-models/monitoring/prometheus"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule","docId":"kusion/reference/modules/catalog-models/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/catalog-models/workload/job","docId":"kusion/reference/modules/catalog-models/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/catalog-models/workload/service","docId":"kusion/reference/modules/catalog-models/workload/service"}]}]},{"type":"category","label":"Workspace Configs","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/workspace-configs/database/mysql","docId":"kusion/reference/modules/workspace-configs/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/workspace-configs/database/postgres","docId":"kusion/reference/modules/workspace-configs/database/postgres"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"monitoring","href":"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus","docId":"kusion/reference/modules/workspace-configs/monitoring/prometheus"}]},{"type":"category","label":"networking","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/workspace-configs/networking/port","docId":"kusion/reference/modules/workspace-configs/networking/port"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule","docId":"kusion/reference/modules/workspace-configs/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/job","docId":"kusion/reference/modules/workspace-configs/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/service","docId":"kusion/reference/modules/workspace-configs/workload/service"}]}]},{"type":"link","label":"Resource Naming Conventions","href":"/docs/next/kusion/reference/modules/naming-conventions","docId":"kusion/reference/modules/naming-conventions"}],"href":"/docs/next/kusion/reference/modules/"},{"type":"link","label":"Roadmap","href":"/docs/next/kusion/reference/roadmap","docId":"kusion/reference/roadmap"}]},{"type":"category","label":"FAQ","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/kusion/faq/install-error","docId":"kusion/faq/install-error"},{"type":"link","label":"KCL","href":"/docs/next/kusion/faq/kcl","docId":"kusion/faq/kcl"}]}]},{"type":"category","label":"operating","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/docs/next/operating/introduction/","docId":"operating/introduction/introduction"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/operating/started/install","docId":"operating/started/install"},{"type":"link","label":"Using KusionStack Operating to operate Pods gracefully","href":"/docs/next/operating/started/demo-graceful-operation","docId":"operating/started/demo-graceful-operation"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"PodOpsLifecycle","href":"/docs/next/operating/concepts/podopslifecycle","docId":"operating/concepts/podopslifecycle"}]},{"type":"category","label":"Manuals","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CollaSet","href":"/docs/next/operating/manuals/collaset","docId":"operating/manuals/collaset"},{"type":"link","label":"ResourceConsist","href":"/docs/next/operating/manuals/resourceconsist","docId":"operating/manuals/resourceconsist"},{"type":"link","label":"PodTransitionRule","href":"/docs/next/operating/manuals/podtransitionrule","docId":"operating/manuals/podtransitionrule"},{"type":"link","label":"PodDecoration","href":"/docs/next/operating/manuals/poddecoration","docId":"operating/manuals/poddecoration"}]}]}],"kusion":[{"type":"category","label":"What is Kusion?","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/","docId":"kusion/what-is-kusion/overview"},{"type":"link","label":"Kusion vs Other Software","href":"/docs/next/kusion/what-is-kusion/kusion-vs-x","docId":"kusion/what-is-kusion/kusion-vs-x"}]},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Install Kusion","href":"/docs/next/kusion/getting-started/install-kusion","docId":"kusion/getting-started/install-kusion"},{"type":"link","label":"Deliver the WordPress Application on Kubernetes","href":"/docs/next/kusion/getting-started/deliver-wordpress","docId":"kusion/getting-started/deliver-wordpress"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Project","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/project/overview","docId":"kusion/concepts/project/overview"},{"type":"link","label":"Project Configuration","href":"/docs/next/kusion/concepts/project/configuration","docId":"kusion/concepts/project/configuration"}]},{"type":"category","label":"Stack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/stack/overview","docId":"kusion/concepts/stack/overview"},{"type":"link","label":"Stack Configuration","href":"/docs/next/kusion/concepts/stack/configuration","docId":"kusion/concepts/stack/configuration"}]},{"type":"link","label":"Kusion Module","href":"/docs/next/kusion/concepts/kusion-module","docId":"kusion/concepts/kusion-module"},{"type":"link","label":"Workspace","href":"/docs/next/kusion/concepts/workspace","docId":"kusion/concepts/workspace"},{"type":"link","label":"AppConfiguration","href":"/docs/next/kusion/concepts/app-configuration","docId":"kusion/concepts/app-configuration"},{"type":"link","label":"Intent","href":"/docs/next/kusion/concepts/intent","docId":"kusion/concepts/intent"},{"type":"link","label":"Backend","href":"/docs/next/kusion/concepts/backend","docId":"kusion/concepts/backend"},{"type":"link","label":"Configuration","href":"/docs/next/kusion/concepts/configuration","docId":"kusion/concepts/configuration"},{"type":"link","label":"How Kusion Works?","href":"/docs/next/kusion/concepts/how-kusion-works","docId":"kusion/concepts/how-kusion-works"}]},{"type":"category","label":"Configuration Walkthrough","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration File Overview","href":"/docs/next/kusion/configuration-walkthrough/overview","docId":"kusion/configuration-walkthrough/overview"},{"type":"link","label":"KCL Basics","href":"/docs/next/kusion/configuration-walkthrough/kcl-basics","docId":"kusion/configuration-walkthrough/kcl-basics"},{"type":"link","label":"Base and Override","href":"/docs/next/kusion/configuration-walkthrough/base-override","docId":"kusion/configuration-walkthrough/base-override"},{"type":"link","label":"Workload","href":"/docs/next/kusion/configuration-walkthrough/workload","docId":"kusion/configuration-walkthrough/workload"},{"type":"link","label":"Application Networking","href":"/docs/next/kusion/configuration-walkthrough/networking","docId":"kusion/configuration-walkthrough/networking"},{"type":"link","label":"Managed Databases","href":"/docs/next/kusion/configuration-walkthrough/databse","docId":"kusion/configuration-walkthrough/databse"},{"type":"link","label":"Secrets","href":"/docs/next/kusion/configuration-walkthrough/secret","docId":"kusion/configuration-walkthrough/secret"},{"type":"link","label":"Application Monitoring","href":"/docs/next/kusion/configuration-walkthrough/monitoring","docId":"kusion/configuration-walkthrough/monitoring"},{"type":"link","label":"Operational Rules","href":"/docs/next/kusion/configuration-walkthrough/operational-rules","docId":"kusion/configuration-walkthrough/operational-rules"}]},{"type":"category","label":"User Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Cloud Resources","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deliver the WordPress Application with Cloud RDS","href":"/docs/next/kusion/user-guides/cloud-resources/database","docId":"kusion/user-guides/cloud-resources/database"},{"type":"link","label":"Expose Application Service Deployed on CSP Kubernetes","href":"/docs/next/kusion/user-guides/cloud-resources/expose-service","docId":"kusion/user-guides/cloud-resources/expose-service"}]},{"type":"category","label":"Kubernetes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application","href":"/docs/next/kusion/user-guides/working-with-k8s/deploy-application","docId":"kusion/user-guides/working-with-k8s/deploy-application"},{"type":"link","label":"Configure Containers","href":"/docs/next/kusion/user-guides/working-with-k8s/container","docId":"kusion/user-guides/working-with-k8s/container"},{"type":"link","label":"Expose Service","href":"/docs/next/kusion/user-guides/working-with-k8s/service","docId":"kusion/user-guides/working-with-k8s/service"},{"type":"link","label":"Upgrade Image","href":"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade","docId":"kusion/user-guides/working-with-k8s/image-upgrade"},{"type":"link","label":"Configure Resource Specification","href":"/docs/next/kusion/user-guides/working-with-k8s/resource-spec","docId":"kusion/user-guides/working-with-k8s/resource-spec"},{"type":"link","label":"Set up Operational Rules","href":"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules","docId":"kusion/user-guides/working-with-k8s/set-up-operational-rules"},{"type":"link","label":"Schedule a Job","href":"/docs/next/kusion/user-guides/working-with-k8s/job","docId":"kusion/user-guides/working-with-k8s/job"}]},{"type":"category","label":"Automated Observability","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configure Monitoring Behavior With Prometheus","href":"/docs/next/kusion/user-guides/observability/prometheus","docId":"kusion/user-guides/observability/prometheus"}]},{"type":"category","label":"GitHub Actions","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application Securely and Efficiently via GitHub Actions","href":"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions","docId":"kusion/user-guides/github-actions/deploy-application-via-github-actions"}]},{"type":"category","label":"Secrets Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Using Cloud Secrets Manager","href":"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets","docId":"kusion/user-guides/secrets-management/using-cloud-secrets"}]}]},{"type":"category","label":"Reference","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Kusion Commands","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"kusion apply","href":"/docs/next/kusion/reference/commands/kusion-apply","docId":"kusion/reference/commands/kusion-apply"},{"type":"link","label":"kusion build","href":"/docs/next/kusion/reference/commands/kusion-build","docId":"kusion/reference/commands/kusion-build"},{"type":"link","label":"kusion compile","href":"/docs/next/kusion/reference/commands/kusion-compile","docId":"kusion/reference/commands/kusion-compile"},{"type":"link","label":"kusion destroy","href":"/docs/next/kusion/reference/commands/kusion-destroy","docId":"kusion/reference/commands/kusion-destroy"},{"type":"link","label":"kusion init","href":"/docs/next/kusion/reference/commands/kusion-init","docId":"kusion/reference/commands/kusion-init"},{"type":"link","label":"kusion preview","href":"/docs/next/kusion/reference/commands/kusion-preview","docId":"kusion/reference/commands/kusion-preview"},{"type":"link","label":"kusion version","href":"/docs/next/kusion/reference/commands/kusion-version","docId":"kusion/reference/commands/kusion-version"},{"type":"link","label":"kusion workspace create","href":"/docs/next/kusion/reference/commands/kusion-workspace-create","docId":"kusion/reference/commands/kusion-workspace-create"},{"type":"link","label":"kusion workspace delete","href":"/docs/next/kusion/reference/commands/kusion-workspace-delete","docId":"kusion/reference/commands/kusion-workspace-delete"},{"type":"link","label":"kusion workspace list","href":"/docs/next/kusion/reference/commands/kusion-workspace-list","docId":"kusion/reference/commands/kusion-workspace-list"},{"type":"link","label":"kusion workspace show","href":"/docs/next/kusion/reference/commands/kusion-workspace-show","docId":"kusion/reference/commands/kusion-workspace-show"},{"type":"link","label":"kusion workspace update","href":"/docs/next/kusion/reference/commands/kusion-workspace-update","docId":"kusion/reference/commands/kusion-workspace-update"},{"type":"link","label":"kusion workspace","href":"/docs/next/kusion/reference/commands/kusion-workspace","docId":"kusion/reference/commands/kusion-workspace"}],"href":"/docs/next/kusion/reference/commands/"},{"type":"category","label":"Kusion Modules","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Catalog Models","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"appconfiguration","href":"/docs/next/kusion/reference/modules/catalog-models/app-configuration","docId":"kusion/reference/modules/catalog-models/app-configuration"},{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/catalog-models/database/mysql","docId":"kusion/reference/modules/catalog-models/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/catalog-models/database/postgres","docId":"kusion/reference/modules/catalog-models/database/postgres"}]},{"type":"category","label":"internal","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"common","href":"/docs/next/kusion/reference/modules/catalog-models/internal/common","docId":"kusion/reference/modules/catalog-models/internal/common"},{"type":"category","label":"container","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"lifecycle","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/","docId":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle"},{"type":"link","label":"probe","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/","docId":"kusion/reference/modules/catalog-models/internal/container/probe/probe"}],"href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/"},{"type":"category","label":"network","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/catalog-models/internal/network/port","docId":"kusion/reference/modules/catalog-models/internal/network/port"}]},{"type":"link","label":"secret","href":"/docs/next/kusion/reference/modules/catalog-models/internal/secret/","docId":"kusion/reference/modules/catalog-models/internal/secret/secret"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"prometheus","href":"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus","docId":"kusion/reference/modules/catalog-models/monitoring/prometheus"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule","docId":"kusion/reference/modules/catalog-models/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/catalog-models/workload/job","docId":"kusion/reference/modules/catalog-models/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/catalog-models/workload/service","docId":"kusion/reference/modules/catalog-models/workload/service"}]}]},{"type":"category","label":"Workspace Configs","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/workspace-configs/database/mysql","docId":"kusion/reference/modules/workspace-configs/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/workspace-configs/database/postgres","docId":"kusion/reference/modules/workspace-configs/database/postgres"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"monitoring","href":"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus","docId":"kusion/reference/modules/workspace-configs/monitoring/prometheus"}]},{"type":"category","label":"networking","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/workspace-configs/networking/port","docId":"kusion/reference/modules/workspace-configs/networking/port"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule","docId":"kusion/reference/modules/workspace-configs/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/job","docId":"kusion/reference/modules/workspace-configs/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/service","docId":"kusion/reference/modules/workspace-configs/workload/service"}]}]},{"type":"link","label":"Resource Naming Conventions","href":"/docs/next/kusion/reference/modules/naming-conventions","docId":"kusion/reference/modules/naming-conventions"}],"href":"/docs/next/kusion/reference/modules/"},{"type":"link","label":"Roadmap","href":"/docs/next/kusion/reference/roadmap","docId":"kusion/reference/roadmap"}]},{"type":"category","label":"FAQ","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/kusion/faq/install-error","docId":"kusion/faq/install-error"},{"type":"link","label":"KCL","href":"/docs/next/kusion/faq/kcl","docId":"kusion/faq/kcl"}]}],"operating":[{"type":"link","label":"Introduction","href":"/docs/next/operating/introduction/","docId":"operating/introduction/introduction"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/operating/started/install","docId":"operating/started/install"},{"type":"link","label":"Using KusionStack Operating to operate Pods gracefully","href":"/docs/next/operating/started/demo-graceful-operation","docId":"operating/started/demo-graceful-operation"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"PodOpsLifecycle","href":"/docs/next/operating/concepts/podopslifecycle","docId":"operating/concepts/podopslifecycle"}]},{"type":"category","label":"Manuals","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CollaSet","href":"/docs/next/operating/manuals/collaset","docId":"operating/manuals/collaset"},{"type":"link","label":"ResourceConsist","href":"/docs/next/operating/manuals/resourceconsist","docId":"operating/manuals/resourceconsist"},{"type":"link","label":"PodTransitionRule","href":"/docs/next/operating/manuals/podtransitionrule","docId":"operating/manuals/podtransitionrule"},{"type":"link","label":"PodDecoration","href":"/docs/next/operating/manuals/poddecoration","docId":"operating/manuals/poddecoration"}]}],"community":[{"type":"link","label":"Community","href":"/docs/next/community/intro/","docId":"community/intro/intro"}],"ctrlmesh":[{"type":"link","label":"Introduction","href":"/docs/next/ctrlmesh/intro/","docId":"ctrlmesh/intro/intro"},{"type":"link","label":"Concepts","href":"/docs/next/ctrlmesh/concepts/","docId":"ctrlmesh/concepts/concepts"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/ctrlmesh/started/install","docId":"ctrlmesh/started/install"},{"type":"link","label":"Try a Sample","href":"/docs/next/ctrlmesh/started/try","docId":"ctrlmesh/started/try"}]},{"type":"link","label":"FAQ","href":"/docs/next/ctrlmesh/faq/","docId":"ctrlmesh/faq/faq"}]},"docs":{"community/intro/intro":{"id":"community/intro/intro","title":"Community","description":"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.","sidebar":"community"},"ctrlmesh/concepts/concepts":{"id":"ctrlmesh/concepts/concepts","title":"Concepts","description":"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.","sidebar":"ctrlmesh"},"ctrlmesh/faq/faq":{"id":"ctrlmesh/faq/faq","title":"FAQ","description":"","sidebar":"ctrlmesh"},"ctrlmesh/intro/intro":{"id":"ctrlmesh/intro/intro","title":"Controller Mesh","description":"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.","sidebar":"ctrlmesh"},"ctrlmesh/started/install":{"id":"ctrlmesh/started/install","title":"Installation","description":"Install with helm","sidebar":"ctrlmesh"},"ctrlmesh/started/try":{"id":"ctrlmesh/started/try","title":"Try a Sample","description":"This guide lets you quickly evaluate KusionStack Controller Mesh.","sidebar":"ctrlmesh"},"kusion/concepts/app-configuration":{"id":"kusion/concepts/app-configuration","title":"AppConfiguration","description":"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and AppConfiguration model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself.","sidebar":"kusion"},"kusion/concepts/backend":{"id":"kusion/concepts/backend","title":"Backend","description":"Backend is Kusion\'s storage, which defines the place to store Workspace, Spec and State. By default, Kusion uses the local type of backend to store the state on the local disk. While in the scenario of team collaboration, the Workspace, Spec and State can be stored on a remote backend, such as mysql, oss and s3, to allow multiple users\' access.","sidebar":"kusion"},"kusion/concepts/configuration":{"id":"kusion/concepts/configuration","title":"Configuration","description":"Kusion can be configured with some global settings, which are separate from the AppConfiguration written by the application developers and the workspace configurations written by the platform engineers.","sidebar":"kusion"},"kusion/concepts/how-kusion-works":{"id":"kusion/concepts/how-kusion-works","title":"How Kusion Works?","description":"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Modules defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.","sidebar":"kusion"},"kusion/concepts/intent":{"id":"kusion/concepts/intent","title":"Intent","description":"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.","sidebar":"kusion"},"kusion/concepts/kusion-module":{"id":"kusion/concepts/kusion-module","title":"Kusion Module","description":"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:","sidebar":"kusion"},"kusion/concepts/project/configuration":{"id":"kusion/concepts/project/configuration","title":"Project Configuration","description":"Users can add config items of the project in project.yaml, such as the project name, generator type, Prometheus monitoring, etc.","sidebar":"kusion"},"kusion/concepts/project/overview":{"id":"kusion/concepts/project/overview","title":"Overview","description":"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications.","sidebar":"kusion"},"kusion/concepts/stack/configuration":{"id":"kusion/concepts/stack/configuration","title":"Stack Configuration","description":"Users can add config items of the stack in stack.yaml, such as the stack name, etc.","sidebar":"kusion"},"kusion/concepts/stack/overview":{"id":"kusion/concepts/stack/overview","title":"Overview","description":"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production.","sidebar":"kusion"},"kusion/concepts/workspace":{"id":"kusion/concepts/workspace","title":"Workspace","description":"Definition","sidebar":"kusion"},"kusion/configuration-walkthrough/base-override":{"id":"kusion/configuration-walkthrough/base-override","title":"Base and Override","description":"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.","sidebar":"kusion"},"kusion/configuration-walkthrough/databse":{"id":"kusion/configuration-walkthrough/databse","title":"Managed Databases","description":"You could also specify a database needed for the application. That can be achieved via a mysql or a postgres module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.","sidebar":"kusion"},"kusion/configuration-walkthrough/kcl-basics":{"id":"kusion/configuration-walkthrough/kcl-basics","title":"KCL Basics","description":"Table of Content","sidebar":"kusion"},"kusion/configuration-walkthrough/monitoring":{"id":"kusion/configuration-walkthrough/monitoring","title":"Application Monitoring","description":"You could also specify the collection of monitoring requirements for the application. That can be achieved via a monitoring module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.","sidebar":"kusion"},"kusion/configuration-walkthrough/networking":{"id":"kusion/configuration-walkthrough/networking","title":"Application Networking","description":"In addition to configuring application\'s container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed. You can specify a network module in the accessories field in AppConfiguration to achieve that.","sidebar":"kusion"},"kusion/configuration-walkthrough/operational-rules":{"id":"kusion/configuration-walkthrough/operational-rules","title":"Operational Rules","description":"You could also specify the collection of operational rule requirements for the application. That can be achieved via a opsrule module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that. Operational rules are used as a preemptive measure to police and stop any unwanted changes.","sidebar":"kusion"},"kusion/configuration-walkthrough/overview":{"id":"kusion/configuration-walkthrough/overview","title":"Configuration File Overview","description":"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.","sidebar":"kusion"},"kusion/configuration-walkthrough/secret":{"id":"kusion/configuration-walkthrough/secret","title":"Secrets","description":"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers.","sidebar":"kusion"},"kusion/configuration-walkthrough/workload":{"id":"kusion/configuration-walkthrough/workload","title":"Workload","description":"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application.","sidebar":"kusion"},"kusion/faq/install-error":{"id":"kusion/faq/install-error","title":"Installation","description":"1. Could not find libintl.dylib","sidebar":"kusion"},"kusion/faq/kcl":{"id":"kusion/faq/kcl","title":"KCL","description":"Visit the KCL website for more documents.","sidebar":"kusion"},"kusion/getting-started/deliver-wordpress":{"id":"kusion/getting-started/deliver-wordpress","title":"Deliver the WordPress Application on Kubernetes","description":"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.","sidebar":"kusion"},"kusion/getting-started/install-kusion":{"id":"kusion/getting-started/install-kusion","title":"Install Kusion","description":"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.","sidebar":"kusion"},"kusion/reference/commands/index":{"id":"kusion/reference/commands/index","title":"Kusion Commands","description":"Kusion is the Platform Orchestrator of KusionStack","sidebar":"kusion"},"kusion/reference/commands/kusion-apply":{"id":"kusion/reference/commands/kusion-apply","title":"kusion apply","description":"Apply the operational intent of various resources to multiple runtimes","sidebar":"kusion"},"kusion/reference/commands/kusion-build":{"id":"kusion/reference/commands/kusion-build","title":"kusion build","description":"Build Kusion modules in a Stack to the Intent","sidebar":"kusion"},"kusion/reference/commands/kusion-compile":{"id":"kusion/reference/commands/kusion-compile","title":"kusion compile","description":"Deprecated: Use \'kusion build\' to generate the Intent instead","sidebar":"kusion"},"kusion/reference/commands/kusion-destroy":{"id":"kusion/reference/commands/kusion-destroy","title":"kusion destroy","description":"Destroy resources within the stack.","sidebar":"kusion"},"kusion/reference/commands/kusion-init":{"id":"kusion/reference/commands/kusion-init","title":"kusion init","description":"Initialize the scaffolding for a project","sidebar":"kusion"},"kusion/reference/commands/kusion-preview":{"id":"kusion/reference/commands/kusion-preview","title":"kusion preview","description":"Preview a series of resource changes within the stack","sidebar":"kusion"},"kusion/reference/commands/kusion-version":{"id":"kusion/reference/commands/kusion-version","title":"kusion version","description":"Print the Kusion version information for the current context","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace":{"id":"kusion/reference/commands/kusion-workspace","title":"kusion workspace","description":"Workspace is a logical concept representing a target that stacks will be deployed to","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-create":{"id":"kusion/reference/commands/kusion-workspace-create","title":"kusion workspace create","description":"Create a new workspace","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-delete":{"id":"kusion/reference/commands/kusion-workspace-delete","title":"kusion workspace delete","description":"Delete a workspace","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-list":{"id":"kusion/reference/commands/kusion-workspace-list","title":"kusion workspace list","description":"List all workspace names","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-show":{"id":"kusion/reference/commands/kusion-workspace-show","title":"kusion workspace show","description":"Show a workspace configuration","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-update":{"id":"kusion/reference/commands/kusion-workspace-update","title":"kusion workspace update","description":"Update a workspace configuration","sidebar":"kusion"},"kusion/reference/modules/catalog-models/app-configuration":{"id":"kusion/reference/modules/catalog-models/app-configuration","title":"appconfiguration","description":"Schema AppConfiguration","sidebar":"kusion"},"kusion/reference/modules/catalog-models/database/mysql":{"id":"kusion/reference/modules/catalog-models/database/mysql","title":"mysql","description":"Schema MySQL","sidebar":"kusion"},"kusion/reference/modules/catalog-models/database/postgres":{"id":"kusion/reference/modules/catalog-models/database/postgres","title":"postgres","description":"Schema PostgreSQL","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/common":{"id":"kusion/reference/modules/catalog-models/internal/common","title":"common","description":"Schema WorkloadBase","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/container/container":{"id":"kusion/reference/modules/catalog-models/internal/container/container","title":"container","description":"Schema Container","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle":{"id":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle","title":"lifecycle","description":"Schema Lifecycle","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/container/probe/probe":{"id":"kusion/reference/modules/catalog-models/internal/container/probe/probe","title":"probe","description":"Schema Probe","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/network/port":{"id":"kusion/reference/modules/catalog-models/internal/network/port","title":"port","description":"Schema Port","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/secret/secret":{"id":"kusion/reference/modules/catalog-models/internal/secret/secret","title":"secret","description":"Schema Secret","sidebar":"kusion"},"kusion/reference/modules/catalog-models/monitoring/prometheus":{"id":"kusion/reference/modules/catalog-models/monitoring/prometheus","title":"prometheus","description":"Schema Prometheus","sidebar":"kusion"},"kusion/reference/modules/catalog-models/trait/opsrule":{"id":"kusion/reference/modules/catalog-models/trait/opsrule","title":"opsrule","description":"Schema OpsRule","sidebar":"kusion"},"kusion/reference/modules/catalog-models/workload/job":{"id":"kusion/reference/modules/catalog-models/workload/job","title":"job","description":"Schemas","sidebar":"kusion"},"kusion/reference/modules/catalog-models/workload/service":{"id":"kusion/reference/modules/catalog-models/workload/service","title":"service","description":"Schemas","sidebar":"kusion"},"kusion/reference/modules/index":{"id":"kusion/reference/modules/index","title":"Kusion Modules","description":"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.","sidebar":"kusion"},"kusion/reference/modules/naming-conventions":{"id":"kusion/reference/modules/naming-conventions","title":"Resource Naming Conventions","description":"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users\' awareness. This document will introduce the naming conventions for these related resources.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/database/mysql":{"id":"kusion/reference/modules/workspace-configs/database/mysql","title":"mysql","description":"Module MySQL","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/database/postgres":{"id":"kusion/reference/modules/workspace-configs/database/postgres","title":"postgres","description":"Module PostgreSQL","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/monitoring/prometheus":{"id":"kusion/reference/modules/workspace-configs/monitoring/prometheus","title":"monitoring","description":"monitoring can be used to define workspace-level monitoring configurations.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/networking/port":{"id":"kusion/reference/modules/workspace-configs/networking/port","title":"port","description":"port can be used to define workspace-level networking configurations.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/trait/opsrule":{"id":"kusion/reference/modules/workspace-configs/trait/opsrule","title":"opsrule","description":"opsrule can be used to define workspace-level operational rule configurations.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/workload/job":{"id":"kusion/reference/modules/workspace-configs/workload/job","title":"job","description":"job can be used to define workspace-level job configuration.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/workload/service":{"id":"kusion/reference/modules/workspace-configs/workload/service","title":"service","description":"service can be used to define workspace-level service configuration.","sidebar":"kusion"},"kusion/reference/roadmap":{"id":"kusion/reference/roadmap","title":"Roadmap","description":"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker","sidebar":"kusion"},"kusion/user-guides/cloud-resources/database":{"id":"kusion/user-guides/cloud-resources/database","title":"Deliver the WordPress Application with Cloud RDS","description":"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.","sidebar":"kusion"},"kusion/user-guides/cloud-resources/expose-service":{"id":"kusion/user-guides/cloud-resources/expose-service","title":"Expose Application Service Deployed on CSP Kubernetes","description":"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.","sidebar":"kusion"},"kusion/user-guides/github-actions/deploy-application-via-github-actions":{"id":"kusion/user-guides/github-actions/deploy-application-via-github-actions","title":"Deploy Application Securely and Efficiently via GitHub Actions","description":"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.","sidebar":"kusion"},"kusion/user-guides/observability/prometheus":{"id":"kusion/user-guides/observability/prometheus","title":"Configure Monitoring Behavior With Prometheus","description":"This document provides the step-by-step instruction to set up monitoring for your application.","sidebar":"kusion"},"kusion/user-guides/secrets-management/using-cloud-secrets":{"id":"kusion/user-guides/secrets-management/using-cloud-secrets","title":"Using Cloud Secrets Manager","description":"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/container":{"id":"kusion/user-guides/working-with-k8s/container","title":"Configure Containers","description":"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/deploy-application":{"id":"kusion/user-guides/working-with-k8s/deploy-application","title":"Deploy Application","description":"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/image-upgrade":{"id":"kusion/user-guides/working-with-k8s/image-upgrade","title":"Upgrade Image","description":"You can declare the application\'s container image via image field of the Container schema.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/job":{"id":"kusion/user-guides/working-with-k8s/job","title":"Schedule a Job","description":"The guides above provide examples on how to configure workloads of the type wl.Service, which is typically used for long-running web applications that should \\"never\\" go down. Alternatively, you could also schedule another kind of workload profile, namely wl.Job which corresponds to a one-off or recurring execution of tasks that run to completion and then stop.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/resource-spec":{"id":"kusion/user-guides/working-with-k8s/resource-spec","title":"Configure Resource Specification","description":"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/service":{"id":"kusion/user-guides/working-with-k8s/service","title":"Expose Service","description":"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don\'t match the service ports), so that it can be consumed by other applications.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/set-up-operational-rules":{"id":"kusion/user-guides/working-with-k8s/set-up-operational-rules","title":"Set up Operational Rules","description":"You can set up operational rules in the AppConfiguration model via the opsRule field and corresponding platform configurations in the workspace directory. The opsRule is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes.","sidebar":"kusion"},"kusion/what-is-kusion/kusion-vs-x":{"id":"kusion/what-is-kusion/kusion-vs-x","title":"Kusion vs Other Software","description":"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.","sidebar":"kusion"},"kusion/what-is-kusion/overview":{"id":"kusion/what-is-kusion/overview","title":"Overview","description":"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.","sidebar":"kusion"},"operating/concepts/podopslifecycle":{"id":"operating/concepts/podopslifecycle","title":"PodOpsLifecycle","description":"Background","sidebar":"operating"},"operating/introduction/introduction":{"id":"operating/introduction/introduction","title":"What is KusionStack Operating?","description":"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,","sidebar":"operating"},"operating/manuals/collaset":{"id":"operating/manuals/collaset","title":"CollaSet","description":"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.","sidebar":"operating"},"operating/manuals/poddecoration":{"id":"operating/manuals/poddecoration","title":"PodDecoration","description":"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.","sidebar":"operating"},"operating/manuals/podtransitionrule":{"id":"operating/manuals/podtransitionrule","title":"PodTransitionRule","description":"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.","sidebar":"operating"},"operating/manuals/resourceconsist":{"id":"operating/manuals/resourceconsist","title":"ResourceConsist","description":"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following","sidebar":"operating"},"operating/started/demo-graceful-operation":{"id":"operating/started/demo-graceful-operation","title":"Using KusionStack Operating to operate Pods gracefully","description":"Applications always provide its service along with traffic routing.","sidebar":"operating"},"operating/started/install":{"id":"operating/started/install","title":"Installation","description":"Install with helm","sidebar":"operating"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.c61778ca.js b/assets/js/935f2afb.c61778ca.js deleted file mode 100644 index 2627b49199c..00000000000 --- a/assets/js/935f2afb.c61778ca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"v0.11 \ud83d\udea7","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"docs":[{"type":"category","label":"community","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Community","href":"/docs/next/community/intro/","docId":"community/intro/intro"}]},{"type":"category","label":"ctrlmesh","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/docs/next/ctrlmesh/intro/","docId":"ctrlmesh/intro/intro"},{"type":"link","label":"Concepts","href":"/docs/next/ctrlmesh/concepts/","docId":"ctrlmesh/concepts/concepts"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/ctrlmesh/started/install","docId":"ctrlmesh/started/install"},{"type":"link","label":"Try a Sample","href":"/docs/next/ctrlmesh/started/try","docId":"ctrlmesh/started/try"}]},{"type":"link","label":"FAQ","href":"/docs/next/ctrlmesh/faq/","docId":"ctrlmesh/faq/faq"}]},{"type":"category","label":"kusion","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"What is Kusion?","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/","docId":"kusion/what-is-kusion/overview"},{"type":"link","label":"Kusion vs Other Software","href":"/docs/next/kusion/what-is-kusion/kusion-vs-x","docId":"kusion/what-is-kusion/kusion-vs-x"}]},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Install Kusion","href":"/docs/next/kusion/getting-started/install-kusion","docId":"kusion/getting-started/install-kusion"},{"type":"link","label":"Deliver the WordPress Application on Kubernetes","href":"/docs/next/kusion/getting-started/deliver-wordpress","docId":"kusion/getting-started/deliver-wordpress"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Project","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/project/overview","docId":"kusion/concepts/project/overview"},{"type":"link","label":"Project Configuration","href":"/docs/next/kusion/concepts/project/configuration","docId":"kusion/concepts/project/configuration"}]},{"type":"category","label":"Stack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/stack/overview","docId":"kusion/concepts/stack/overview"},{"type":"link","label":"Stack Configuration","href":"/docs/next/kusion/concepts/stack/configuration","docId":"kusion/concepts/stack/configuration"}]},{"type":"link","label":"Kusion Module","href":"/docs/next/kusion/concepts/kusion-module","docId":"kusion/concepts/kusion-module"},{"type":"link","label":"Workspace","href":"/docs/next/kusion/concepts/workspace","docId":"kusion/concepts/workspace"},{"type":"link","label":"AppConfiguration","href":"/docs/next/kusion/concepts/app-configuration","docId":"kusion/concepts/app-configuration"},{"type":"link","label":"Intent","href":"/docs/next/kusion/concepts/intent","docId":"kusion/concepts/intent"},{"type":"link","label":"Backend Configuration","href":"/docs/next/kusion/concepts/backend-configuration","docId":"kusion/concepts/backend-configuration"},{"type":"link","label":"Configuration","href":"/docs/next/kusion/concepts/configuration","docId":"kusion/concepts/configuration"},{"type":"link","label":"How Kusion Works?","href":"/docs/next/kusion/concepts/how-kusion-works","docId":"kusion/concepts/how-kusion-works"}]},{"type":"category","label":"Configuration Walkthrough","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration File Overview","href":"/docs/next/kusion/configuration-walkthrough/overview","docId":"kusion/configuration-walkthrough/overview"},{"type":"link","label":"KCL Basics","href":"/docs/next/kusion/configuration-walkthrough/kcl-basics","docId":"kusion/configuration-walkthrough/kcl-basics"},{"type":"link","label":"Base and Override","href":"/docs/next/kusion/configuration-walkthrough/base-override","docId":"kusion/configuration-walkthrough/base-override"},{"type":"link","label":"Workload","href":"/docs/next/kusion/configuration-walkthrough/workload","docId":"kusion/configuration-walkthrough/workload"},{"type":"link","label":"Application Networking","href":"/docs/next/kusion/configuration-walkthrough/networking","docId":"kusion/configuration-walkthrough/networking"},{"type":"link","label":"Managed Databases","href":"/docs/next/kusion/configuration-walkthrough/databse","docId":"kusion/configuration-walkthrough/databse"},{"type":"link","label":"Secrets","href":"/docs/next/kusion/configuration-walkthrough/secret","docId":"kusion/configuration-walkthrough/secret"},{"type":"link","label":"Application Monitoring","href":"/docs/next/kusion/configuration-walkthrough/monitoring","docId":"kusion/configuration-walkthrough/monitoring"},{"type":"link","label":"Operational Rules","href":"/docs/next/kusion/configuration-walkthrough/operational-rules","docId":"kusion/configuration-walkthrough/operational-rules"}]},{"type":"category","label":"User Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Cloud Resources","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deliver the WordPress Application with Cloud RDS","href":"/docs/next/kusion/user-guides/cloud-resources/database","docId":"kusion/user-guides/cloud-resources/database"},{"type":"link","label":"Expose Application Service Deployed on CSP Kubernetes","href":"/docs/next/kusion/user-guides/cloud-resources/expose-service","docId":"kusion/user-guides/cloud-resources/expose-service"}]},{"type":"category","label":"Kubernetes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application","href":"/docs/next/kusion/user-guides/working-with-k8s/deploy-application","docId":"kusion/user-guides/working-with-k8s/deploy-application"},{"type":"link","label":"Configure Containers","href":"/docs/next/kusion/user-guides/working-with-k8s/container","docId":"kusion/user-guides/working-with-k8s/container"},{"type":"link","label":"Expose Service","href":"/docs/next/kusion/user-guides/working-with-k8s/service","docId":"kusion/user-guides/working-with-k8s/service"},{"type":"link","label":"Upgrade Image","href":"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade","docId":"kusion/user-guides/working-with-k8s/image-upgrade"},{"type":"link","label":"Configure Resource Specification","href":"/docs/next/kusion/user-guides/working-with-k8s/resource-spec","docId":"kusion/user-guides/working-with-k8s/resource-spec"},{"type":"link","label":"Set up Operational Rules","href":"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules","docId":"kusion/user-guides/working-with-k8s/set-up-operational-rules"},{"type":"link","label":"Schedule a Job","href":"/docs/next/kusion/user-guides/working-with-k8s/job","docId":"kusion/user-guides/working-with-k8s/job"}]},{"type":"category","label":"Automated Observability","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configure Monitoring Behavior With Prometheus","href":"/docs/next/kusion/user-guides/observability/prometheus","docId":"kusion/user-guides/observability/prometheus"}]},{"type":"category","label":"GitHub Actions","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application Securely and Efficiently via GitHub Actions","href":"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions","docId":"kusion/user-guides/github-actions/deploy-application-via-github-actions"}]},{"type":"category","label":"Secrets Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Using Cloud Secrets Manager","href":"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets","docId":"kusion/user-guides/secrets-management/using-cloud-secrets"}]}]},{"type":"category","label":"Reference","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Kusion Commands","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"kusion apply","href":"/docs/next/kusion/reference/commands/kusion-apply","docId":"kusion/reference/commands/kusion-apply"},{"type":"link","label":"kusion build","href":"/docs/next/kusion/reference/commands/kusion-build","docId":"kusion/reference/commands/kusion-build"},{"type":"link","label":"kusion compile","href":"/docs/next/kusion/reference/commands/kusion-compile","docId":"kusion/reference/commands/kusion-compile"},{"type":"link","label":"kusion destroy","href":"/docs/next/kusion/reference/commands/kusion-destroy","docId":"kusion/reference/commands/kusion-destroy"},{"type":"link","label":"kusion init","href":"/docs/next/kusion/reference/commands/kusion-init","docId":"kusion/reference/commands/kusion-init"},{"type":"link","label":"kusion preview","href":"/docs/next/kusion/reference/commands/kusion-preview","docId":"kusion/reference/commands/kusion-preview"},{"type":"link","label":"kusion version","href":"/docs/next/kusion/reference/commands/kusion-version","docId":"kusion/reference/commands/kusion-version"},{"type":"link","label":"kusion workspace create","href":"/docs/next/kusion/reference/commands/kusion-workspace-create","docId":"kusion/reference/commands/kusion-workspace-create"},{"type":"link","label":"kusion workspace delete","href":"/docs/next/kusion/reference/commands/kusion-workspace-delete","docId":"kusion/reference/commands/kusion-workspace-delete"},{"type":"link","label":"kusion workspace list","href":"/docs/next/kusion/reference/commands/kusion-workspace-list","docId":"kusion/reference/commands/kusion-workspace-list"},{"type":"link","label":"kusion workspace show","href":"/docs/next/kusion/reference/commands/kusion-workspace-show","docId":"kusion/reference/commands/kusion-workspace-show"},{"type":"link","label":"kusion workspace update","href":"/docs/next/kusion/reference/commands/kusion-workspace-update","docId":"kusion/reference/commands/kusion-workspace-update"},{"type":"link","label":"kusion workspace","href":"/docs/next/kusion/reference/commands/kusion-workspace","docId":"kusion/reference/commands/kusion-workspace"}],"href":"/docs/next/kusion/reference/commands/"},{"type":"category","label":"Kusion Modules","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Catalog Models","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"appconfiguration","href":"/docs/next/kusion/reference/modules/catalog-models/app-configuration","docId":"kusion/reference/modules/catalog-models/app-configuration"},{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/catalog-models/database/mysql","docId":"kusion/reference/modules/catalog-models/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/catalog-models/database/postgres","docId":"kusion/reference/modules/catalog-models/database/postgres"}]},{"type":"category","label":"internal","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"common","href":"/docs/next/kusion/reference/modules/catalog-models/internal/common","docId":"kusion/reference/modules/catalog-models/internal/common"},{"type":"category","label":"container","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"lifecycle","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/","docId":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle"},{"type":"link","label":"probe","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/","docId":"kusion/reference/modules/catalog-models/internal/container/probe/probe"}],"href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/"},{"type":"category","label":"network","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/catalog-models/internal/network/port","docId":"kusion/reference/modules/catalog-models/internal/network/port"}]},{"type":"link","label":"secret","href":"/docs/next/kusion/reference/modules/catalog-models/internal/secret/","docId":"kusion/reference/modules/catalog-models/internal/secret/secret"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"prometheus","href":"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus","docId":"kusion/reference/modules/catalog-models/monitoring/prometheus"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule","docId":"kusion/reference/modules/catalog-models/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/catalog-models/workload/job","docId":"kusion/reference/modules/catalog-models/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/catalog-models/workload/service","docId":"kusion/reference/modules/catalog-models/workload/service"}]}]},{"type":"category","label":"Workspace Configs","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/workspace-configs/database/mysql","docId":"kusion/reference/modules/workspace-configs/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/workspace-configs/database/postgres","docId":"kusion/reference/modules/workspace-configs/database/postgres"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"monitoring","href":"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus","docId":"kusion/reference/modules/workspace-configs/monitoring/prometheus"}]},{"type":"category","label":"networking","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/workspace-configs/networking/port","docId":"kusion/reference/modules/workspace-configs/networking/port"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule","docId":"kusion/reference/modules/workspace-configs/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/job","docId":"kusion/reference/modules/workspace-configs/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/service","docId":"kusion/reference/modules/workspace-configs/workload/service"}]}]},{"type":"link","label":"Resource Naming Conventions","href":"/docs/next/kusion/reference/modules/naming-conventions","docId":"kusion/reference/modules/naming-conventions"}],"href":"/docs/next/kusion/reference/modules/"},{"type":"link","label":"Roadmap","href":"/docs/next/kusion/reference/roadmap","docId":"kusion/reference/roadmap"}]},{"type":"category","label":"FAQ","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/kusion/faq/install-error","docId":"kusion/faq/install-error"},{"type":"link","label":"KCL","href":"/docs/next/kusion/faq/kcl","docId":"kusion/faq/kcl"}]}]},{"type":"category","label":"operating","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/docs/next/operating/introduction/","docId":"operating/introduction/introduction"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/operating/started/install","docId":"operating/started/install"},{"type":"link","label":"Using KusionStack Operating to operate Pods gracefully","href":"/docs/next/operating/started/demo-graceful-operation","docId":"operating/started/demo-graceful-operation"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"PodOpsLifecycle","href":"/docs/next/operating/concepts/podopslifecycle","docId":"operating/concepts/podopslifecycle"}]},{"type":"category","label":"Manuals","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CollaSet","href":"/docs/next/operating/manuals/collaset","docId":"operating/manuals/collaset"},{"type":"link","label":"ResourceConsist","href":"/docs/next/operating/manuals/resourceconsist","docId":"operating/manuals/resourceconsist"},{"type":"link","label":"PodTransitionRule","href":"/docs/next/operating/manuals/podtransitionrule","docId":"operating/manuals/podtransitionrule"},{"type":"link","label":"PodDecoration","href":"/docs/next/operating/manuals/poddecoration","docId":"operating/manuals/poddecoration"}]}]}],"kusion":[{"type":"category","label":"What is Kusion?","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/","docId":"kusion/what-is-kusion/overview"},{"type":"link","label":"Kusion vs Other Software","href":"/docs/next/kusion/what-is-kusion/kusion-vs-x","docId":"kusion/what-is-kusion/kusion-vs-x"}]},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Install Kusion","href":"/docs/next/kusion/getting-started/install-kusion","docId":"kusion/getting-started/install-kusion"},{"type":"link","label":"Deliver the WordPress Application on Kubernetes","href":"/docs/next/kusion/getting-started/deliver-wordpress","docId":"kusion/getting-started/deliver-wordpress"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Project","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/project/overview","docId":"kusion/concepts/project/overview"},{"type":"link","label":"Project Configuration","href":"/docs/next/kusion/concepts/project/configuration","docId":"kusion/concepts/project/configuration"}]},{"type":"category","label":"Stack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/docs/next/kusion/concepts/stack/overview","docId":"kusion/concepts/stack/overview"},{"type":"link","label":"Stack Configuration","href":"/docs/next/kusion/concepts/stack/configuration","docId":"kusion/concepts/stack/configuration"}]},{"type":"link","label":"Kusion Module","href":"/docs/next/kusion/concepts/kusion-module","docId":"kusion/concepts/kusion-module"},{"type":"link","label":"Workspace","href":"/docs/next/kusion/concepts/workspace","docId":"kusion/concepts/workspace"},{"type":"link","label":"AppConfiguration","href":"/docs/next/kusion/concepts/app-configuration","docId":"kusion/concepts/app-configuration"},{"type":"link","label":"Intent","href":"/docs/next/kusion/concepts/intent","docId":"kusion/concepts/intent"},{"type":"link","label":"Backend Configuration","href":"/docs/next/kusion/concepts/backend-configuration","docId":"kusion/concepts/backend-configuration"},{"type":"link","label":"Configuration","href":"/docs/next/kusion/concepts/configuration","docId":"kusion/concepts/configuration"},{"type":"link","label":"How Kusion Works?","href":"/docs/next/kusion/concepts/how-kusion-works","docId":"kusion/concepts/how-kusion-works"}]},{"type":"category","label":"Configuration Walkthrough","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration File Overview","href":"/docs/next/kusion/configuration-walkthrough/overview","docId":"kusion/configuration-walkthrough/overview"},{"type":"link","label":"KCL Basics","href":"/docs/next/kusion/configuration-walkthrough/kcl-basics","docId":"kusion/configuration-walkthrough/kcl-basics"},{"type":"link","label":"Base and Override","href":"/docs/next/kusion/configuration-walkthrough/base-override","docId":"kusion/configuration-walkthrough/base-override"},{"type":"link","label":"Workload","href":"/docs/next/kusion/configuration-walkthrough/workload","docId":"kusion/configuration-walkthrough/workload"},{"type":"link","label":"Application Networking","href":"/docs/next/kusion/configuration-walkthrough/networking","docId":"kusion/configuration-walkthrough/networking"},{"type":"link","label":"Managed Databases","href":"/docs/next/kusion/configuration-walkthrough/databse","docId":"kusion/configuration-walkthrough/databse"},{"type":"link","label":"Secrets","href":"/docs/next/kusion/configuration-walkthrough/secret","docId":"kusion/configuration-walkthrough/secret"},{"type":"link","label":"Application Monitoring","href":"/docs/next/kusion/configuration-walkthrough/monitoring","docId":"kusion/configuration-walkthrough/monitoring"},{"type":"link","label":"Operational Rules","href":"/docs/next/kusion/configuration-walkthrough/operational-rules","docId":"kusion/configuration-walkthrough/operational-rules"}]},{"type":"category","label":"User Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Cloud Resources","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deliver the WordPress Application with Cloud RDS","href":"/docs/next/kusion/user-guides/cloud-resources/database","docId":"kusion/user-guides/cloud-resources/database"},{"type":"link","label":"Expose Application Service Deployed on CSP Kubernetes","href":"/docs/next/kusion/user-guides/cloud-resources/expose-service","docId":"kusion/user-guides/cloud-resources/expose-service"}]},{"type":"category","label":"Kubernetes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application","href":"/docs/next/kusion/user-guides/working-with-k8s/deploy-application","docId":"kusion/user-guides/working-with-k8s/deploy-application"},{"type":"link","label":"Configure Containers","href":"/docs/next/kusion/user-guides/working-with-k8s/container","docId":"kusion/user-guides/working-with-k8s/container"},{"type":"link","label":"Expose Service","href":"/docs/next/kusion/user-guides/working-with-k8s/service","docId":"kusion/user-guides/working-with-k8s/service"},{"type":"link","label":"Upgrade Image","href":"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade","docId":"kusion/user-guides/working-with-k8s/image-upgrade"},{"type":"link","label":"Configure Resource Specification","href":"/docs/next/kusion/user-guides/working-with-k8s/resource-spec","docId":"kusion/user-guides/working-with-k8s/resource-spec"},{"type":"link","label":"Set up Operational Rules","href":"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules","docId":"kusion/user-guides/working-with-k8s/set-up-operational-rules"},{"type":"link","label":"Schedule a Job","href":"/docs/next/kusion/user-guides/working-with-k8s/job","docId":"kusion/user-guides/working-with-k8s/job"}]},{"type":"category","label":"Automated Observability","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configure Monitoring Behavior With Prometheus","href":"/docs/next/kusion/user-guides/observability/prometheus","docId":"kusion/user-guides/observability/prometheus"}]},{"type":"category","label":"GitHub Actions","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Deploy Application Securely and Efficiently via GitHub Actions","href":"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions","docId":"kusion/user-guides/github-actions/deploy-application-via-github-actions"}]},{"type":"category","label":"Secrets Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Using Cloud Secrets Manager","href":"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets","docId":"kusion/user-guides/secrets-management/using-cloud-secrets"}]}]},{"type":"category","label":"Reference","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Kusion Commands","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"kusion apply","href":"/docs/next/kusion/reference/commands/kusion-apply","docId":"kusion/reference/commands/kusion-apply"},{"type":"link","label":"kusion build","href":"/docs/next/kusion/reference/commands/kusion-build","docId":"kusion/reference/commands/kusion-build"},{"type":"link","label":"kusion compile","href":"/docs/next/kusion/reference/commands/kusion-compile","docId":"kusion/reference/commands/kusion-compile"},{"type":"link","label":"kusion destroy","href":"/docs/next/kusion/reference/commands/kusion-destroy","docId":"kusion/reference/commands/kusion-destroy"},{"type":"link","label":"kusion init","href":"/docs/next/kusion/reference/commands/kusion-init","docId":"kusion/reference/commands/kusion-init"},{"type":"link","label":"kusion preview","href":"/docs/next/kusion/reference/commands/kusion-preview","docId":"kusion/reference/commands/kusion-preview"},{"type":"link","label":"kusion version","href":"/docs/next/kusion/reference/commands/kusion-version","docId":"kusion/reference/commands/kusion-version"},{"type":"link","label":"kusion workspace create","href":"/docs/next/kusion/reference/commands/kusion-workspace-create","docId":"kusion/reference/commands/kusion-workspace-create"},{"type":"link","label":"kusion workspace delete","href":"/docs/next/kusion/reference/commands/kusion-workspace-delete","docId":"kusion/reference/commands/kusion-workspace-delete"},{"type":"link","label":"kusion workspace list","href":"/docs/next/kusion/reference/commands/kusion-workspace-list","docId":"kusion/reference/commands/kusion-workspace-list"},{"type":"link","label":"kusion workspace show","href":"/docs/next/kusion/reference/commands/kusion-workspace-show","docId":"kusion/reference/commands/kusion-workspace-show"},{"type":"link","label":"kusion workspace update","href":"/docs/next/kusion/reference/commands/kusion-workspace-update","docId":"kusion/reference/commands/kusion-workspace-update"},{"type":"link","label":"kusion workspace","href":"/docs/next/kusion/reference/commands/kusion-workspace","docId":"kusion/reference/commands/kusion-workspace"}],"href":"/docs/next/kusion/reference/commands/"},{"type":"category","label":"Kusion Modules","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Catalog Models","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"appconfiguration","href":"/docs/next/kusion/reference/modules/catalog-models/app-configuration","docId":"kusion/reference/modules/catalog-models/app-configuration"},{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/catalog-models/database/mysql","docId":"kusion/reference/modules/catalog-models/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/catalog-models/database/postgres","docId":"kusion/reference/modules/catalog-models/database/postgres"}]},{"type":"category","label":"internal","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"common","href":"/docs/next/kusion/reference/modules/catalog-models/internal/common","docId":"kusion/reference/modules/catalog-models/internal/common"},{"type":"category","label":"container","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"lifecycle","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/","docId":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle"},{"type":"link","label":"probe","href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/","docId":"kusion/reference/modules/catalog-models/internal/container/probe/probe"}],"href":"/docs/next/kusion/reference/modules/catalog-models/internal/container/"},{"type":"category","label":"network","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/catalog-models/internal/network/port","docId":"kusion/reference/modules/catalog-models/internal/network/port"}]},{"type":"link","label":"secret","href":"/docs/next/kusion/reference/modules/catalog-models/internal/secret/","docId":"kusion/reference/modules/catalog-models/internal/secret/secret"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"prometheus","href":"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus","docId":"kusion/reference/modules/catalog-models/monitoring/prometheus"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule","docId":"kusion/reference/modules/catalog-models/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/catalog-models/workload/job","docId":"kusion/reference/modules/catalog-models/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/catalog-models/workload/service","docId":"kusion/reference/modules/catalog-models/workload/service"}]}]},{"type":"category","label":"Workspace Configs","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"database","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"mysql","href":"/docs/next/kusion/reference/modules/workspace-configs/database/mysql","docId":"kusion/reference/modules/workspace-configs/database/mysql"},{"type":"link","label":"postgres","href":"/docs/next/kusion/reference/modules/workspace-configs/database/postgres","docId":"kusion/reference/modules/workspace-configs/database/postgres"}]},{"type":"category","label":"monitoring","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"monitoring","href":"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus","docId":"kusion/reference/modules/workspace-configs/monitoring/prometheus"}]},{"type":"category","label":"networking","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"port","href":"/docs/next/kusion/reference/modules/workspace-configs/networking/port","docId":"kusion/reference/modules/workspace-configs/networking/port"}]},{"type":"category","label":"trait","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"opsrule","href":"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule","docId":"kusion/reference/modules/workspace-configs/trait/opsrule"}]},{"type":"category","label":"workload","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"job","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/job","docId":"kusion/reference/modules/workspace-configs/workload/job"},{"type":"link","label":"service","href":"/docs/next/kusion/reference/modules/workspace-configs/workload/service","docId":"kusion/reference/modules/workspace-configs/workload/service"}]}]},{"type":"link","label":"Resource Naming Conventions","href":"/docs/next/kusion/reference/modules/naming-conventions","docId":"kusion/reference/modules/naming-conventions"}],"href":"/docs/next/kusion/reference/modules/"},{"type":"link","label":"Roadmap","href":"/docs/next/kusion/reference/roadmap","docId":"kusion/reference/roadmap"}]},{"type":"category","label":"FAQ","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/kusion/faq/install-error","docId":"kusion/faq/install-error"},{"type":"link","label":"KCL","href":"/docs/next/kusion/faq/kcl","docId":"kusion/faq/kcl"}]}],"operating":[{"type":"link","label":"Introduction","href":"/docs/next/operating/introduction/","docId":"operating/introduction/introduction"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/operating/started/install","docId":"operating/started/install"},{"type":"link","label":"Using KusionStack Operating to operate Pods gracefully","href":"/docs/next/operating/started/demo-graceful-operation","docId":"operating/started/demo-graceful-operation"}]},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"PodOpsLifecycle","href":"/docs/next/operating/concepts/podopslifecycle","docId":"operating/concepts/podopslifecycle"}]},{"type":"category","label":"Manuals","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CollaSet","href":"/docs/next/operating/manuals/collaset","docId":"operating/manuals/collaset"},{"type":"link","label":"ResourceConsist","href":"/docs/next/operating/manuals/resourceconsist","docId":"operating/manuals/resourceconsist"},{"type":"link","label":"PodTransitionRule","href":"/docs/next/operating/manuals/podtransitionrule","docId":"operating/manuals/podtransitionrule"},{"type":"link","label":"PodDecoration","href":"/docs/next/operating/manuals/poddecoration","docId":"operating/manuals/poddecoration"}]}],"community":[{"type":"link","label":"Community","href":"/docs/next/community/intro/","docId":"community/intro/intro"}],"ctrlmesh":[{"type":"link","label":"Introduction","href":"/docs/next/ctrlmesh/intro/","docId":"ctrlmesh/intro/intro"},{"type":"link","label":"Concepts","href":"/docs/next/ctrlmesh/concepts/","docId":"ctrlmesh/concepts/concepts"},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/docs/next/ctrlmesh/started/install","docId":"ctrlmesh/started/install"},{"type":"link","label":"Try a Sample","href":"/docs/next/ctrlmesh/started/try","docId":"ctrlmesh/started/try"}]},{"type":"link","label":"FAQ","href":"/docs/next/ctrlmesh/faq/","docId":"ctrlmesh/faq/faq"}]},"docs":{"community/intro/intro":{"id":"community/intro/intro","title":"Community","description":"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.","sidebar":"community"},"ctrlmesh/concepts/concepts":{"id":"ctrlmesh/concepts/concepts","title":"Concepts","description":"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.","sidebar":"ctrlmesh"},"ctrlmesh/faq/faq":{"id":"ctrlmesh/faq/faq","title":"FAQ","description":"","sidebar":"ctrlmesh"},"ctrlmesh/intro/intro":{"id":"ctrlmesh/intro/intro","title":"Controller Mesh","description":"KusionStack Controller Mesh is a solution that helps developers managing their controllers/operators better.","sidebar":"ctrlmesh"},"ctrlmesh/started/install":{"id":"ctrlmesh/started/install","title":"Installation","description":"Install with helm","sidebar":"ctrlmesh"},"ctrlmesh/started/try":{"id":"ctrlmesh/started/try","title":"Try a Sample","description":"This guide lets you quickly evaluate KusionStack Controller Mesh.","sidebar":"ctrlmesh"},"kusion/concepts/app-configuration":{"id":"kusion/concepts/app-configuration","title":"AppConfiguration","description":"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and AppConfiguration model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself.","sidebar":"kusion"},"kusion/concepts/backend-configuration":{"id":"kusion/concepts/backend-configuration","title":"Backend Configuration","description":"The backend configuration defines the place where Kusion stores its state data file. By default, Kusion uses the local type of backend to store the state on the local disk. While for team collaboration projects, the state can be stored on a remote backend, such as mysql, oss and s3 to allow multiple users access it.","sidebar":"kusion"},"kusion/concepts/configuration":{"id":"kusion/concepts/configuration","title":"Configuration","description":"Kusion can be configured with some global settings, which are separate from the AppConfiguration written by the application developers and the workspace configurations written by the platform engineers.","sidebar":"kusion"},"kusion/concepts/how-kusion-works":{"id":"kusion/concepts/how-kusion-works","title":"How Kusion Works?","description":"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Modules defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.","sidebar":"kusion"},"kusion/concepts/intent":{"id":"kusion/concepts/intent","title":"Intent","description":"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.","sidebar":"kusion"},"kusion/concepts/kusion-module":{"id":"kusion/concepts/kusion-module","title":"Kusion Module","description":"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:","sidebar":"kusion"},"kusion/concepts/project/configuration":{"id":"kusion/concepts/project/configuration","title":"Project Configuration","description":"Users can add config items of the project in project.yaml, such as the project name, generator type, Prometheus monitoring, etc.","sidebar":"kusion"},"kusion/concepts/project/overview":{"id":"kusion/concepts/project/overview","title":"Overview","description":"A project in Kusion is defined as any folder that contains a project.yaml file and is linked to a Git repository. Typically, the mapping between a project and a repository is 1:1, however, it is possible to have multiple projects connected to a single repository\u2014for example, in the case of a monorepo. A project consists of one or more applications.","sidebar":"kusion"},"kusion/concepts/stack/configuration":{"id":"kusion/concepts/stack/configuration","title":"Stack Configuration","description":"Users can add config items of the stack in stack.yaml, such as the stack name, etc.","sidebar":"kusion"},"kusion/concepts/stack/overview":{"id":"kusion/concepts/stack/overview","title":"Overview","description":"A stack in Kusion is any folder that contains a stack.yaml file within the corresponding project directory. A stack provides a mechanism to isolate multiple deployments of the same application, serving as the target workspace to which an application will be deployed. It is also the smallest operational unit that can be configured and deployed independently. Stacks are commonly used to denote different phases of the software development lifecycle, such as development, staging, and production.","sidebar":"kusion"},"kusion/concepts/workspace":{"id":"kusion/concepts/workspace","title":"Workspace","description":"Definition","sidebar":"kusion"},"kusion/configuration-walkthrough/base-override":{"id":"kusion/configuration-walkthrough/base-override","title":"Base and Override","description":"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.","sidebar":"kusion"},"kusion/configuration-walkthrough/databse":{"id":"kusion/configuration-walkthrough/databse","title":"Managed Databases","description":"You could also specify a database needed for the application. That can be achieved via a mysql or a postgres module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.","sidebar":"kusion"},"kusion/configuration-walkthrough/kcl-basics":{"id":"kusion/configuration-walkthrough/kcl-basics","title":"KCL Basics","description":"Table of Content","sidebar":"kusion"},"kusion/configuration-walkthrough/monitoring":{"id":"kusion/configuration-walkthrough/monitoring","title":"Application Monitoring","description":"You could also specify the collection of monitoring requirements for the application. That can be achieved via a monitoring module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.","sidebar":"kusion"},"kusion/configuration-walkthrough/networking":{"id":"kusion/configuration-walkthrough/networking","title":"Application Networking","description":"In addition to configuring application\'s container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed. You can specify a network module in the accessories field in AppConfiguration to achieve that.","sidebar":"kusion"},"kusion/configuration-walkthrough/operational-rules":{"id":"kusion/configuration-walkthrough/operational-rules","title":"Operational Rules","description":"You could also specify the collection of operational rule requirements for the application. That can be achieved via a opsrule module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that. Operational rules are used as a preemptive measure to police and stop any unwanted changes.","sidebar":"kusion"},"kusion/configuration-walkthrough/overview":{"id":"kusion/configuration-walkthrough/overview","title":"Configuration File Overview","description":"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.","sidebar":"kusion"},"kusion/configuration-walkthrough/secret":{"id":"kusion/configuration-walkthrough/secret","title":"Secrets","description":"Secrets are used to store sensitive data like passwords, API keys, TLS certificates, tokens, or other credentials. Kusion provides multiple secret types, and makes it easy to be consumed in containers.","sidebar":"kusion"},"kusion/configuration-walkthrough/workload":{"id":"kusion/configuration-walkthrough/workload","title":"Workload","description":"The workload attribute in the AppConfiguration instance is used to describe the specification for the application workload. The application workload generally represents the computing component for the application.","sidebar":"kusion"},"kusion/faq/install-error":{"id":"kusion/faq/install-error","title":"Installation","description":"1. Could not find libintl.dylib","sidebar":"kusion"},"kusion/faq/kcl":{"id":"kusion/faq/kcl","title":"KCL","description":"Visit the KCL website for more documents.","sidebar":"kusion"},"kusion/getting-started/deliver-wordpress":{"id":"kusion/getting-started/deliver-wordpress","title":"Deliver the WordPress Application on Kubernetes","description":"In this tutorial we will walk through how to deploy a WordPress application on Kubernetes with Kusion. The WordPress application will interact with a locally deployed MySQL, which is declared as a database accessory in the config codes and will be automatically created and managed by Kusion.","sidebar":"kusion"},"kusion/getting-started/install-kusion":{"id":"kusion/getting-started/install-kusion","title":"Install Kusion","description":"You can install the latest Kusion CLI on MacOS and Linux. Choose the one you prefer from the methods below.","sidebar":"kusion"},"kusion/reference/commands/index":{"id":"kusion/reference/commands/index","title":"Kusion Commands","description":"Kusion is the Platform Orchestrator of KusionStack","sidebar":"kusion"},"kusion/reference/commands/kusion-apply":{"id":"kusion/reference/commands/kusion-apply","title":"kusion apply","description":"Apply the operational intent of various resources to multiple runtimes","sidebar":"kusion"},"kusion/reference/commands/kusion-build":{"id":"kusion/reference/commands/kusion-build","title":"kusion build","description":"Build Kusion modules in a Stack to the Intent","sidebar":"kusion"},"kusion/reference/commands/kusion-compile":{"id":"kusion/reference/commands/kusion-compile","title":"kusion compile","description":"Deprecated: Use \'kusion build\' to generate the Intent instead","sidebar":"kusion"},"kusion/reference/commands/kusion-destroy":{"id":"kusion/reference/commands/kusion-destroy","title":"kusion destroy","description":"Destroy resources within the stack.","sidebar":"kusion"},"kusion/reference/commands/kusion-init":{"id":"kusion/reference/commands/kusion-init","title":"kusion init","description":"Initialize the scaffolding for a project","sidebar":"kusion"},"kusion/reference/commands/kusion-preview":{"id":"kusion/reference/commands/kusion-preview","title":"kusion preview","description":"Preview a series of resource changes within the stack","sidebar":"kusion"},"kusion/reference/commands/kusion-version":{"id":"kusion/reference/commands/kusion-version","title":"kusion version","description":"Print the Kusion version information for the current context","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace":{"id":"kusion/reference/commands/kusion-workspace","title":"kusion workspace","description":"Workspace is a logical concept representing a target that stacks will be deployed to","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-create":{"id":"kusion/reference/commands/kusion-workspace-create","title":"kusion workspace create","description":"Create a new workspace","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-delete":{"id":"kusion/reference/commands/kusion-workspace-delete","title":"kusion workspace delete","description":"Delete a workspace","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-list":{"id":"kusion/reference/commands/kusion-workspace-list","title":"kusion workspace list","description":"List all workspace names","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-show":{"id":"kusion/reference/commands/kusion-workspace-show","title":"kusion workspace show","description":"Show a workspace configuration","sidebar":"kusion"},"kusion/reference/commands/kusion-workspace-update":{"id":"kusion/reference/commands/kusion-workspace-update","title":"kusion workspace update","description":"Update a workspace configuration","sidebar":"kusion"},"kusion/reference/modules/catalog-models/app-configuration":{"id":"kusion/reference/modules/catalog-models/app-configuration","title":"appconfiguration","description":"Schema AppConfiguration","sidebar":"kusion"},"kusion/reference/modules/catalog-models/database/mysql":{"id":"kusion/reference/modules/catalog-models/database/mysql","title":"mysql","description":"Schema MySQL","sidebar":"kusion"},"kusion/reference/modules/catalog-models/database/postgres":{"id":"kusion/reference/modules/catalog-models/database/postgres","title":"postgres","description":"Schema PostgreSQL","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/common":{"id":"kusion/reference/modules/catalog-models/internal/common","title":"common","description":"Schema WorkloadBase","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/container/container":{"id":"kusion/reference/modules/catalog-models/internal/container/container","title":"container","description":"Schema Container","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle":{"id":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle","title":"lifecycle","description":"Schema Lifecycle","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/container/probe/probe":{"id":"kusion/reference/modules/catalog-models/internal/container/probe/probe","title":"probe","description":"Schema Probe","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/network/port":{"id":"kusion/reference/modules/catalog-models/internal/network/port","title":"port","description":"Schema Port","sidebar":"kusion"},"kusion/reference/modules/catalog-models/internal/secret/secret":{"id":"kusion/reference/modules/catalog-models/internal/secret/secret","title":"secret","description":"Schema Secret","sidebar":"kusion"},"kusion/reference/modules/catalog-models/monitoring/prometheus":{"id":"kusion/reference/modules/catalog-models/monitoring/prometheus","title":"prometheus","description":"Schema Prometheus","sidebar":"kusion"},"kusion/reference/modules/catalog-models/trait/opsrule":{"id":"kusion/reference/modules/catalog-models/trait/opsrule","title":"opsrule","description":"Schema OpsRule","sidebar":"kusion"},"kusion/reference/modules/catalog-models/workload/job":{"id":"kusion/reference/modules/catalog-models/workload/job","title":"job","description":"Schemas","sidebar":"kusion"},"kusion/reference/modules/catalog-models/workload/service":{"id":"kusion/reference/modules/catalog-models/workload/service","title":"service","description":"Schemas","sidebar":"kusion"},"kusion/reference/modules/index":{"id":"kusion/reference/modules/index","title":"Kusion Modules","description":"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.","sidebar":"kusion"},"kusion/reference/modules/naming-conventions":{"id":"kusion/reference/modules/naming-conventions","title":"Resource Naming Conventions","description":"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users\' awareness. This document will introduce the naming conventions for these related resources.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/database/mysql":{"id":"kusion/reference/modules/workspace-configs/database/mysql","title":"mysql","description":"Module MySQL","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/database/postgres":{"id":"kusion/reference/modules/workspace-configs/database/postgres","title":"postgres","description":"Module PostgreSQL","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/monitoring/prometheus":{"id":"kusion/reference/modules/workspace-configs/monitoring/prometheus","title":"monitoring","description":"monitoring can be used to define workspace-level monitoring configurations.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/networking/port":{"id":"kusion/reference/modules/workspace-configs/networking/port","title":"port","description":"port can be used to define workspace-level networking configurations.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/trait/opsrule":{"id":"kusion/reference/modules/workspace-configs/trait/opsrule","title":"opsrule","description":"opsrule can be used to define workspace-level operational rule configurations.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/workload/job":{"id":"kusion/reference/modules/workspace-configs/workload/job","title":"job","description":"job can be used to define workspace-level job configuration.","sidebar":"kusion"},"kusion/reference/modules/workspace-configs/workload/service":{"id":"kusion/reference/modules/workspace-configs/workload/service","title":"service","description":"service can be used to define workspace-level service configuration.","sidebar":"kusion"},"kusion/reference/roadmap":{"id":"kusion/reference/roadmap","title":"Roadmap","description":"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker","sidebar":"kusion"},"kusion/user-guides/cloud-resources/database":{"id":"kusion/user-guides/cloud-resources/database","title":"Deliver the WordPress Application with Cloud RDS","description":"This tutorial will demonstrate how to deploy a WordPress application with Kusion, which relies on both Kubernetes and IaaS resources provided by cloud vendors. We can learn how to declare the Relational Database Service (RDS) to provide a cloud-based database solution for our application from this article.","sidebar":"kusion"},"kusion/user-guides/cloud-resources/expose-service":{"id":"kusion/user-guides/cloud-resources/expose-service","title":"Expose Application Service Deployed on CSP Kubernetes","description":"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.","sidebar":"kusion"},"kusion/user-guides/github-actions/deploy-application-via-github-actions":{"id":"kusion/user-guides/github-actions/deploy-application-via-github-actions","title":"Deploy Application Securely and Efficiently via GitHub Actions","description":"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.","sidebar":"kusion"},"kusion/user-guides/observability/prometheus":{"id":"kusion/user-guides/observability/prometheus","title":"Configure Monitoring Behavior With Prometheus","description":"This document provides the step-by-step instruction to set up monitoring for your application.","sidebar":"kusion"},"kusion/user-guides/secrets-management/using-cloud-secrets":{"id":"kusion/user-guides/secrets-management/using-cloud-secrets","title":"Using Cloud Secrets Manager","description":"Applications usually store sensitive data in secrets by using centralized secrets management solutions. For example, you authenticate databases, services, and external systems with passwords, API keys, tokens, and other credentials stored in a secret store, e.g. Hashicorp Vault, AWS Secrets Manager, Azure Key Vault, etc","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/container":{"id":"kusion/user-guides/working-with-k8s/container","title":"Configure Containers","description":"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/deploy-application":{"id":"kusion/user-guides/working-with-k8s/deploy-application","title":"Deploy Application","description":"This guide shows you how to use Kusion CLIs to complete the deployment of an application running in Kubernetes.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/image-upgrade":{"id":"kusion/user-guides/working-with-k8s/image-upgrade","title":"Upgrade Image","description":"You can declare the application\'s container image via image field of the Container schema.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/job":{"id":"kusion/user-guides/working-with-k8s/job","title":"Schedule a Job","description":"The guides above provide examples on how to configure workloads of the type wl.Service, which is typically used for long-running web applications that should \\"never\\" go down. Alternatively, you could also schedule another kind of workload profile, namely wl.Job which corresponds to a one-off or recurring execution of tasks that run to completion and then stop.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/resource-spec":{"id":"kusion/user-guides/working-with-k8s/resource-spec","title":"Configure Resource Specification","description":"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/service":{"id":"kusion/user-guides/working-with-k8s/service","title":"Expose Service","description":"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don\'t match the service ports), so that it can be consumed by other applications.","sidebar":"kusion"},"kusion/user-guides/working-with-k8s/set-up-operational-rules":{"id":"kusion/user-guides/working-with-k8s/set-up-operational-rules","title":"Set up Operational Rules","description":"You can set up operational rules in the AppConfiguration model via the opsRule field and corresponding platform configurations in the workspace directory. The opsRule is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes.","sidebar":"kusion"},"kusion/what-is-kusion/kusion-vs-x":{"id":"kusion/what-is-kusion/kusion-vs-x","title":"Kusion vs Other Software","description":"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.","sidebar":"kusion"},"kusion/what-is-kusion/overview":{"id":"kusion/what-is-kusion/overview","title":"Overview","description":"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.","sidebar":"kusion"},"operating/concepts/podopslifecycle":{"id":"operating/concepts/podopslifecycle","title":"PodOpsLifecycle","description":"Background","sidebar":"operating"},"operating/introduction/introduction":{"id":"operating/introduction/introduction","title":"What is KusionStack Operating?","description":"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,","sidebar":"operating"},"operating/manuals/collaset":{"id":"operating/manuals/collaset","title":"CollaSet","description":"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.","sidebar":"operating"},"operating/manuals/poddecoration":{"id":"operating/manuals/poddecoration","title":"PodDecoration","description":"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.","sidebar":"operating"},"operating/manuals/podtransitionrule":{"id":"operating/manuals/podtransitionrule","title":"PodTransitionRule","description":"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.","sidebar":"operating"},"operating/manuals/resourceconsist":{"id":"operating/manuals/resourceconsist","title":"ResourceConsist","description":"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following","sidebar":"operating"},"operating/started/demo-graceful-operation":{"id":"operating/started/demo-graceful-operation","title":"Using KusionStack Operating to operate Pods gracefully","description":"Applications always provide its service along with traffic routing.","sidebar":"operating"},"operating/started/install":{"id":"operating/started/install","title":"Installation","description":"Install with helm","sidebar":"operating"}}}')}}]); \ No newline at end of file diff --git a/assets/js/9595b411.88e3cf18.js b/assets/js/9595b411.88e3cf18.js new file mode 100644 index 00000000000..38c5057e678 --- /dev/null +++ b/assets/js/9595b411.88e3cf18.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[581],{3905:(e,a,n)=>{n.d(a,{Zo:()=>r,kt:()=>m});var t=n(67294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function i(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=t.createContext({}),d=function(e){var a=t.useContext(p),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},r=function(e){var a=d(e.components);return t.createElement(p.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},u=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,i=e.originalType,p=e.parentName,r=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=l,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return n?t.createElement(g,o(o({ref:a},r),{},{components:n})):t.createElement(g,o({ref:a},r))}));function m(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var i=n.length,o=new Array(i);o[0]=u;var s={};for(var p in a)hasOwnProperty.call(a,p)&&(s[p]=a[p]);s.originalType=e,s.mdxType="string"==typeof e?e:l,o[1]=s;for(var d=2;d{n.r(a),n.d(a,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var t=n(87462),l=(n(67294),n(3905));const i={sidebar_position:1},o="CollaSet",s={unversionedId:"operating/manuals/collaset",id:"version-v0.9/operating/manuals/collaset",title:"CollaSet",description:"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.",source:"@site/versioned_docs/version-v0.9/operating/manuals/collaset.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/collaset",permalink:"/docs/v0.9/operating/manuals/collaset",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/collaset.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"operating",previous:{title:"PodOpsLifecycle",permalink:"/docs/v0.9/operating/concepts/podopslifecycle"},next:{title:"ResourceConsist",permalink:"/docs/v0.9/operating/manuals/resourceconsist"}},p={},d=[{value:"Basic Features",id:"basic-features",level:2},{value:"Scaling Pods",id:"scaling-pods",level:3},{value:"Updating Pods",id:"updating-pods",level:3},{value:"Partition",id:"partition",level:4},{value:"Update by Label",id:"update-by-label",level:4},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Scaling Pods",id:"scaling-pods-1",level:3},{value:"Pod Instance ID",id:"pod-instance-id",level:4},{value:"Revision Consistency",id:"revision-consistency",level:4},{value:"Updating Pods",id:"updating-pods-1",level:3},{value:"Update Policy",id:"update-policy",level:4}],r={toc:d};function c(e){let{components:a,...n}=e;return(0,l.kt)("wrapper",(0,t.Z)({},r,n,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"collaset"},"CollaSet"),(0,l.kt)("p",null,"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods."),(0,l.kt)("p",null,"A basic CollaSet configuration is represented in the following YAML format:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Let's explore the features of CollaSet."),(0,l.kt)("h2",{id:"basic-features"},"Basic Features"),(0,l.kt)("h3",{id:"scaling-pods"},"Scaling Pods"),(0,l.kt)("p",null,"CollaSet utilizes the field spec.replicas to indicate the number of Pods under management."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 3 # indicate the number of Pods to manage\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n...\n")),(0,l.kt)("p",null,"Pods can be provisioned by CollaSet."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-85q7g 1/1 Running 0 57s\ncollaset-sample-vx5ws 1/1 Running 0 57s\ncollaset-sample-hr7pv 1/1 Running 0 57s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("p",null,"By default, CollaSet always creates new Pods using the latest template specified in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". CollaSet establishes ownership over a set of Pods through the label selector defined in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector"),". Thus, it's important to ensure that the labels provided in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector")," match those in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template.metadata.labels"),"."),(0,l.kt)("p",null,"CollaSet status provides general information about this CollaSet and all Pods under it."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get cls collaset-sample -o yaml\n......\nstatus:\n availableReplicas: 3\n collisionCount: 0\n conditions:\n - lastTransitionTime: "2023-09-01T03:56:09Z"\n reason: Updated\n status: "True"\n type: Update\n currentRevision: collaset-sample-6d7b7c58f\n observedGeneration: 1\n operatingReplicas: 0\n readyReplicas: 3\n replicas: 3\n scheduledReplicas: 3\n updatedAvailableReplicas: 3\n updatedReadyReplicas: 3\n updatedReplicas: 3\n updatedRevision: collaset-sample-6d7b7c58f\n')),(0,l.kt)("p",null,"Some fields in CollaSet status are explained here:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedRevision")," indicates the latest revision that CollaSet uses to create or update Pods."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"currentRevision")," indicates the last updated revision. It will be set to updatedRevision after all Pods are updated, and their PodReady conditions become True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"replicas")," indicates the count of Pods under this CollaSet."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"scheduledReplicas")," indicates the count of Pods under this CollaSet that successfully got scheduled."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"availableReplicas")," indicates the count of Pods under this CollaSet that have all expected finalizers attached."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," indicates the count of Pods under this CollaSet that have the updated revision."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," indicates the count of Pods under this CollaSet that are counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," and have their PodReady conditions set to True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedAvailableReplicas")," indicates the count of Pods under this CollaSet that is counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," and have all expected finalizers attached."),(0,l.kt)("h3",{id:"updating-pods"},"Updating Pods"),(0,l.kt)("p",null,"CollaSet generates Pods according to the pod template described in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". This template can be updated to signal CollaSet to update each owned Pod:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n......\nspec:\n......\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n......\n")),(0,l.kt)("p",null,"CollaSet immediately updates all Pods it owns with the new Pod template by default."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("p",null,"The update progress can be controlled using partition."),(0,l.kt)("h4",{id:"partition"},"Partition"),(0,l.kt)("p",null,"Similar to StatefulSet, ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," is used to control the upgrade progress."),(0,l.kt)("p",null,"By default, if not indicated, all Pods will be updated when spec.template changes. The ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," can be adjusted from 0 to ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.replicas")," to specify how many Pods CollaSet should update. ",(0,l.kt)("strong",{parentName:"p"},"Unlike StatefulSet, the partition in CollaSet represents the number of Pods to update.")),(0,l.kt)("p",null,"Let's update the image back to nginx:1.25.2:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.25.2 # changed from nginx:1.24.0 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # use partition to control upgrade progress\n")),(0,l.kt)("p",null,"In this case, CollaSet only updates 1 Pod to the updated revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.25.2 # only 1 Pod updated\n - image: nginx:1.24.0\n')),(0,l.kt)("h4",{id:"update-by-label"},"Update by Label"),(0,l.kt)("p",null,"By configuring the ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," rolling update policy, users can precisely specify which Pods they want to update by using labels."),(0,l.kt)("p",null,"If you go back to the sample in the ",(0,l.kt)("a",{parentName:"p",href:"#Partition"},"section Partition")," and change ",(0,l.kt)("inlineCode",{parentName:"p"},"byPartition")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," like the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n- byPartition:\n- partition: 1\n+ byLabel: {}\n")),(0,l.kt)("p",null,"Subsequently, each Pod will only be updated if it's marked with the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/update-included"),"."),(0,l.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,l.kt)("h3",{id:"scaling-pods-1"},"Scaling Pods"),(0,l.kt)("h4",{id:"pod-instance-id"},"Pod Instance ID"),(0,l.kt)("p",null,"Each Pod created by CollaSet has a unique ID held by the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/instance-id"),", which can be used to identify each individual Pod."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: Pod\nmetadata:\n labels:\n collaset.kusionstack.io/instance-id: "0" # Pod instance ID\n...\n')),(0,l.kt)("p",null,"CollaSet provides a context to specify an ID pool, which defaults to the same name as the CollaSet and is immutable."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"...\nspec:\n scaleStrategy:\n context: \n")),(0,l.kt)("p",null,"The same ID pool name can be indicated for multiple CollaSets, allowing them to share a single ID pool. Consequently, each Pod created by these CollaSets will be assigned a unique ID."),(0,l.kt)("p",null,"For example, these are two CollaSets with the same context:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ cat ~/sample.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-a\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n---\n\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-b\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Then create these CollaSets with the sample file:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default apply -f ~/sample.yaml\ncollaset.apps.kusionstack.io/collaset-sample-a created\ncollaset.apps.kusionstack.io/collaset-sample-b created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-a-g4sjj 1/1 Running 0 42s\ncollaset-sample-a-ph9vc 1/1 Running 0 42s\ncollaset-sample-b-fqkq4 1/1 Running 0 42s\ncollaset-sample-b-lqg8f 1/1 Running 0 42s\n\n$ kubectl -n default get pod -o yaml | grep collaset.kusionstack.io/instance-id\n collaset.kusionstack.io/instance-id: "0"\n collaset.kusionstack.io/instance-id: "1"\n collaset.kusionstack.io/instance-id: "3"\n collaset.kusionstack.io/instance-id: "2"\n')),(0,l.kt)("p",null,"Now, the 4 Pods created by these 2 CollaSets will have a unique instance ID."),(0,l.kt)("h4",{id:"revision-consistency"},"Revision Consistency"),(0,l.kt)("p",null,"Pods within a CollaSet can utilize more than two different Pod templates simultaneously, including both the current and updated revisions. This can result from partial updates. To ensure the stability of Pod revisions over time, CollaSet records this information. When a Pod is deleted, CollaSet recreates it using its previous revision."),(0,l.kt)("p",null,"It can be reproduced by following steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Provision a new CollaSet with replicas 3.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 4s\ncollaset-sample-glgnb 1/1 Running 0 4s\ncollaset-sample-qs46r 1/1 Running 0 4s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.24.0 and set the partition to 2. Then there will be 2 Pods with image nginx:1.24.0 and 1 Pod with image nginx:1.25.2.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 2 # update 2 Pods\n\n# Wait until these 2 Pods are updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("ol",{start:3},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.23.4 and set the partition to 1.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.23.4 # changed from nginx:1.24.0\n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # update 1 Pod\n\n# Wait until the Pod is updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # Pod collaset-sample-qs46r\n - image: nginx:1.23.4\n')),(0,l.kt)("p",null,"Now, there are 3 Pods, each of which has an individual image. If we then delete the Pod with the image nginx:1.24.0, the new Pod replacing it will be created with the same image nginx:1.24.0 in order for the Pod to inherit the revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl delete -n default delete pod collaset-sample-qs46r\npod "collaset-sample-qs46r" deleted\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 3h\ncollaset-sample-ht9x6 1/1 Running 0 2m27s # Pod recreated\ncollaset-sample-qs46r 1/1 Running 1 (3h ago) 3h\n\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # image has not been changed\n - image: nginx:1.23.4\n')),(0,l.kt)("h3",{id:"updating-pods-1"},"Updating Pods"),(0,l.kt)("h4",{id:"update-policy"},"Update Policy"),(0,l.kt)("p",null,"In addition to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," update policy, which is identical to Deployment and StatefulSet, CollaSet offers the ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," update policy."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # Options: InPlaceIfPossible, ReCreate\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," is the default value, which instructs CollaSets to try to update Pods in place when only container images, labels, and annotations have changed. If some other fields have changed too, the policy will back off to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," policy."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," indicates CollaSets always delete the old Pod and create a new one with an updated revision."),(0,l.kt)("p",null,"If update pod template with ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," policy as following example, the Pod will not be recreated."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # use InPlaceIfPossible policy\n\n$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5wvlh 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-ldvrg 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-pbz75 1/1 Running 1 (6s ago) 2m10s\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9595b411.e4151beb.js b/assets/js/9595b411.e4151beb.js deleted file mode 100644 index f956ade04cc..00000000000 --- a/assets/js/9595b411.e4151beb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[581],{3905:(e,a,n)=>{n.d(a,{Zo:()=>r,kt:()=>m});var t=n(67294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function i(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=t.createContext({}),d=function(e){var a=t.useContext(p),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},r=function(e){var a=d(e.components);return t.createElement(p.Provider,{value:a},e.children)},c={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},u=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,i=e.originalType,p=e.parentName,r=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=l,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return n?t.createElement(g,o(o({ref:a},r),{},{components:n})):t.createElement(g,o({ref:a},r))}));function m(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var i=n.length,o=new Array(i);o[0]=u;var s={};for(var p in a)hasOwnProperty.call(a,p)&&(s[p]=a[p]);s.originalType=e,s.mdxType="string"==typeof e?e:l,o[1]=s;for(var d=2;d{n.r(a),n.d(a,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var t=n(87462),l=(n(67294),n(3905));const i={sidebar_position:1},o="CollaSet",s={unversionedId:"operating/manuals/collaset",id:"version-v0.9/operating/manuals/collaset",title:"CollaSet",description:"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods.",source:"@site/versioned_docs/version-v0.9/operating/manuals/collaset.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/collaset",permalink:"/docs/v0.9/operating/manuals/collaset",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/collaset.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"operating",previous:{title:"PodOpsLifecycle",permalink:"/docs/v0.9/operating/concepts/podopslifecycle"},next:{title:"ResourceConsist",permalink:"/docs/v0.9/operating/manuals/resourceconsist"}},p={},d=[{value:"Basic Features",id:"basic-features",level:2},{value:"Scaling Pods",id:"scaling-pods",level:3},{value:"Updating Pods",id:"updating-pods",level:3},{value:"Partition",id:"partition",level:4},{value:"Update by Label",id:"update-by-label",level:4},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Scaling Pods",id:"scaling-pods-1",level:3},{value:"Pod Instance ID",id:"pod-instance-id",level:4},{value:"Revision Consistency",id:"revision-consistency",level:4},{value:"Updating Pods",id:"updating-pods-1",level:3},{value:"Update Policy",id:"update-policy",level:4}],r={toc:d};function c(e){let{components:a,...n}=e;return(0,l.kt)("wrapper",(0,t.Z)({},r,n,{components:a,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"collaset"},"CollaSet"),(0,l.kt)("p",null,"CollaSet is responsible for managing a set of Pods. Similar to Kubernetes Deployment and StatefulSet, it also supports scaling and updating Pods. Additionally, CollaSet offers advanced features to provide users with more granular control over managing Pods."),(0,l.kt)("p",null,"A basic CollaSet configuration is represented in the following YAML format:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Let's explore the features of CollaSet."),(0,l.kt)("h2",{id:"basic-features"},"Basic Features"),(0,l.kt)("h3",{id:"scaling-pods"},"Scaling Pods"),(0,l.kt)("p",null,"CollaSet utilizes the field spec.replicas to indicate the number of Pods under management."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n replicas: 3 # indicate the number of Pods to manage\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n...\n")),(0,l.kt)("p",null,"Pods can be provisioned by CollaSet."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-85q7g 1/1 Running 0 57s\ncollaset-sample-vx5ws 1/1 Running 0 57s\ncollaset-sample-hr7pv 1/1 Running 0 57s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("p",null,"By default, CollaSet always creates new Pods using the latest template specified in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". CollaSet establishes ownership over a set of Pods through the label selector defined in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector"),". Thus, it's important to ensure that the labels provided in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.selector")," match those in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template.metadata.labels"),"."),(0,l.kt)("p",null,"CollaSet status provides general information about this CollaSet and all Pods under it."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get cls collaset-sample -o yaml\n......\nstatus:\n availableReplicas: 3\n collisionCount: 0\n conditions:\n - lastTransitionTime: "2023-09-01T03:56:09Z"\n reason: Updated\n status: "True"\n type: Update\n currentRevision: collaset-sample-6d7b7c58f\n observedGeneration: 1\n operatingReplicas: 0\n readyReplicas: 3\n replicas: 3\n scheduledReplicas: 3\n updatedAvailableReplicas: 3\n updatedReadyReplicas: 3\n updatedReplicas: 3\n updatedRevision: collaset-sample-6d7b7c58f\n')),(0,l.kt)("p",null,"Some fields in CollaSet status are explained here:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedRevision")," indicates the latest revision that CollaSet uses to create or update Pods."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"currentRevision")," indicates the last updated revision. It will be set to updatedRevision after all Pods are updated, and their PodReady conditions become True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"replicas")," indicates the count of Pods under this CollaSet."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"scheduledReplicas")," indicates the count of Pods under this CollaSet that successfully got scheduled."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"availableReplicas")," indicates the count of Pods under this CollaSet that have all expected finalizers attached."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," indicates the count of Pods under this CollaSet that have the updated revision."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," indicates the count of Pods under this CollaSet that are counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReplicas")," and have their PodReady conditions set to True."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"updatedAvailableReplicas")," indicates the count of Pods under this CollaSet that is counted in ",(0,l.kt)("inlineCode",{parentName:"p"},"updatedReadyReplicas")," and have all expected finalizers attached."),(0,l.kt)("h3",{id:"updating-pods"},"Updating Pods"),(0,l.kt)("p",null,"CollaSet generates Pods according to the pod template described in ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.template"),". This template can be updated to signal CollaSet to update each owned Pod:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n......\nspec:\n......\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n......\n")),(0,l.kt)("p",null,"CollaSet immediately updates all Pods it owns with the new Pod template by default."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("p",null,"The update progress can be controlled using partition."),(0,l.kt)("h4",{id:"partition"},"Partition"),(0,l.kt)("p",null,"Similar to StatefulSet, ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," is used to control the upgrade progress."),(0,l.kt)("p",null,"By default, if not indicated, all Pods will be updated when spec.template changes. The ",(0,l.kt)("inlineCode",{parentName:"p"},"partition")," can be adjusted from 0 to ",(0,l.kt)("inlineCode",{parentName:"p"},"spec.replicas")," to specify how many Pods CollaSet should update. ",(0,l.kt)("strong",{parentName:"p"},"Unlike StatefulSet, the partition in CollaSet represents the number of Pods to update.")),(0,l.kt)("p",null,"Let's update the image back to nginx:1.25.2:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.25.2 # changed from nginx:1.24.0 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # use partition to control upgrade progress\n")),(0,l.kt)("p",null,"In this case, CollaSet only updates 1 Pod to the updated revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.25.2 # only 1 Pod updated\n - image: nginx:1.24.0\n')),(0,l.kt)("h4",{id:"update-by-label"},"Update by Label"),(0,l.kt)("p",null,"By configuring the ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," rolling update policy, users can precisely specify which Pods they want to update by using labels."),(0,l.kt)("p",null,"If you go back to the sample in the ",(0,l.kt)("a",{parentName:"p",href:"#Partition"},"section Partition")," and change ",(0,l.kt)("inlineCode",{parentName:"p"},"byPartition")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"byLabel")," like the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n- byPartition:\n- partition: 1\n+ byLabel: {}\n")),(0,l.kt)("p",null,"Subsequently, each Pod will only be updated if it's marked with the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/update-included"),"."),(0,l.kt)("h2",{id:"advanced-features"},"Advanced Features"),(0,l.kt)("h3",{id:"scaling-pods-1"},"Scaling Pods"),(0,l.kt)("h4",{id:"pod-instance-id"},"Pod Instance ID"),(0,l.kt)("p",null,"Each Pod created by CollaSet has a unique ID held by the label ",(0,l.kt)("inlineCode",{parentName:"p"},"collaset.kusionstack.io/instance-id"),", which can be used to identify each individual Pod."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: Pod\nmetadata:\n labels:\n collaset.kusionstack.io/instance-id: "0" # Pod instance ID\n...\n')),(0,l.kt)("p",null,"CollaSet provides a context to specify an ID pool, which defaults to the same name as the CollaSet and is immutable."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"...\nspec:\n scaleStrategy:\n context: \n")),(0,l.kt)("p",null,"The same ID pool name can be indicated for multiple CollaSets, allowing them to share a single ID pool. Consequently, each Pod created by these CollaSets will be assigned a unique ID."),(0,l.kt)("p",null,"For example, these are two CollaSets with the same context:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ cat ~/sample.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-a\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n---\n\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample-b\nspec:\n replicas: 2\n scaleStrategy:\n context: foo # with the same context foo\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: nginx\n")),(0,l.kt)("p",null,"Then create these CollaSets with the sample file:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default apply -f ~/sample.yaml\ncollaset.apps.kusionstack.io/collaset-sample-a created\ncollaset.apps.kusionstack.io/collaset-sample-b created\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-a-g4sjj 1/1 Running 0 42s\ncollaset-sample-a-ph9vc 1/1 Running 0 42s\ncollaset-sample-b-fqkq4 1/1 Running 0 42s\ncollaset-sample-b-lqg8f 1/1 Running 0 42s\n\n$ kubectl -n default get pod -o yaml | grep collaset.kusionstack.io/instance-id\n collaset.kusionstack.io/instance-id: "0"\n collaset.kusionstack.io/instance-id: "1"\n collaset.kusionstack.io/instance-id: "3"\n collaset.kusionstack.io/instance-id: "2"\n')),(0,l.kt)("p",null,"Now, the 4 Pods created by these 2 CollaSets will have a unique instance ID."),(0,l.kt)("h4",{id:"revision-consistency"},"Revision Consistency"),(0,l.kt)("p",null,"Pods within a CollaSet can utilize more than two different Pod templates simultaneously, including both the current and updated revisions. This can result from partial updates. To ensure the stability of Pod revisions over time, CollaSet records this information. When a Pod is deleted, CollaSet recreates it using its previous revision."),(0,l.kt)("p",null,"It can be reproduced by following steps:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Provision a new CollaSet with replicas 3.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n default apply -f ./config/samples/apps_v1alpha1_collaset.yaml\ncollaset.apps.kusionstack.io/collaset-sample created\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 4s\ncollaset-sample-glgnb 1/1 Running 0 4s\ncollaset-sample-qs46r 1/1 Running 0 4s\n\n$ kubectl -n default get cls\nNAME DESIRED CURRENT UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\ncollaset-sample 3 3 3 3 3 collaset-sample-6d7b7c58f collaset-sample-6d7b7c58f 64s\n")),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.24.0 and set the partition to 2. Then there will be 2 Pods with image nginx:1.24.0 and 1 Pod with image nginx:1.25.2.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2 \n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 2 # update 2 Pods\n\n# Wait until these 2 Pods are updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n')),(0,l.kt)("ol",{start:3},(0,l.kt)("li",{parentName:"ol"},"Update the image of PodTemplate of the CollaSet to image nginx:1.23.4 and set the partition to 1.")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.23.4 # changed from nginx:1.24.0\n ...\n updateStrategy:\n rollingUpdate:\n byPartition:\n partition: 1 # update 1 Pod\n\n# Wait until the Pod is updated, and check the Pod\'s images.\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # Pod collaset-sample-qs46r\n - image: nginx:1.23.4\n')),(0,l.kt)("p",null,"Now, there are 3 Pods, each of which has an individual image. If we then delete the Pod with the image nginx:1.24.0, the new Pod replacing it will be created with the same image nginx:1.24.0 in order for the Pod to inherit the revision."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl delete -n default delete pod collaset-sample-qs46r\npod "collaset-sample-qs46r" deleted\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5tgcs 1/1 Running 0 3h\ncollaset-sample-ht9x6 1/1 Running 0 2m27s # Pod recreated\ncollaset-sample-qs46r 1/1 Running 1 (3h ago) 3h\n\n$ kubectl get pod -o yaml | grep "image: nginx"\n - image: nginx:1.25.2\n - image: nginx:1.24.0 # image has not been changed\n - image: nginx:1.23.4\n')),(0,l.kt)("h3",{id:"updating-pods-1"},"Updating Pods"),(0,l.kt)("h4",{id:"update-policy"},"Update Policy"),(0,l.kt)("p",null,"In addition to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," update policy, which is identical to Deployment and StatefulSet, CollaSet offers the ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," update policy."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # Options: InPlaceIfPossible, ReCreate\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," is the default value, which instructs CollaSets to try to update Pods in place when only container images, labels, and annotations have changed. If some other fields have changed too, the policy will back off to the ",(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," policy."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"ReCreate")," indicates CollaSets always delete the old Pod and create a new one with an updated revision."),(0,l.kt)("p",null,"If update pod template with ",(0,l.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible")," policy as following example, the Pod will not be recreated."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl -n default edit cls collaset-sample\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: collaset-sample\nspec:\n template:\n ......\n spec:\n containers:\n - image: nginx:1.24.0 # changed from nginx:1.25.2\n ...\n updateStrategy:\n podUpgradePolicy: InPlaceIfPossible # use InPlaceIfPossible policy\n\n$ kubectl -n default get pod -o yaml | grep "image: nginx"\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n - image: nginx:1.24.0\n\n$ kubectl -n default get pod\nNAME READY STATUS RESTARTS AGE\ncollaset-sample-5wvlh 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-ldvrg 1/1 Running 1 (6s ago) 2m10s\ncollaset-sample-pbz75 1/1 Running 1 (6s ago) 2m10s\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9662bf8d.a11ba1b1.js b/assets/js/9662bf8d.a11ba1b1.js deleted file mode 100644 index 4c6c359657a..00000000000 --- a/assets/js/9662bf8d.a11ba1b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8194],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=r.createContext({}),l=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=l(e.components);return r.createElement(s.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=l(t),m=i,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(h,o(o({ref:n},c),{},{components:t})):r.createElement(h,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=u;var p={};for(var s in n)hasOwnProperty.call(n,s)&&(p[s]=n[s]);p.originalType=e,p.mdxType="string"==typeof e?e:i,o[1]=p;for(var l=2;l{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>l});var r=t(87462),i=(t(67294),t(3905));const a={},o="Expose Service",p={unversionedId:"kusion/user-guides/working-with-k8s/service",id:"version-v0.10/kusion/user-guides/working-with-k8s/service",title:"Expose Service",description:"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/3-service.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/service",permalink:"/docs/kusion/user-guides/working-with-k8s/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/3-service.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Containers",permalink:"/docs/kusion/user-guides/working-with-k8s/container"},next:{title:"Upgrade Image",permalink:"/docs/kusion/user-guides/working-with-k8s/image-upgrade"}},s={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function d(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"expose-service"},"Expose Service"),(0,i.kt)("p",null,"You can determine how to expose your service in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). The ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field defines a list of all the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port"),"s you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications."),(0,i.kt)("p",null,"Unless explicitly defined, each of the ports exposed is by default exposed privately as a ",(0,i.kt)("inlineCode",{parentName:"p"},"ClusterIP")," type service. You can expose a port publicly by specifying the ",(0,i.kt)("inlineCode",{parentName:"p"},"exposeInternet")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema. At the moment, the implementation for publicly access is done via Load Balancer type service backed by cloud providers. Ingress will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-port"},"here")," for more details."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the services to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/networking/port"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 8080\n targetPort: 80\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"The code above changes the service port to expose from ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," in the last guide to ",(0,i.kt)("inlineCode",{parentName:"p"},"8080"),", but still targeting the container port ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," because that's what the application is listening on."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new service configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Update\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld UnChanged\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Update v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS UnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip \nUnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the Kubernetes service now has the updated attributes (mapping service port 8080 to container port 80) as defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl get svc -n simple-service -o yaml\n...\n spec:\n ...\n ports:\n - name: simple-service-dev-helloworld-private-8080-tcp\n port: 8080\n protocol: TCP\n targetPort: 80\n...\n")),(0,i.kt)("p",null,"Exposing service port 8080:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:8080\n")),(0,i.kt)("p",null,"Open browser and visit ",(0,i.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),", the application should be up and running\uff1a"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"app-preview",src:t(92287).Z,width:"1830",height:"330"})))}d.isMDXComponent=!0},92287:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/9662bf8d.e0078cb6.js b/assets/js/9662bf8d.e0078cb6.js new file mode 100644 index 00000000000..75bde0ca69b --- /dev/null +++ b/assets/js/9662bf8d.e0078cb6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8194],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=r.createContext({}),l=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=l(e.components);return r.createElement(s.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=l(t),m=i,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(h,o(o({ref:n},c),{},{components:t})):r.createElement(h,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=u;var p={};for(var s in n)hasOwnProperty.call(n,s)&&(p[s]=n[s]);p.originalType=e,p.mdxType="string"==typeof e?e:i,o[1]=p;for(var l=2;l{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>l});var r=t(87462),i=(t(67294),t(3905));const a={},o="Expose Service",p={unversionedId:"kusion/user-guides/working-with-k8s/service",id:"version-v0.10/kusion/user-guides/working-with-k8s/service",title:"Expose Service",description:"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/3-service.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/service",permalink:"/docs/kusion/user-guides/working-with-k8s/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/3-service.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Containers",permalink:"/docs/kusion/user-guides/working-with-k8s/container"},next:{title:"Upgrade Image",permalink:"/docs/kusion/user-guides/working-with-k8s/image-upgrade"}},s={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function d(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"expose-service"},"Expose Service"),(0,i.kt)("p",null,"You can determine how to expose your service in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). The ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field defines a list of all the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port"),"s you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications."),(0,i.kt)("p",null,"Unless explicitly defined, each of the ports exposed is by default exposed privately as a ",(0,i.kt)("inlineCode",{parentName:"p"},"ClusterIP")," type service. You can expose a port publicly by specifying the ",(0,i.kt)("inlineCode",{parentName:"p"},"exposeInternet")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema. At the moment, the implementation for publicly access is done via Load Balancer type service backed by cloud providers. Ingress will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-port"},"here")," for more details."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the services to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/networking/port"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 8080\n targetPort: 80\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"The code above changes the service port to expose from ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," in the last guide to ",(0,i.kt)("inlineCode",{parentName:"p"},"8080"),", but still targeting the container port ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," because that's what the application is listening on."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new service configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Update\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld UnChanged\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Update v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS UnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip \nUnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the Kubernetes service now has the updated attributes (mapping service port 8080 to container port 80) as defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl get svc -n simple-service -o yaml\n...\n spec:\n ...\n ports:\n - name: simple-service-dev-helloworld-private-8080-tcp\n port: 8080\n protocol: TCP\n targetPort: 80\n...\n")),(0,i.kt)("p",null,"Exposing service port 8080:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:8080\n")),(0,i.kt)("p",null,"Open browser and visit ",(0,i.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),", the application should be up and running\uff1a"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"app-preview",src:t(92287).Z,width:"1830",height:"330"})))}d.isMDXComponent=!0},92287:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/977fdfc4.4b11e617.js b/assets/js/977fdfc4.4b11e617.js new file mode 100644 index 00000000000..228d439b41c --- /dev/null +++ b/assets/js/977fdfc4.4b11e617.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[135],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(n),m=o,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||r;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{n.d(t,{Z:()=>i});var a=n(67294),o=n(86010);const r="tabItem_Ymn6";function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r,i),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>S});var a=n(87462),o=n(67294),r=n(86010),i=n(12466),s=n(76775),l=n(91980),u=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=o.Children.map(e,(e=>{if(!e||(0,o.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function d(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),r=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=d(e),[i,s]=(0,o.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=n.find((e=>e.default))??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:r}))),[l,u]=h({queryString:n,groupId:a}),[p,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),k=(()=>{const e=l??p;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{k&&s(k)}),[k]);return{selectedValue:i,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,r]),tabValues:r}}var k=n(72389);const g="tabList__CuJ",b="tabItem_LNqP";function y(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(p(t),l(a))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:i}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},i,{className:(0,r.Z)("tabs__item",b,null==i?void 0:i.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;const r=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=r.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function w(e){const t=f(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",g)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(v,(0,a.Z)({},e,t)))}function S(e){const t=(0,k.Z)();return o.createElement(w,(0,a.Z)({key:String(t)},e))}},81087:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>u,toc:()=>p});var a=n(87462),o=(n(67294),n(3905)),r=n(74866),i=n(85162);const s={id:"databse"},l="Managed Databases",u={unversionedId:"kusion/configuration-walkthrough/databse",id:"kusion/configuration-walkthrough/databse",title:"Managed Databases",description:"You could also specify a database needed for the application. That can be achieved via a mysql or a postgres module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.",source:"@site/docs/kusion/4-configuration-walkthrough/6-database.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/databse",permalink:"/docs/next/kusion/configuration-walkthrough/databse",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/6-database.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"databse"},sidebar:"kusion",previous:{title:"Application Networking",permalink:"/docs/next/kusion/configuration-walkthrough/networking"},next:{title:"Secrets",permalink:"/docs/next/kusion/configuration-walkthrough/secret"}},c={},p=[{value:"Import",id:"import",level:2},{value:"Types of Database offerings",id:"types-of-database-offerings",level:2},{value:"Cloud Credentials and Permissions",id:"cloud-credentials-and-permissions",level:2},{value:"Configure Database",id:"configure-database",level:2},{value:"Provision a Cloud Database",id:"provision-a-cloud-database",level:3},{value:"AWS RDS Instance",id:"aws-rds-instance",level:4},{value:"AliCloud RDS Instance",id:"alicloud-rds-instance",level:4},{value:"Local Database",id:"local-database",level:3},{value:"Database Credentials",id:"database-credentials",level:2},{value:"Configure Network Access",id:"configure-network-access",level:2},{value:"Subnet ID",id:"subnet-id",level:3},{value:"Private Routing",id:"private-routing",level:3}],d={toc:p};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"managed-databases"},"Managed Databases"),(0,o.kt)("p",null,"You could also specify a database needed for the application. That can be achieved via a ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql")," or a ",(0,o.kt)("inlineCode",{parentName:"p"},"postgres")," module (or bring-your-own-module) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that."),(0,o.kt)("p",null,"You can currently have several databases with ",(0,o.kt)("strong",{parentName:"p"},"different database names")," for an application at the same time."),(0,o.kt)("h2",{id:"import"},"Import"),(0,o.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,o.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/configuration-walkthrough/overview#configuration-file-overview"},"Configuration File Overview"),"."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport mysql.mysql\nimport postgres.postgres\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod")," must contain reference to the ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql")," module or ",(0,o.kt)("inlineCode",{parentName:"p"},"postgres")," module:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'#...\n\n[dependencies]\nmysql = { oci = "oci://ghcr.io/kusionstack/mysql", tag = "0.1.0" }\npostgres = { oci = "oci://ghcr.io/kusionstack/postgres", tag = "0.1.0" }\n#...\n')),(0,o.kt)("h2",{id:"types-of-database-offerings"},"Types of Database offerings"),(0,o.kt)("p",null,"As of version 0.11.0, Kusion supports the following database offerings on the cloud:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,o.kt)("a",{parentName:"li",href:"https://aws.amazon.com/rds/"},"AWS")),(0,o.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,o.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/databases"},"AliCloud"))),(0,o.kt)("p",null,"More database types on more cloud vendors will be added in the future."),(0,o.kt)("p",null,"Alternatively, Kusion also supports creating a database at ",(0,o.kt)("inlineCode",{parentName:"p"},"localhost")," for local testing needs. A local database is quicker to stand up and easier to manage. It also eliminates the need for an account and any relevant costs with the cloud providers in the case that a local testing environment is sufficient."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"You do need a local Kubernetes cluster to run the local database workloads. You can refer to ",(0,o.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/start/"},"Minikube")," or ",(0,o.kt)("a",{parentName:"p",href:"https://kind.sigs.k8s.io/docs/user/quick-start/"},"Kind")," to get started.\nTo see an end-to-end use case for standing up a local testing environment including a local database, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/getting-started/deliver-wordpress"},"Kusion Quickstart"),".")),(0,o.kt)("h2",{id:"cloud-credentials-and-permissions"},"Cloud Credentials and Permissions"),(0,o.kt)("p",null,"Kusion provisions databases on the cloud via ",(0,o.kt)("a",{parentName:"p",href:"https://www.terraform.io/"},"terraform")," providers. For it to create ",(0,o.kt)("em",{parentName:"p"},"any")," cloud resources, it requires a set of credentials that belongs to an account that has the appropriate write access so the terraform provider can be initialized properly."),(0,o.kt)("p",null,"For AWS, the environment variables needed:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'export AWS_ACCESS_KEY_ID="xxxxxxxxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="xxxxxxx" # replace it with your SecretKey\n')),(0,o.kt)("p",null,"For AliCloud, the environment variables needed:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'export ALICLOUD_ACCESS_KEY="xxxxxxxxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="xxxxxxxxx" # replace it with your SecretKey\n')),(0,o.kt)("p",null,"The user account that owns these credentials would need to have the proper permission policies attached to create databases and security groups. If you are using the cloud-managed policies, the policies needed to provision a database and configure firewall rules are listed below."),(0,o.kt)("p",null,"For AWS:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AmazonVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AmazonRDSFullAccess")," for creating and managing RDS instances")),(0,o.kt)("p",null,"For AliCloud:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AliyunVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AliyunRDSFullAccess")," for creating and managing RDS instances")),(0,o.kt)("p",null,"Alternatively, you can use customer managed policies if the cloud provider built-in policies don't meet your needs. The list of permissions needed are in the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonRDSFullAccess.html#AmazonRDSFullAccess-json"},"AmazonRDSFullAccess Policy Document")," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonVPCFullAccess.html"},"AmazonVPCFullAccess Policy Document"),". It will most likely be a subset of the permissions in the policy documents."),(0,o.kt)("h2",{id:"configure-database"},"Configure Database"),(0,o.kt)("h3",{id:"provision-a-cloud-database"},"Provision a Cloud Database"),(0,o.kt)("p",null,"Assuming the steps in the ",(0,o.kt)("a",{parentName:"p",href:"#cloud-credentials-and-permissions"},"Cloud Credentials and Permissions")," section is setup properly, you can now provision cloud databases via Kusion."),(0,o.kt)("h4",{id:"aws-rds-instance"},"AWS RDS Instance"),(0,o.kt)("p",null,"To provision an AWS RDS instance with MySQL v8.0 or PostgreSQL v14.0, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". "),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# MySQL configurations for AWS RDS\nmodules: \n kusionstack/mysql@0.1.0:\n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# PostgreSQL configurations for AWS RDS\nmodules: \n kusionstack/postgres@0.1.0:\n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,o.kt)("p",null,"For KCL configuration file declarations: "),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n accessories: {\n "mysql": mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n accessories: {\n "postgres": postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,o.kt)("p",null,"It's highly recommended to replace ",(0,o.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," and closely manage the whitelist of IPs that can access the database for security purposes. The ",(0,o.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," in the example above or if ",(0,o.kt)("inlineCode",{parentName:"p"},"securityIPs")," is omitted altogether will allow connections from anywhere which would typically be a security bad practice."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceType")," field determines the computation and memory capacity of the RDS instance. The ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.micro")," instance type in the example above represents the ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3")," instance class with a size of ",(0,o.kt)("inlineCode",{parentName:"p"},"micro"),". In the same ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3")," instance family there are also ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.small"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.medium"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.2xlarge"),", etc."),(0,o.kt)("p",null,"The full list of supported ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Support"},"here"),"."),(0,o.kt)("p",null,"You can also adjust the storage capacity for the database instance by changing the ",(0,o.kt)("inlineCode",{parentName:"p"},"size")," field which is storage size measured in gigabytes. The minimum is 20. More details can be found ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#Concepts.Storage.GeneralSSD"},"here"),"."),(0,o.kt)("h4",{id:"alicloud-rds-instance"},"AliCloud RDS Instance"),(0,o.kt)("p",null,"To provision an Alicloud RDS instance with MySQL or PostgreSQL, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". Note that AliCloud RDS has several additional fields such as ",(0,o.kt)("inlineCode",{parentName:"p"},"category"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting"),":"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# MySQL configurations for Alicloud RDS\nmodules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# PostgreSQL configurations for Alicloud RDS\nmodules: \n kusionstack/postgres@0.1.0:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,o.kt)("p",null,"For KCL configuration file declarations: "),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n accessories: {\n "mysql": mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n accessories: {\n "postgres": postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,o.kt)("p",null,"We will walkthrough ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting")," in the ",(0,o.kt)("a",{parentName:"p",href:"#configure-network-access"},"Configure Network Access")," section."),(0,o.kt)("p",null,"The full list of supported ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found in:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/primary-apsaradb-rds-for-mysql-instance-types#concept-2096487"},"MySQL instance types(x86)")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/primary-apsaradb-rds-for-postgresql-instance-types#concept-2096578"},"PostgreSQL instance types"))),(0,o.kt)("h3",{id:"local-database"},"Local Database"),(0,o.kt)("p",null,"To deploy a local database with MySQL v8.0 or PostgreSQL v14.0:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n accessories: {\n "mysql": mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n accessories: {\n "postgres": postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n }\n }\n}\n')))),(0,o.kt)("h2",{id:"database-credentials"},"Database Credentials"),(0,o.kt)("p",null,"There is no need to manage the database credentials manually. Kusion will automatically generate a random password, set it as the credential when creating the database, and then inject the hostname, username and password into the application runtime."),(0,o.kt)("p",null,"You have the option to BYO (Bring Your Own) username for the database credential by specifying the ",(0,o.kt)("inlineCode",{parentName:"p"},"username")," attribute in the ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n kusionstack/mysql@0.1.0:\n default:\n # ...\n username: "my_username"\n')),(0,o.kt)("p",null,"You ",(0,o.kt)("strong",{parentName:"p"},"cannot")," bring your own password. The password will always be managed by Kusion automatically."),(0,o.kt)("p",null,"The database credentials are injected into the environment variables of the application container. You can access them via the following env vars:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"# env | grep KUSION_DB\nKUSION_DB_HOST_WORDPRESS_MYSQL=wordpress.xxxxxxxx.us-east-1.rds.amazonaws.com\nKUSION_DB_USERNAME_WORDPRESS_MYSQL=xxxxxxxxx\nKUSION_DB_PASSWORD_WORDPRESS_MYSQL=xxxxxxxxx\n")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the environment of database credentials injected by Kusion can be found at ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/postgres#credentials-and-connectivity"},"postgres credentials and connectivity"))),(0,o.kt)("p",null,"You can use these environment variables out of the box. Or most likely, your application might retrieve the connection details from a different set of environment variables. In that case, you can map the kusion environment variables to the ones expected by your application using the ",(0,o.kt)("inlineCode",{parentName:"p"},"$()")," expression. "),(0,o.kt)("p",null,"This example below will assign the value of ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_WORDPRESS_MYSQL")," into ",(0,o.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_HOST"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_USERNAME_WORDPRESS_MYSQL")," into ",(0,o.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER"),", likewise for ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_PASSWORD_WORDPRESS_MYSQL")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_PASSWORD"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3-apache"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n }\n # ...\n }\n }\n # ...\n }\n accessories: {\n # ...\n }\n}\n')),(0,o.kt)("h2",{id:"configure-network-access"},"Configure Network Access"),(0,o.kt)("p",null,"You can also optionally configure the network access to the database as part of the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". This is highly recommended because it dramatically increases the security posture of your cloud environment in the means of least privilege principle."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"securityIPs")," field in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Database")," schema declares the list of network addresses that are allowed to access the database. The network addresses are in the ",(0,o.kt)("a",{parentName:"p",href:"https://aws.amazon.com/what-is/cidr/"},"CIDR notation")," and can be either a private IP range (",(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc1918"},"RFC-1918")," and ",(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6598"},"RFC-6598")," address) or a public one."),(0,o.kt)("p",null,"If the database need to be accessed from a public location (which should most likely not be the case in a production environment), ",(0,o.kt)("inlineCode",{parentName:"p"},"securityIPs")," need to include the public IP address of the traffic source (For instance, if the RDS database needs to be accessed from your computer)."),(0,o.kt)("p",null,"To configure AWS RDS to restrict network access from a VPC with a CIDR of ",(0,o.kt)("inlineCode",{parentName:"p"},"10.0.1.0/24")," and a public IP of ",(0,o.kt)("inlineCode",{parentName:"p"},"103.192.227.125"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: aws\n # ...\n securityIPs: \n - "10.0.1.0/24"\n - "103.192.227.125/32"\n')),(0,o.kt)("p",null,"Depending on the cloud provider, the default behavior of the database firewall settings may differ if omitted."),(0,o.kt)("h3",{id:"subnet-id"},"Subnet ID"),(0,o.kt)("p",null,"On AWS, you have the option to launch the RDS instance inside a specific VPC if a ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," is present in the application configuration. By default, if ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," is not provided, the RDS will be created in the default VPC for that account. However, the recommendation is to self-manage your VPCs to provider better isolation from a network security perspective."),(0,o.kt)("p",null,"On AliCloud, the ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," is required. The concept of subnet maps to VSwitch in AliCloud."),(0,o.kt)("p",null,"To place the RDS instance into a specific VPC on Alicloud:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: alicloud\n # ...\n subnetID: "subnet-xxxxxxxxxxxxxxxx"\n')),(0,o.kt)("h3",{id:"private-routing"},"Private Routing"),(0,o.kt)("p",null,"There is an option to enforce private routing on certain cloud providers if both the workload and the database are running on the cloud."),(0,o.kt)("p",null,"On AliCloud, you can set the ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,o.kt)("inlineCode",{parentName:"p"},"True"),". The database host generated will be a private FQDN that is only resolvable and accessible from within the AliCloud VPCs. Setting ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,o.kt)("inlineCode",{parentName:"p"},"True")," when ",(0,o.kt)("inlineCode",{parentName:"p"},"type")," is ",(0,o.kt)("inlineCode",{parentName:"p"},"aws")," is a no-op."),(0,o.kt)("p",null,"To enforce private routing on AliCloud:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"modules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: alicloud\n # ...\n privateRouting: true\n")),(0,o.kt)("p",null,"Kusion will then generate a private FQDN and inject it into the application runtime as the environment variable ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_")," for the application to use. A complete list of Kusion-managed environment variables for mysql database can be found ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"here"),"."),(0,o.kt)("p",null,"Otherwise when using the public FQDN to connect to a database from the workload, the route will depend on cloud provider's routing preference. The options are generally either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Travel as far as possible on the cloud provider's global backbone network, or also referred to as cold potato routing, or"),(0,o.kt)("li",{parentName:"ul"},"Egress as early as possible to the public Internet and re-enter the cloud provider's datacenter later, or also referred to as hot potato routing")),(0,o.kt)("p",null,"The prior generally has better performance but is also more expensive."),(0,o.kt)("p",null,"You can find a good read on the ",(0,o.kt)("a",{parentName:"p",href:"https://aws.amazon.com/blogs/architecture/internet-routing-and-traffic-engineering/"},"AWS Blog")," or the ",(0,o.kt)("a",{parentName:"p",href:"https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/routing-preference-overview"},"Microsoft Learn"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/977fdfc4.f3c7fcf1.js b/assets/js/977fdfc4.f3c7fcf1.js deleted file mode 100644 index d647a9cda37..00000000000 --- a/assets/js/977fdfc4.f3c7fcf1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[135],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(n),m=o,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||r;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{n.d(t,{Z:()=>i});var a=n(67294),o=n(86010);const r="tabItem_Ymn6";function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r,i),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>S});var a=n(87462),o=n(67294),r=n(86010),i=n(12466),s=n(76775),l=n(91980),u=n(67392),c=n(50012);function p(e){return function(e){var t;return(null==(t=o.Children.map(e,(e=>{if(!e||(0,o.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function d(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),r=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=d(e),[i,s]=(0,o.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=n.find((e=>e.default))??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:r}))),[l,u]=h({queryString:n,groupId:a}),[p,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),k=(()=>{const e=l??p;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{k&&s(k)}),[k]);return{selectedValue:i,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,r]),tabValues:r}}var k=n(72389);const g="tabList__CuJ",b="tabItem_LNqP";function y(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(p(t),l(a))},m=e=>{var t;let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}null==(t=n)||t.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:i}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},i,{className:(0,r.Z)("tabs__item",b,null==i?void 0:i.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;const r=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=r.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function w(e){const t=f(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",g)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(v,(0,a.Z)({},e,t)))}function S(e){const t=(0,k.Z)();return o.createElement(w,(0,a.Z)({key:String(t)},e))}},81087:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>u,toc:()=>p});var a=n(87462),o=(n(67294),n(3905)),r=n(74866),i=n(85162);const s={id:"databse"},l="Managed Databases",u={unversionedId:"kusion/configuration-walkthrough/databse",id:"kusion/configuration-walkthrough/databse",title:"Managed Databases",description:"You could also specify a database needed for the application. That can be achieved via a mysql or a postgres module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.",source:"@site/docs/kusion/4-configuration-walkthrough/6-database.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/databse",permalink:"/docs/next/kusion/configuration-walkthrough/databse",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/6-database.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{id:"databse"},sidebar:"kusion",previous:{title:"Application Networking",permalink:"/docs/next/kusion/configuration-walkthrough/networking"},next:{title:"Secrets",permalink:"/docs/next/kusion/configuration-walkthrough/secret"}},c={},p=[{value:"Import",id:"import",level:2},{value:"Types of Database offerings",id:"types-of-database-offerings",level:2},{value:"Cloud Credentials and Permissions",id:"cloud-credentials-and-permissions",level:2},{value:"Configure Database",id:"configure-database",level:2},{value:"Provision a Cloud Database",id:"provision-a-cloud-database",level:3},{value:"AWS RDS Instance",id:"aws-rds-instance",level:4},{value:"AliCloud RDS Instance",id:"alicloud-rds-instance",level:4},{value:"Local Database",id:"local-database",level:3},{value:"Database Credentials",id:"database-credentials",level:2},{value:"Configure Network Access",id:"configure-network-access",level:2},{value:"Subnet ID",id:"subnet-id",level:3},{value:"Private Routing",id:"private-routing",level:3}],d={toc:p};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"managed-databases"},"Managed Databases"),(0,o.kt)("p",null,"You could also specify a database needed for the application. That can be achieved via a ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql")," or a ",(0,o.kt)("inlineCode",{parentName:"p"},"postgres")," module (or bring-your-own-module) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that."),(0,o.kt)("p",null,"You can currently have several databases with ",(0,o.kt)("strong",{parentName:"p"},"different database names")," for an application at the same time."),(0,o.kt)("h2",{id:"import"},"Import"),(0,o.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,o.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/configuration-walkthrough/overview#configuration-file-overview"},"Configuration File Overview"),"."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport mysql.mysql\nimport postgres.postgres\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod")," must contain reference to the ",(0,o.kt)("inlineCode",{parentName:"p"},"mysql")," module or ",(0,o.kt)("inlineCode",{parentName:"p"},"postgres")," module:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'#...\n\n[dependencies]\nmysql = { oci = "oci://ghcr.io/kusionstack/mysql", tag = "0.1.0" }\npostgres = { oci = "oci://ghcr.io/kusionstack/postgres", tag = "0.1.0" }\n#...\n')),(0,o.kt)("h2",{id:"types-of-database-offerings"},"Types of Database offerings"),(0,o.kt)("p",null,"As of version 0.11.0, Kusion supports the following database offerings on the cloud:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,o.kt)("a",{parentName:"li",href:"https://aws.amazon.com/rds/"},"AWS")),(0,o.kt)("li",{parentName:"ul"},"MySQL and PostgreSQL Relational Database Service (RDS) on ",(0,o.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/databases"},"AliCloud"))),(0,o.kt)("p",null,"More database types on more cloud vendors will be added in the future."),(0,o.kt)("p",null,"Alternatively, Kusion also supports creating a database at ",(0,o.kt)("inlineCode",{parentName:"p"},"localhost")," for local testing needs. A local database is quicker to stand up and easier to manage. It also eliminates the need for an account and any relevant costs with the cloud providers in the case that a local testing environment is sufficient."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"You do need a local Kubernetes cluster to run the local database workloads. You can refer to ",(0,o.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/start/"},"Minikube")," or ",(0,o.kt)("a",{parentName:"p",href:"https://kind.sigs.k8s.io/docs/user/quick-start/"},"Kind")," to get started.\nTo see an end-to-end use case for standing up a local testing environment including a local database, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/getting-started/deliver-wordpress"},"Kusion Quickstart"),".")),(0,o.kt)("h2",{id:"cloud-credentials-and-permissions"},"Cloud Credentials and Permissions"),(0,o.kt)("p",null,"Kusion provisions databases on the cloud via ",(0,o.kt)("a",{parentName:"p",href:"https://www.terraform.io/"},"terraform")," providers. For it to create ",(0,o.kt)("em",{parentName:"p"},"any")," cloud resources, it requires a set of credentials that belongs to an account that has the appropriate write access so the terraform provider can be initialized properly."),(0,o.kt)("p",null,"For AWS, the environment variables needed:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'export AWS_ACCESS_KEY_ID="xxxxxxxxxxx" # replace it with your AccessKey\nexport AWS_SECRET_ACCESS_KEY="xxxxxxx" # replace it with your SecretKey\n')),(0,o.kt)("p",null,"For AliCloud, the environment variables needed:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'export ALICLOUD_ACCESS_KEY="xxxxxxxxx" # replace it with your AccessKey\nexport ALICLOUD_SECRET_KEY="xxxxxxxxx" # replace it with your SecretKey\n')),(0,o.kt)("p",null,"The user account that owns these credentials would need to have the proper permission policies attached to create databases and security groups. If you are using the cloud-managed policies, the policies needed to provision a database and configure firewall rules are listed below."),(0,o.kt)("p",null,"For AWS:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AmazonVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AmazonRDSFullAccess")," for creating and managing RDS instances")),(0,o.kt)("p",null,"For AliCloud:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AliyunVPCFullAccess")," for creating and managing database firewall rules via security group"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"AliyunRDSFullAccess")," for creating and managing RDS instances")),(0,o.kt)("p",null,"Alternatively, you can use customer managed policies if the cloud provider built-in policies don't meet your needs. The list of permissions needed are in the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonRDSFullAccess.html#AmazonRDSFullAccess-json"},"AmazonRDSFullAccess Policy Document")," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonVPCFullAccess.html"},"AmazonVPCFullAccess Policy Document"),". It will most likely be a subset of the permissions in the policy documents."),(0,o.kt)("h2",{id:"configure-database"},"Configure Database"),(0,o.kt)("h3",{id:"provision-a-cloud-database"},"Provision a Cloud Database"),(0,o.kt)("p",null,"Assuming the steps in the ",(0,o.kt)("a",{parentName:"p",href:"#cloud-credentials-and-permissions"},"Cloud Credentials and Permissions")," section is setup properly, you can now provision cloud databases via Kusion."),(0,o.kt)("h4",{id:"aws-rds-instance"},"AWS RDS Instance"),(0,o.kt)("p",null,"To provision an AWS RDS instance with MySQL v8.0 or PostgreSQL v14.0, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". "),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# MySQL configurations for AWS RDS\nmodules: \n kusionstack/mysql@0.1.0:\n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1 # Please replace with your own aws provider region\n\n# PostgreSQL configurations for AWS RDS\nmodules: \n kusionstack/postgres@0.1.0:\n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,o.kt)("p",null,"For KCL configuration file declarations: "),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n accessories: {\n "mysql": mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n accessories: {\n "postgres": postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,o.kt)("p",null,"It's highly recommended to replace ",(0,o.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," and closely manage the whitelist of IPs that can access the database for security purposes. The ",(0,o.kt)("inlineCode",{parentName:"p"},"0.0.0.0/0")," in the example above or if ",(0,o.kt)("inlineCode",{parentName:"p"},"securityIPs")," is omitted altogether will allow connections from anywhere which would typically be a security bad practice."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceType")," field determines the computation and memory capacity of the RDS instance. The ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.micro")," instance type in the example above represents the ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3")," instance class with a size of ",(0,o.kt)("inlineCode",{parentName:"p"},"micro"),". In the same ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3")," instance family there are also ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.small"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.medium"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"db.t3.2xlarge"),", etc."),(0,o.kt)("p",null,"The full list of supported ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Support"},"here"),"."),(0,o.kt)("p",null,"You can also adjust the storage capacity for the database instance by changing the ",(0,o.kt)("inlineCode",{parentName:"p"},"size")," field which is storage size measured in gigabytes. The minimum is 20. More details can be found ",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#Concepts.Storage.GeneralSSD"},"here"),"."),(0,o.kt)("h4",{id:"alicloud-rds-instance"},"AliCloud RDS Instance"),(0,o.kt)("p",null,"To provision an Alicloud RDS instance with MySQL or PostgreSQL, you can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". Note that AliCloud RDS has several additional fields such as ",(0,o.kt)("inlineCode",{parentName:"p"},"category"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting"),":"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# MySQL configurations for Alicloud RDS\nmodules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: alicloud\n size: 20\n instanceType: mysql.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-mysql"\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing # Please replace with your own alicloud provider region\n\n# PostgreSQL configurations for Alicloud RDS\nmodules: \n kusionstack/postgres@0.1.0:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))),(0,o.kt)("p",null,"For KCL configuration file declarations: "),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n accessories: {\n "mysql": mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n accessories: {\n "postgres": postgres.PostgreSQL {\n type: "cloud"\n version: "14.0"\n }\n }\n}\n')))),(0,o.kt)("p",null,"We will walkthrough ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting")," in the ",(0,o.kt)("a",{parentName:"p",href:"#configure-network-access"},"Configure Network Access")," section."),(0,o.kt)("p",null,"The full list of supported ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceType")," values can be found in:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-mysql/primary-apsaradb-rds-for-mysql-instance-types#concept-2096487"},"MySQL instance types(x86)")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/primary-apsaradb-rds-for-postgresql-instance-types#concept-2096578"},"PostgreSQL instance types"))),(0,o.kt)("h3",{id:"local-database"},"Local Database"),(0,o.kt)("p",null,"To deploy a local database with MySQL v8.0 or PostgreSQL v14.0:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(i.Z,{value:"MySQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'wordpress: ac.AppConfiguration {\n # ...\n accessories: {\n "mysql": mysql.MySQL {\n type: "local"\n version: "8.0"\n }\n }\n}\n'))),(0,o.kt)(i.Z,{value:"PostgreSQL",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'pgadmin: ac.AppConfiguration {\n # ...\n accessories: {\n "postgres": postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n }\n }\n}\n')))),(0,o.kt)("h2",{id:"database-credentials"},"Database Credentials"),(0,o.kt)("p",null,"There is no need to manage the database credentials manually. Kusion will automatically generate a random password, set it as the credential when creating the database, and then inject the hostname, username and password into the application runtime."),(0,o.kt)("p",null,"You have the option to BYO (Bring Your Own) username for the database credential by specifying the ",(0,o.kt)("inlineCode",{parentName:"p"},"username")," attribute in the ",(0,o.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n kusionstack/mysql@0.1.0:\n default:\n # ...\n username: "my_username"\n')),(0,o.kt)("p",null,"You ",(0,o.kt)("strong",{parentName:"p"},"cannot")," bring your own password. The password will always be managed by Kusion automatically."),(0,o.kt)("p",null,"The database credentials are injected into the environment variables of the application container. You can access them via the following env vars:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"# env | grep KUSION_DB\nKUSION_DB_HOST_WORDPRESS_MYSQL=wordpress.xxxxxxxx.us-east-1.rds.amazonaws.com\nKUSION_DB_USERNAME_WORDPRESS_MYSQL=xxxxxxxxx\nKUSION_DB_PASSWORD_WORDPRESS_MYSQL=xxxxxxxxx\n")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"More details about the environment of database credentials injected by Kusion can be found at ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"mysql credentials and connectivity")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/postgres#credentials-and-connectivity"},"postgres credentials and connectivity"))),(0,o.kt)("p",null,"You can use these environment variables out of the box. Or most likely, your application might retrieve the connection details from a different set of environment variables. In that case, you can map the kusion environment variables to the ones expected by your application using the ",(0,o.kt)("inlineCode",{parentName:"p"},"$()")," expression. "),(0,o.kt)("p",null,"This example below will assign the value of ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_WORDPRESS_MYSQL")," into ",(0,o.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_HOST"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_USERNAME_WORDPRESS_MYSQL")," into ",(0,o.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_USER"),", likewise for ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_PASSWORD_WORDPRESS_MYSQL")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"WORDPRESS_DB_PASSWORD"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image = "wordpress:6.3-apache"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n }\n # ...\n }\n }\n # ...\n }\n accessories: {\n # ...\n }\n}\n')),(0,o.kt)("h2",{id:"configure-network-access"},"Configure Network Access"),(0,o.kt)("p",null,"You can also optionally configure the network access to the database as part of the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". This is highly recommended because it dramatically increases the security posture of your cloud environment in the means of least privilege principle."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"securityIPs")," field in the ",(0,o.kt)("inlineCode",{parentName:"p"},"Database")," schema declares the list of network addresses that are allowed to access the database. The network addresses are in the ",(0,o.kt)("a",{parentName:"p",href:"https://aws.amazon.com/what-is/cidr/"},"CIDR notation")," and can be either a private IP range (",(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc1918"},"RFC-1918")," and ",(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6598"},"RFC-6598")," address) or a public one."),(0,o.kt)("p",null,"If the database need to be accessed from a public location (which should most likely not be the case in a production environment), ",(0,o.kt)("inlineCode",{parentName:"p"},"securityIPs")," need to include the public IP address of the traffic source (For instance, if the RDS database needs to be accessed from your computer)."),(0,o.kt)("p",null,"To configure AWS RDS to restrict network access from a VPC with a CIDR of ",(0,o.kt)("inlineCode",{parentName:"p"},"10.0.1.0/24")," and a public IP of ",(0,o.kt)("inlineCode",{parentName:"p"},"103.192.227.125"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: aws\n # ...\n securityIPs: \n - "10.0.1.0/24"\n - "103.192.227.125/32"\n')),(0,o.kt)("p",null,"Depending on the cloud provider, the default behavior of the database firewall settings may differ if omitted."),(0,o.kt)("h3",{id:"subnet-id"},"Subnet ID"),(0,o.kt)("p",null,"On AWS, you have the option to launch the RDS instance inside a specific VPC if a ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," is present in the application configuration. By default, if ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," is not provided, the RDS will be created in the default VPC for that account. However, the recommendation is to self-manage your VPCs to provider better isolation from a network security perspective."),(0,o.kt)("p",null,"On AliCloud, the ",(0,o.kt)("inlineCode",{parentName:"p"},"subnetID")," is required. The concept of subnet maps to VSwitch in AliCloud."),(0,o.kt)("p",null,"To place the RDS instance into a specific VPC on Alicloud:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'modules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: alicloud\n # ...\n subnetID: "subnet-xxxxxxxxxxxxxxxx"\n')),(0,o.kt)("h3",{id:"private-routing"},"Private Routing"),(0,o.kt)("p",null,"There is an option to enforce private routing on certain cloud providers if both the workload and the database are running on the cloud."),(0,o.kt)("p",null,"On AliCloud, you can set the ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,o.kt)("inlineCode",{parentName:"p"},"True"),". The database host generated will be a private FQDN that is only resolvable and accessible from within the AliCloud VPCs. Setting ",(0,o.kt)("inlineCode",{parentName:"p"},"privateRouting")," flag to ",(0,o.kt)("inlineCode",{parentName:"p"},"True")," when ",(0,o.kt)("inlineCode",{parentName:"p"},"type")," is ",(0,o.kt)("inlineCode",{parentName:"p"},"aws")," is a no-op."),(0,o.kt)("p",null,"To enforce private routing on AliCloud:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"modules: \n kusionstack/mysql@0.1.0: \n default: \n cloud: alicloud\n # ...\n privateRouting: true\n")),(0,o.kt)("p",null,"Kusion will then generate a private FQDN and inject it into the application runtime as the environment variable ",(0,o.kt)("inlineCode",{parentName:"p"},"KUSION_DB_HOST_")," for the application to use. A complete list of Kusion-managed environment variables for mysql database can be found ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/kusion/reference/modules/catalog-models/database/mysql#credentials-and-connectivity"},"here"),"."),(0,o.kt)("p",null,"Otherwise when using the public FQDN to connect to a database from the workload, the route will depend on cloud provider's routing preference. The options are generally either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Travel as far as possible on the cloud provider's global backbone network, or also referred to as cold potato routing, or"),(0,o.kt)("li",{parentName:"ul"},"Egress as early as possible to the public Internet and re-enter the cloud provider's datacenter later, or also referred to as hot potato routing")),(0,o.kt)("p",null,"The prior generally has better performance but is also more expensive."),(0,o.kt)("p",null,"You can find a good read on the ",(0,o.kt)("a",{parentName:"p",href:"https://aws.amazon.com/blogs/architecture/internet-routing-and-traffic-engineering/"},"AWS Blog")," or the ",(0,o.kt)("a",{parentName:"p",href:"https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/routing-preference-overview"},"Microsoft Learn"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/97d4b178.23c0f1d6.js b/assets/js/97d4b178.23c0f1d6.js new file mode 100644 index 00000000000..e6f29dc0c17 --- /dev/null +++ b/assets/js/97d4b178.23c0f1d6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5644],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,r(r({ref:t},d),{},{components:n})):a.createElement(k,r({ref:t},d))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(87462),i=(n(67294),n(3905));const o={id:"kcl-basics"},r="KCL Basics",l={unversionedId:"kusion/configuration-walkthrough/kcl-basics",id:"kusion/configuration-walkthrough/kcl-basics",title:"KCL Basics",description:"Table of Content",source:"@site/docs/kusion/4-configuration-walkthrough/2-kcl-basics.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/kcl-basics",permalink:"/docs/next/kusion/configuration-walkthrough/kcl-basics",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/2-kcl-basics.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kcl-basics"},sidebar:"kusion",previous:{title:"Configuration File Overview",permalink:"/docs/next/kusion/configuration-walkthrough/overview"},next:{title:"Base and Override",permalink:"/docs/next/kusion/configuration-walkthrough/base-override"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Variable assignments",id:"variable-assignments",level:2},{value:"Common built-in types",id:"common-built-in-types",level:2},{value:"Lists and maps",id:"lists-and-maps",level:2},{value:"Conditional statements",id:"conditional-statements",level:2},{value:"The : and = operator",id:"the--and--operator",level:2},{value:"Advanced KCL capabilities",id:"advanced-kcl-capabilities",level:2}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kcl-basics"},"KCL Basics"),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#variable-assignments"},"Variable assignments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#common-built-in-types"},"Common built-in types")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#lists-and-maps"},"Lists and maps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#conditional-statements"},"Conditional statements")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#the--and--operator"},"The : and = operator")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#advanced-kcl-capabilities"},"Advanced KCL capabilities"))),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h2",{id:"variable-assignments"},"Variable assignments"),(0,i.kt)("p",null,"There are two ways to initialize a variable in KCL. You can either use the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," operator or the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss the difference between them in ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},"this section later"),"."),(0,i.kt)("p",null,"Here are the two ways to create a variable and initialize it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'foo = "Foo" # Declare a variable named `foo` and its value is a string literal "Foo"\nbar: "Bar" # Declare a variable named `bar` and its value is a string literal "Bar"\n')),(0,i.kt)("p",null,"You will be able to override a variable assignment via the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss this in depth in the ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},(0,i.kt)("inlineCode",{parentName:"a"},":")," and ",(0,i.kt)("inlineCode",{parentName:"a"},"=")," operator section"),"."),(0,i.kt)("h2",{id:"common-built-in-types"},"Common built-in types"),(0,i.kt)("p",null,"KCL supports ",(0,i.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"float"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"bool")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"string")," as the built-in types."),(0,i.kt)("p",null,"Other types are defined in the packages that are imported into the application configuration files. One such example would be the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object (or ",(0,i.kt)("inlineCode",{parentName:"p"},"Container"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Probe"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," object, etc) that are defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"kam")," repository."),(0,i.kt)("h2",{id:"lists-and-maps"},"Lists and maps"),(0,i.kt)("p",null,"Lists are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"[]")," notation.\nAn example of lists:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"list0 = [1, 2, 3]\nlist1 = [4, 5, 6]\njoined_list = list0 + list1 # [1, 2, 3, 4, 5, 6]\n")),(0,i.kt)("p",null,"Maps are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," notation.\nAn example of maps:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"a = {\"one\" = 1, \"two\" = 2, \"three\" = 3}\nb = {'one' = 1, 'two' = 2, 'three' = 3}\nassert a == b # True\nassert len(a) == 3 # True\n")),(0,i.kt)("h2",{id:"conditional-statements"},"Conditional statements"),(0,i.kt)("p",null,"You can also use basic control flow statements when writing the configuration file."),(0,i.kt)("p",null,"An example that sets the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," conditionally based on the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"containers.myapp.resources.cpu"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1 if containers.myapp.resources.cpu == "500m" else 2\n }\n}\n')),(0,i.kt)("p",null,"For more details on KCL's control flow statements, please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#control-flow-statements"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"the--and--operator"},"The ",(0,i.kt)("inlineCode",{parentName:"h2"},":")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"=")," operator"),(0,i.kt)("p",null,"You might have noticed there is a mixed usage of the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," in the samples above."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"TLDR: The recommendation is to use ",(0,i.kt)("inlineCode",{parentName:"strong"},":")," in the common configurations, and ",(0,i.kt)("inlineCode",{parentName:"strong"},"=")," for override in the environment-specific configurations."))),(0,i.kt)("p",null,"In KCL:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},":")," represents a union-ed value assignment. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: T E"),", the value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will be merged and union-ed into the element value."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"=")," represents a value override. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = T E"),", The value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will override the ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier")," attribute value.")),(0,i.kt)("p",null,"Let's take a look at an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is one configuration that will be merged.\nconfig: Config {\n data.d1 = 1\n}\n# This is another configuration that will be merged.\nconfig: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The above is equivalent to the snippet below since the two expressions for ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," get merged/union-ed into one:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d1 = 1\n data.d2 = 1\n}\n")),(0,i.kt)("p",null,"whereas using the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operators will result in a different outcome:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is first configuration.\nconfig = Config {\n data.d1 = 1\n}\n# This is second configuration that will override the prior one.\nconfig = Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The config above results in:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict with each other."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"data0 = {id: 1} | {id: 2} # Error\uff1aconflicting values between {'id': 2} and {'id': 1}\ndata1 = {id: 1} | {id = 2} # Ok, the value of `data` is {\"id\": 2}\n")),(0,i.kt)("p",null,"More about ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator can be found in the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#config-operations"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"advanced-kcl-capabilities"},"Advanced KCL capabilities"),(0,i.kt)("p",null,"For more advanced KCL capabilities, please visit the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/97d4b178.5c4f0b6b.js b/assets/js/97d4b178.5c4f0b6b.js deleted file mode 100644 index 5870348c1f8..00000000000 --- a/assets/js/97d4b178.5c4f0b6b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5644],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,r(r({ref:t},d),{},{components:n})):a.createElement(k,r({ref:t},d))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(87462),i=(n(67294),n(3905));const o={id:"kcl-basics"},r="KCL Basics",l={unversionedId:"kusion/configuration-walkthrough/kcl-basics",id:"kusion/configuration-walkthrough/kcl-basics",title:"KCL Basics",description:"Table of Content",source:"@site/docs/kusion/4-configuration-walkthrough/2-kcl-basics.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/kcl-basics",permalink:"/docs/next/kusion/configuration-walkthrough/kcl-basics",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/2-kcl-basics.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kcl-basics"},sidebar:"kusion",previous:{title:"Configuration File Overview",permalink:"/docs/next/kusion/configuration-walkthrough/overview"},next:{title:"Base and Override",permalink:"/docs/next/kusion/configuration-walkthrough/base-override"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Variable assignments",id:"variable-assignments",level:2},{value:"Common built-in types",id:"common-built-in-types",level:2},{value:"Lists and maps",id:"lists-and-maps",level:2},{value:"Conditional statements",id:"conditional-statements",level:2},{value:"The : and = operator",id:"the--and--operator",level:2},{value:"Advanced KCL capabilities",id:"advanced-kcl-capabilities",level:2}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kcl-basics"},"KCL Basics"),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#variable-assignments"},"Variable assignments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#common-built-in-types"},"Common built-in types")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#lists-and-maps"},"Lists and maps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#conditional-statements"},"Conditional statements")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#the--and--operator"},"The : and = operator")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#advanced-kcl-capabilities"},"Advanced KCL capabilities"))),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h2",{id:"variable-assignments"},"Variable assignments"),(0,i.kt)("p",null,"There are two ways to initialize a variable in KCL. You can either use the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," operator or the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss the difference between them in ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},"this section later"),"."),(0,i.kt)("p",null,"Here are the two ways to create a variable and initialize it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'foo = "Foo" # Declare a variable named `foo` and its value is a string literal "Foo"\nbar: "Bar" # Declare a variable named `bar` and its value is a string literal "Bar"\n')),(0,i.kt)("p",null,"You will be able to override a variable assignment via the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss this in depth in the ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},(0,i.kt)("inlineCode",{parentName:"a"},":")," and ",(0,i.kt)("inlineCode",{parentName:"a"},"=")," operator section"),"."),(0,i.kt)("h2",{id:"common-built-in-types"},"Common built-in types"),(0,i.kt)("p",null,"KCL supports ",(0,i.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"float"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"bool")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"string")," as the built-in types."),(0,i.kt)("p",null,"Other types are defined in the packages that are imported into the application configuration files. One such example would be the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object (or ",(0,i.kt)("inlineCode",{parentName:"p"},"Container"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Probe"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," object, etc) that are defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"kam")," repository."),(0,i.kt)("h2",{id:"lists-and-maps"},"Lists and maps"),(0,i.kt)("p",null,"Lists are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"[]")," notation.\nAn example of lists:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"list0 = [1, 2, 3]\nlist1 = [4, 5, 6]\njoined_list = list0 + list1 # [1, 2, 3, 4, 5, 6]\n")),(0,i.kt)("p",null,"Maps are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," notation.\nAn example of maps:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"a = {\"one\" = 1, \"two\" = 2, \"three\" = 3}\nb = {'one' = 1, 'two' = 2, 'three' = 3}\nassert a == b # True\nassert len(a) == 3 # True\n")),(0,i.kt)("h2",{id:"conditional-statements"},"Conditional statements"),(0,i.kt)("p",null,"You can also use basic control flow statements when writing the configuration file."),(0,i.kt)("p",null,"An example that sets the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," conditionally based on the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"containers.myapp.resources.cpu"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1 if containers.myapp.resources.cpu == "500m" else 2\n }\n}\n')),(0,i.kt)("p",null,"For more details on KCL's control flow statements, please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#control-flow-statements"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"the--and--operator"},"The ",(0,i.kt)("inlineCode",{parentName:"h2"},":")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"=")," operator"),(0,i.kt)("p",null,"You might have noticed there is a mixed usage of the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," in the samples above."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"TLDR: The recommendation is to use ",(0,i.kt)("inlineCode",{parentName:"strong"},":")," in the common configurations, and ",(0,i.kt)("inlineCode",{parentName:"strong"},"=")," for override in the environment-specific configurations."))),(0,i.kt)("p",null,"In KCL:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},":")," represents a union-ed value assignment. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: T E"),", the value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will be merged and union-ed into the element value."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"=")," represents a value override. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = T E"),", The value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will override the ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier")," attribute value.")),(0,i.kt)("p",null,"Let's take a look at an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is one configuration that will be merged.\nconfig: Config {\n data.d1 = 1\n}\n# This is another configuration that will be merged.\nconfig: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The above is equivalent to the snippet below since the two expressions for ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," get merged/union-ed into one:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d1 = 1\n data.d2 = 1\n}\n")),(0,i.kt)("p",null,"whereas using the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operators will result in a different outcome:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is first configuration.\nconfig = Config {\n data.d1 = 1\n}\n# This is second configuration that will override the prior one.\nconfig = Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The config above results in:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict with each other."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"data0 = {id: 1} | {id: 2} # Error\uff1aconflicting values between {'id': 2} and {'id': 1}\ndata1 = {id: 1} | {id = 2} # Ok, the value of `data` is {\"id\": 2}\n")),(0,i.kt)("p",null,"More about ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator can be found in the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#config-operations"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"advanced-kcl-capabilities"},"Advanced KCL capabilities"),(0,i.kt)("p",null,"For more advanced KCL capabilities, please visit the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/99000770.1311682f.js b/assets/js/99000770.1311682f.js deleted file mode 100644 index 9cfcac0ad76..00000000000 --- a/assets/js/99000770.1311682f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[920],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=p(r),m=a,k=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return r?n.createElement(k,l(l({ref:t},s),{},{components:r})):n.createElement(k,l({ref:t},s))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=u;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=r(87462),a=(r(67294),r(3905));const o={},l="port",i={unversionedId:"kusion/reference/model/catalog_models/internal/network/doc_port",id:"version-v0.9/kusion/reference/model/catalog_models/internal/network/doc_port",title:"port",description:"Schema Port",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/network/doc_port.md",sourceDirName:"kusion/reference/model/catalog_models/internal/network",slug:"/kusion/reference/model/catalog_models/internal/network/doc_port",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/network/doc_port.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"common",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common"},next:{title:"secret",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret"}},c={},p=[{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],s={toc:p};function d(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("h2",{id:"schema-port"},"Schema Port"),(0,a.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,a.kt)("br",null),"get accessed."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The exposed port of the Service."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"80"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"targetPort"),(0,a.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"protocol"),(0,a.kt)("br",null),"The protocol to access the port."),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"public"),(0,a.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"False"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/99000770.ffe7dc96.js b/assets/js/99000770.ffe7dc96.js new file mode 100644 index 00000000000..aeac0e7678a --- /dev/null +++ b/assets/js/99000770.ffe7dc96.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[920],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=p(r),m=a,k=u["".concat(c,".").concat(m)]||u[m]||s[m]||o;return r?n.createElement(k,l(l({ref:t},d),{},{components:r})):n.createElement(k,l({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=u;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>s,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=r(87462),a=(r(67294),r(3905));const o={},l="port",i={unversionedId:"kusion/reference/model/catalog_models/internal/network/doc_port",id:"version-v0.9/kusion/reference/model/catalog_models/internal/network/doc_port",title:"port",description:"Schema Port",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/network/doc_port.md",sourceDirName:"kusion/reference/model/catalog_models/internal/network",slug:"/kusion/reference/model/catalog_models/internal/network/doc_port",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/network/doc_port.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"common",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common"},next:{title:"secret",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret"}},c={},p=[{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],d={toc:p};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("h2",{id:"schema-port"},"Schema Port"),(0,a.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,a.kt)("br",null),"get accessed."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The exposed port of the Service."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"80"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"targetPort"),(0,a.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"protocol"),(0,a.kt)("br",null),"The protocol to access the port."),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"public"),(0,a.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"False"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/990e3068.d6055d90.js b/assets/js/990e3068.d6055d90.js new file mode 100644 index 00000000000..ae954511d34 --- /dev/null +++ b/assets/js/990e3068.d6055d90.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4796],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),s=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(n),d=a,f=m["".concat(i,".").concat(d)]||m[d]||u[d]||o;return n?r.createElement(f,l(l({ref:t},p),{},{components:n})):r.createElement(f,l({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="lifecycle",c={unversionedId:"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",id:"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",title:"lifecycle",description:"Schema Lifecycle",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle",slug:"/kusion/reference/modules/catalog-models/internal/container/lifecycle/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"container",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/"},next:{title:"probe",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/"}},i={},s=[{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"lifecycle"},"lifecycle"),(0,a.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,a.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,a.kt)("br",null),"to container lifecycle events."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"preStop"),(0,a.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,a.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"postStart"),(0,a.kt)("br",null),"The action to be taken after a container is created.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/990e3068.f5be684b.js b/assets/js/990e3068.f5be684b.js deleted file mode 100644 index f98b6a3e592..00000000000 --- a/assets/js/990e3068.f5be684b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4796],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),s=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(n),d=a,f=m["".concat(i,".").concat(d)]||m[d]||u[d]||o;return n?r.createElement(f,l(l({ref:t},p),{},{components:n})):r.createElement(f,l({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="lifecycle",c={unversionedId:"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",id:"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",title:"lifecycle",description:"Schema Lifecycle",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle",slug:"/kusion/reference/modules/catalog-models/internal/container/lifecycle/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"container",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/"},next:{title:"probe",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/"}},i={},s=[{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"lifecycle"},"lifecycle"),(0,a.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,a.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,a.kt)("br",null),"to container lifecycle events."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"preStop"),(0,a.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,a.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"postStart"),(0,a.kt)("br",null),"The action to be taken after a container is created.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/99153eb1.5a891290.js b/assets/js/99153eb1.5a891290.js deleted file mode 100644 index 8000cd3d543..00000000000 --- a/assets/js/99153eb1.5a891290.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9010],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>k});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),k=i,m=u["".concat(s,".").concat(k)]||u[k]||d[k]||r;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function k(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var a=n(87462),i=(n(67294),n(3905));const r={},o="Backend Configuration",l={unversionedId:"kusion/reference/cli/backend/backend-configuration",id:"version-v0.9/kusion/reference/cli/backend/backend-configuration",title:"Backend Configuration",description:"The backend configuration defines the place where Kusion stores its state data file. By default, Kusion uses the local type of backend to store the state on the local disk, while for team collaboration projects, the state can be stored on a remote type of backend, such as database, oss and s3 to allow multiple users access it.",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/backend/backend-configuration.md",sourceDirName:"kusion/reference/cli/backend",slug:"/kusion/reference/cli/backend/backend-configuration",permalink:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/backend/backend-configuration.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion version",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version"},next:{title:"Kusion Model Library",permalink:"/docs/v0.9/kusion/reference/model/"}},s={},c=[{value:"Configuring State Backend",id:"configuring-state-backend",level:2},{value:"Command Line Parameters",id:"command-line-parameters",level:3},{value:"Configuration File",id:"configuration-file",level:3},{value:"Configuration Combination",id:"configuration-combination",level:3},{value:"Available Backend",id:"available-backend",level:2},{value:"Default Backend",id:"default-backend",level:3},{value:"local",id:"local",level:3},{value:"oss",id:"oss",level:3},{value:"s3",id:"s3",level:3},{value:"db",id:"db",level:3}],p={toc:c};function d(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"backend-configuration"},"Backend Configuration"),(0,i.kt)("p",null,"The backend configuration defines the place where Kusion stores its ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," data file. By default, Kusion uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"local")," type of backend to store the state on the local disk, while for team collaboration projects, the state can be stored on a ",(0,i.kt)("inlineCode",{parentName:"p"},"remote")," type of backend, such as ",(0,i.kt)("inlineCode",{parentName:"p"},"database"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"oss")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," to allow multiple users access it. "),(0,i.kt)("h2",{id:"configuring-state-backend"},"Configuring State Backend"),(0,i.kt)("p",null,"Kusion configures the storage of state through command line parameters or the ",(0,i.kt)("inlineCode",{parentName:"p"},"backend")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file. "),(0,i.kt)("h3",{id:"command-line-parameters"},"Command Line Parameters"),(0,i.kt)("p",null,"Users can specify the type of backend with the option ",(0,i.kt)("inlineCode",{parentName:"p"},"--backend-type"),", and configure the detailed information with ",(0,i.kt)("inlineCode",{parentName:"p"},"--backend-config")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-C"),", for instance: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --backend-type local --backend-config path=kusion_state.json\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --backend-type local --backend-config path=kusion_state.json\n")),(0,i.kt)("h3",{id:"configuration-file"},"Configuration File"),(0,i.kt)("p",null,"Users can configure the storage of the state with the ",(0,i.kt)("inlineCode",{parentName:"p"},"backend")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: local\n config: \n path: kusion_state.json\n")),(0,i.kt)("p",null,"In this case, ",(0,i.kt)("inlineCode",{parentName:"p"},"storageType")," is used to declare the type of storage for the state backend, and ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," is used to declare the required parameters for the corresponding storage type. "),(0,i.kt)("h3",{id:"configuration-combination"},"Configuration Combination"),(0,i.kt)("p",null,"When both of the ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," and the ",(0,i.kt)("inlineCode",{parentName:"p"},"--backend-config")," option in the command line are configured, Kusion will merge the entire configuration, combining both the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file and the command line options. When there comes a conflict between the options in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file and the command line, the options in the ",(0,i.kt)("strong",{parentName:"p"},"command line")," will take precedence. This way, users can pass the sensitive information like ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeyID")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeySecret")," to Kusion through command line parameters. "),(0,i.kt)("h2",{id:"available-backend"},"Available Backend"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"local"),(0,i.kt)("li",{parentName:"ul"},"oss"),(0,i.kt)("li",{parentName:"ul"},"s3"),(0,i.kt)("li",{parentName:"ul"},"db")),(0,i.kt)("h3",{id:"default-backend"},"Default Backend"),(0,i.kt)("p",null,"When neither the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file nor the command line parameters declare the backend configuration, Kusion by default uses the ",(0,i.kt)("a",{parentName:"p",href:"#local"},"local"),". "),(0,i.kt)("h3",{id:"local"},"local"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"local")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," on the local file system, which is suitable for local operations while not ideal for multi-user collaboration. "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: local\n config: \n path: kusion_state.json\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - local, using local file system to store the state"),(0,i.kt)("li",{parentName:"ul"},"path - ",(0,i.kt)("inlineCode",{parentName:"li"},"optional")," specify the local file path to store the state")),(0,i.kt)("h3",{id:"oss"},"oss"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"oss")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,i.kt)("strong",{parentName:"p"},"Alicloud Object Storage Service (OSS)"),". "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend:\n storageType: oss\n config: \n endpoint: oss-cn-beijing.aliyuncs.com\n bucket: kusion-oss\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - oss, using alicloud oss as the storage backend for state"),(0,i.kt)("li",{parentName:"ul"},"endpoint - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the access endpoint for alicloud oss bucket"),(0,i.kt)("li",{parentName:"ul"},"bucket - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the alicloud oss bucket"),(0,i.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeyID"),(0,i.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeySecret")),(0,i.kt)("h3",{id:"s3"},"s3"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,i.kt)("strong",{parentName:"p"},"AWS Simple Storage Service (S3)"),". "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: s3\n config: \n endpoint: s3.us-east-1.amazonaws.com\n bucket: kusion-s3\n region: us-east-1\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - s3, using aws s3 as the storage backend for state"),(0,i.kt)("li",{parentName:"ul"},"endpoint - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the access endpoint for aws s3 bucket"),(0,i.kt)("li",{parentName:"ul"},"bucket - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the aws s3 bucket"),(0,i.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeyID"),(0,i.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeySecret")),(0,i.kt)("h3",{id:"db"},"db"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"db")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," into a ",(0,i.kt)("strong",{parentName:"p"},"database"),". "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: db\n config: \n dbHost: 127.0.0.1\n dbName: kusion-db\n dbPort: 3306\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply -C dbUser=******* -C dbPassword=*******\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - db, using database as the storage backend for state"),(0,i.kt)("li",{parentName:"ul"},"dbHost - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the access address for the database"),(0,i.kt)("li",{parentName:"ul"},"dbName - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the name of the database"),(0,i.kt)("li",{parentName:"ul"},"dbPort - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the port of the database"),(0,i.kt)("li",{parentName:"ul"},"dbUser - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the user name of the database"),(0,i.kt)("li",{parentName:"ul"},"dbPassword - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the password of the database")),(0,i.kt)("p",null,"Note that the table name in the database used by Kusion is ",(0,i.kt)("strong",{parentName:"p"},"state"),". Below is an example SQL statement for creating this table: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sql"},"CREATE TABLE `state` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',\n `tenant` varchar(100) DEFAULT NULL COMMENT 'tenant',\n `project` varchar(100) NOT NULL COMMENT 'project',\n `kusion_version` varchar(50) DEFAULT NULL COMMENT 'kusion version',\n `version` int(10) unsigned NOT NULL COMMENT 'current state format version\uff0cmay upgrade in the future',\n `serial` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'modification times for state\uff0ccan be used in concurrent control',\n `operator` varchar(100) DEFAULT NULL COMMENT 'last modifier',\n `resources` longtext DEFAULT NULL COMMENT 'state of the resources\uff0cjson array',\n `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'creation time',\n `modified_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'update time',\n `stack` varchar(100) DEFAULT NULL COMMENT 'stack',\n `cluster` varchar(100) DEFAULT NULL COMMENT 'logical isolation in a stack\uff0cusually clustername__cellname',\n PRIMARY KEY (`id`),\n UNIQUE KEY `uk_state_latest` (`tenant`, `project`, `stack`, `serial`, `cluster`),\n KEY `idx_tenant` (`tenant`),\n KEY `idx_project` (`project`),\n KEY `idx_kusion_version` (`kusion_version`),\n KEY `idx_version` (`version`),\n KEY `idx_create_time` (`create_time`),\n KEY `idx_modified_time` (`modified_time`),\n KEY `idx_stack` (`stack`),\n KEY `idx_cluster` (`cluster`)\n);\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/99153eb1.dbb20b4b.js b/assets/js/99153eb1.dbb20b4b.js new file mode 100644 index 00000000000..c9a57528729 --- /dev/null +++ b/assets/js/99153eb1.dbb20b4b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9010],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>k});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),k=i,m=u["".concat(s,".").concat(k)]||u[k]||d[k]||r;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function k(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var a=n(87462),i=(n(67294),n(3905));const r={},o="Backend Configuration",l={unversionedId:"kusion/reference/cli/backend/backend-configuration",id:"version-v0.9/kusion/reference/cli/backend/backend-configuration",title:"Backend Configuration",description:"The backend configuration defines the place where Kusion stores its state data file. By default, Kusion uses the local type of backend to store the state on the local disk, while for team collaboration projects, the state can be stored on a remote type of backend, such as database, oss and s3 to allow multiple users access it.",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/backend/backend-configuration.md",sourceDirName:"kusion/reference/cli/backend",slug:"/kusion/reference/cli/backend/backend-configuration",permalink:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/backend/backend-configuration.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion version",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version"},next:{title:"Kusion Model Library",permalink:"/docs/v0.9/kusion/reference/model/"}},s={},c=[{value:"Configuring State Backend",id:"configuring-state-backend",level:2},{value:"Command Line Parameters",id:"command-line-parameters",level:3},{value:"Configuration File",id:"configuration-file",level:3},{value:"Configuration Combination",id:"configuration-combination",level:3},{value:"Available Backend",id:"available-backend",level:2},{value:"Default Backend",id:"default-backend",level:3},{value:"local",id:"local",level:3},{value:"oss",id:"oss",level:3},{value:"s3",id:"s3",level:3},{value:"db",id:"db",level:3}],p={toc:c};function d(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"backend-configuration"},"Backend Configuration"),(0,i.kt)("p",null,"The backend configuration defines the place where Kusion stores its ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," data file. By default, Kusion uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"local")," type of backend to store the state on the local disk, while for team collaboration projects, the state can be stored on a ",(0,i.kt)("inlineCode",{parentName:"p"},"remote")," type of backend, such as ",(0,i.kt)("inlineCode",{parentName:"p"},"database"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"oss")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," to allow multiple users access it. "),(0,i.kt)("h2",{id:"configuring-state-backend"},"Configuring State Backend"),(0,i.kt)("p",null,"Kusion configures the storage of state through command line parameters or the ",(0,i.kt)("inlineCode",{parentName:"p"},"backend")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file. "),(0,i.kt)("h3",{id:"command-line-parameters"},"Command Line Parameters"),(0,i.kt)("p",null,"Users can specify the type of backend with the option ",(0,i.kt)("inlineCode",{parentName:"p"},"--backend-type"),", and configure the detailed information with ",(0,i.kt)("inlineCode",{parentName:"p"},"--backend-config")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-C"),", for instance: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply --backend-type local --backend-config path=kusion_state.json\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy --backend-type local --backend-config path=kusion_state.json\n")),(0,i.kt)("h3",{id:"configuration-file"},"Configuration File"),(0,i.kt)("p",null,"Users can configure the storage of the state with the ",(0,i.kt)("inlineCode",{parentName:"p"},"backend")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: local\n config: \n path: kusion_state.json\n")),(0,i.kt)("p",null,"In this case, ",(0,i.kt)("inlineCode",{parentName:"p"},"storageType")," is used to declare the type of storage for the state backend, and ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," is used to declare the required parameters for the corresponding storage type. "),(0,i.kt)("h3",{id:"configuration-combination"},"Configuration Combination"),(0,i.kt)("p",null,"When both of the ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," and the ",(0,i.kt)("inlineCode",{parentName:"p"},"--backend-config")," option in the command line are configured, Kusion will merge the entire configuration, combining both the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file and the command line options. When there comes a conflict between the options in the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file and the command line, the options in the ",(0,i.kt)("strong",{parentName:"p"},"command line")," will take precedence. This way, users can pass the sensitive information like ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeyID")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"accessKeySecret")," to Kusion through command line parameters. "),(0,i.kt)("h2",{id:"available-backend"},"Available Backend"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"local"),(0,i.kt)("li",{parentName:"ul"},"oss"),(0,i.kt)("li",{parentName:"ul"},"s3"),(0,i.kt)("li",{parentName:"ul"},"db")),(0,i.kt)("h3",{id:"default-backend"},"Default Backend"),(0,i.kt)("p",null,"When neither the ",(0,i.kt)("inlineCode",{parentName:"p"},"project.yaml")," file nor the command line parameters declare the backend configuration, Kusion by default uses the ",(0,i.kt)("a",{parentName:"p",href:"#local"},"local"),". "),(0,i.kt)("h3",{id:"local"},"local"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"local")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," on the local file system, which is suitable for local operations while not ideal for multi-user collaboration. "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: local\n config: \n path: kusion_state.json\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - local, using local file system to store the state"),(0,i.kt)("li",{parentName:"ul"},"path - ",(0,i.kt)("inlineCode",{parentName:"li"},"optional")," specify the local file path to store the state")),(0,i.kt)("h3",{id:"oss"},"oss"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"oss")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,i.kt)("strong",{parentName:"p"},"Alicloud Object Storage Service (OSS)"),". "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend:\n storageType: oss\n config: \n endpoint: oss-cn-beijing.aliyuncs.com\n bucket: kusion-oss\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - oss, using alicloud oss as the storage backend for state"),(0,i.kt)("li",{parentName:"ul"},"endpoint - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the access endpoint for alicloud oss bucket"),(0,i.kt)("li",{parentName:"ul"},"bucket - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the alicloud oss bucket"),(0,i.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeyID"),(0,i.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the alicloud account accessKeySecret")),(0,i.kt)("h3",{id:"s3"},"s3"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"s3")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," on the ",(0,i.kt)("strong",{parentName:"p"},"AWS Simple Storage Service (S3)"),". "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: s3\n config: \n endpoint: s3.us-east-1.amazonaws.com\n bucket: kusion-s3\n region: us-east-1\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion destroy -C accessKeyID=******* -C accessKeySecret=*******\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - s3, using aws s3 as the storage backend for state"),(0,i.kt)("li",{parentName:"ul"},"endpoint - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the access endpoint for aws s3 bucket"),(0,i.kt)("li",{parentName:"ul"},"bucket - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the name of the aws s3 bucket"),(0,i.kt)("li",{parentName:"ul"},"accessKeyID - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeyID"),(0,i.kt)("li",{parentName:"ul"},"accessKeySecret - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," specify the aws account accessKeySecret")),(0,i.kt)("h3",{id:"db"},"db"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"db")," storage type stores the ",(0,i.kt)("inlineCode",{parentName:"p"},"state")," into a ",(0,i.kt)("strong",{parentName:"p"},"database"),". "),(0,i.kt)("p",null,"Here is an example: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"# project.yaml\nbackend: \n storageType: db\n config: \n dbHost: 127.0.0.1\n dbName: kusion-db\n dbPort: 3306\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kusion apply -C dbUser=******* -C dbPassword=*******\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"storageType - db, using database as the storage backend for state"),(0,i.kt)("li",{parentName:"ul"},"dbHost - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the access address for the database"),(0,i.kt)("li",{parentName:"ul"},"dbName - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the name of the database"),(0,i.kt)("li",{parentName:"ul"},"dbPort - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the port of the database"),(0,i.kt)("li",{parentName:"ul"},"dbUser - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the user name of the database"),(0,i.kt)("li",{parentName:"ul"},"dbPassword - ",(0,i.kt)("inlineCode",{parentName:"li"},"required")," the password of the database")),(0,i.kt)("p",null,"Note that the table name in the database used by Kusion is ",(0,i.kt)("strong",{parentName:"p"},"state"),". Below is an example SQL statement for creating this table: "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sql"},"CREATE TABLE `state` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',\n `tenant` varchar(100) DEFAULT NULL COMMENT 'tenant',\n `project` varchar(100) NOT NULL COMMENT 'project',\n `kusion_version` varchar(50) DEFAULT NULL COMMENT 'kusion version',\n `version` int(10) unsigned NOT NULL COMMENT 'current state format version\uff0cmay upgrade in the future',\n `serial` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'modification times for state\uff0ccan be used in concurrent control',\n `operator` varchar(100) DEFAULT NULL COMMENT 'last modifier',\n `resources` longtext DEFAULT NULL COMMENT 'state of the resources\uff0cjson array',\n `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'creation time',\n `modified_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'update time',\n `stack` varchar(100) DEFAULT NULL COMMENT 'stack',\n `cluster` varchar(100) DEFAULT NULL COMMENT 'logical isolation in a stack\uff0cusually clustername__cellname',\n PRIMARY KEY (`id`),\n UNIQUE KEY `uk_state_latest` (`tenant`, `project`, `stack`, `serial`, `cluster`),\n KEY `idx_tenant` (`tenant`),\n KEY `idx_project` (`project`),\n KEY `idx_kusion_version` (`kusion_version`),\n KEY `idx_version` (`version`),\n KEY `idx_create_time` (`create_time`),\n KEY `idx_modified_time` (`modified_time`),\n KEY `idx_stack` (`stack`),\n KEY `idx_cluster` (`cluster`)\n);\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9aa57586.7b227a3b.js b/assets/js/9aa57586.7b227a3b.js deleted file mode 100644 index e66042aeda5..00000000000 --- a/assets/js/9aa57586.7b227a3b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4032],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(f,i(i({ref:t},c),{},{components:n})):a.createElement(f,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(87462),o=(n(67294),n(3905));const r={sidebar_position:2},i="Kusion vs. Other Software",s={unversionedId:"kusion/intro/kusion-vs-x",id:"version-v0.9/kusion/intro/kusion-vs-x",title:"Kusion vs. Other Software",description:"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.",source:"@site/versioned_docs/version-v0.9/kusion/intro/kusion-vs-x.md",sourceDirName:"kusion/intro",slug:"/kusion/intro/kusion-vs-x",permalink:"/docs/v0.9/kusion/intro/kusion-vs-x",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/intro/kusion-vs-x.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/v0.9/"},next:{title:"Get Started",permalink:"/docs/v0.9/kusion/getting-started/"}},p={},l=[],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-vs-other-software"},"Kusion vs. Other Software"),(0,o.kt)("p",null,"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. GitOps (ArgoCD, FluxCD, etc.)")),(0,o.kt)("p",null,"According to the ",(0,o.kt)("a",{parentName:"p",href:"https://opengitops.dev/"},"open GitOps principles"),", GitOps systems typically have its desired state expressed declaratively, continuously observe actual system state and attempt to apply the desired state. In the design of Kusion toolchain, we refer to those principles but have no intention to reinvent any GitOps systems wheel. "),(0,o.kt)("p",null,"Kusion adopts your GitOps process and improves it with richness of features. The declarative ",(0,o.kt)("a",{parentName:"p",href:"../concepts/appconfiguration"},"AppConfiguration")," model can be used to express desired intent, once intent is declared ",(0,o.kt)("a",{parentName:"p",href:"../reference/cli/kusion"},"Kusion CLI")," takes the role to make production match intent as safely as possible. "),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. PaaS (Heroku, Vercel, etc.)")),(0,o.kt)("p",null,"Kusion shares the same goal with traditional PaaS platforms to provide application delivery and management capabilities. The intuitive difference from the full functionality PaaS platforms is that Kusion is a client-side toolchain, not a complete PaaS platform. "),(0,o.kt)("p",null,"Also traditional PaaS platforms typically constrain the type of applications they can run but there is no such constrain for Kusion which means Kusion provides greater flexibility."),(0,o.kt)("p",null,"Kusion allows you to have platform-like features without the constraints of a traditional PaaS. However, Kusion is not attempting to replace any PaaS platforms, instead Kusion can be used to deploy to a platform such as Heroku."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. KubeVela")),(0,o.kt)("p",null,"KubeVela is a modern software delivery and management control plane. KubeVela makes it easier to deploy and operate applications on top of Kubernetes."),(0,o.kt)("p",null,"Kusion is not a control plane. Kusion is a client-side tool for describing application intent in a declarative way and providing consistent workflow to apply that desired state."),(0,o.kt)("p",null,"With proper Generator implementation, the target Spec of ",(0,o.kt)("a",{parentName:"p",href:"../concepts/appconfiguration"},"AppConfiguration")," can be ",(0,o.kt)("a",{parentName:"p",href:"https://kubevela.io/docs/getting-started/core-concept/"},"KubeVela Application"),' and Kusion can use KubeVela to satisfy the "apply" step.'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Helm")),(0,o.kt)("p",null,"The concept of Helm originates from the ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Package_manager"},"package management")," mechanism of the operating system. It is a package management tool based on templated YAML files and supports the execution and management of resources in the package. "),(0,o.kt)("p",null,"Kusion is not a package manager. Kusion naturally provides a superset of Helm capabilities with the modeled key-value pairs, so that developers can use Kusion directly as a programable alternative to avoid the pain of writing text templates. For users who have adopted Helm, the stack compilation results in Kusion can be packaged and used in Helm format."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Kubernetes")),(0,o.kt)("p",null,'Kubernetes(K8s) is a container scheduling and management runtime widely used around the world, an "operating system" core for containers, and a platform for building platforms. Above the Kubernetes API layer, Kusion aims to provide app-centric ',(0,o.kt)("strong",{parentName:"p"},"abstraction")," and unified ",(0,o.kt)("strong",{parentName:"p"},"workspace"),", better ",(0,o.kt)("strong",{parentName:"p"},"user experience")," and automation ",(0,o.kt)("strong",{parentName:"p"},"workflow"),", and helps developers build the app delivery model easily and collaboratively."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9aa57586.b95d248d.js b/assets/js/9aa57586.b95d248d.js new file mode 100644 index 00000000000..8d7e4a91275 --- /dev/null +++ b/assets/js/9aa57586.b95d248d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4032],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(f,i(i({ref:t},c),{},{components:n})):a.createElement(f,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(87462),o=(n(67294),n(3905));const r={sidebar_position:2},i="Kusion vs. Other Software",s={unversionedId:"kusion/intro/kusion-vs-x",id:"version-v0.9/kusion/intro/kusion-vs-x",title:"Kusion vs. Other Software",description:"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.",source:"@site/versioned_docs/version-v0.9/kusion/intro/kusion-vs-x.md",sourceDirName:"kusion/intro",slug:"/kusion/intro/kusion-vs-x",permalink:"/docs/v0.9/kusion/intro/kusion-vs-x",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/intro/kusion-vs-x.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/v0.9/"},next:{title:"Get Started",permalink:"/docs/v0.9/kusion/getting-started/"}},p={},l=[],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-vs-other-software"},"Kusion vs. Other Software"),(0,o.kt)("p",null,"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. GitOps (ArgoCD, FluxCD, etc.)")),(0,o.kt)("p",null,"According to the ",(0,o.kt)("a",{parentName:"p",href:"https://opengitops.dev/"},"open GitOps principles"),", GitOps systems typically have its desired state expressed declaratively, continuously observe actual system state and attempt to apply the desired state. In the design of Kusion toolchain, we refer to those principles but have no intention to reinvent any GitOps systems wheel. "),(0,o.kt)("p",null,"Kusion adopts your GitOps process and improves it with richness of features. The declarative ",(0,o.kt)("a",{parentName:"p",href:"../concepts/appconfiguration"},"AppConfiguration")," model can be used to express desired intent, once intent is declared ",(0,o.kt)("a",{parentName:"p",href:"../reference/cli/kusion"},"Kusion CLI")," takes the role to make production match intent as safely as possible. "),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. PaaS (Heroku, Vercel, etc.)")),(0,o.kt)("p",null,"Kusion shares the same goal with traditional PaaS platforms to provide application delivery and management capabilities. The intuitive difference from the full functionality PaaS platforms is that Kusion is a client-side toolchain, not a complete PaaS platform. "),(0,o.kt)("p",null,"Also traditional PaaS platforms typically constrain the type of applications they can run but there is no such constrain for Kusion which means Kusion provides greater flexibility."),(0,o.kt)("p",null,"Kusion allows you to have platform-like features without the constraints of a traditional PaaS. However, Kusion is not attempting to replace any PaaS platforms, instead Kusion can be used to deploy to a platform such as Heroku."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. KubeVela")),(0,o.kt)("p",null,"KubeVela is a modern software delivery and management control plane. KubeVela makes it easier to deploy and operate applications on top of Kubernetes."),(0,o.kt)("p",null,"Kusion is not a control plane. Kusion is a client-side tool for describing application intent in a declarative way and providing consistent workflow to apply that desired state."),(0,o.kt)("p",null,"With proper Generator implementation, the target Spec of ",(0,o.kt)("a",{parentName:"p",href:"../concepts/appconfiguration"},"AppConfiguration")," can be ",(0,o.kt)("a",{parentName:"p",href:"https://kubevela.io/docs/getting-started/core-concept/"},"KubeVela Application"),' and Kusion can use KubeVela to satisfy the "apply" step.'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Helm")),(0,o.kt)("p",null,"The concept of Helm originates from the ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Package_manager"},"package management")," mechanism of the operating system. It is a package management tool based on templated YAML files and supports the execution and management of resources in the package. "),(0,o.kt)("p",null,"Kusion is not a package manager. Kusion naturally provides a superset of Helm capabilities with the modeled key-value pairs, so that developers can use Kusion directly as a programable alternative to avoid the pain of writing text templates. For users who have adopted Helm, the stack compilation results in Kusion can be packaged and used in Helm format."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Kubernetes")),(0,o.kt)("p",null,'Kubernetes(K8s) is a container scheduling and management runtime widely used around the world, an "operating system" core for containers, and a platform for building platforms. Above the Kubernetes API layer, Kusion aims to provide app-centric ',(0,o.kt)("strong",{parentName:"p"},"abstraction")," and unified ",(0,o.kt)("strong",{parentName:"p"},"workspace"),", better ",(0,o.kt)("strong",{parentName:"p"},"user experience")," and automation ",(0,o.kt)("strong",{parentName:"p"},"workflow"),", and helps developers build the app delivery model easily and collaboratively."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9c804087.1dc9d49f.js b/assets/js/9c804087.1dc9d49f.js deleted file mode 100644 index ce45f25fe78..00000000000 --- a/assets/js/9c804087.1dc9d49f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9373],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},l=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=u(t),m=o,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||a;return t?r.createElement(f,i(i({ref:n},l),{},{components:t})):r.createElement(f,i({ref:n},l))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=d;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var r=t(87462),o=(t(67294),t(3905));const a={},i="Kusion Commands",s={unversionedId:"kusion/reference/commands/index",id:"version-v0.10/kusion/reference/commands/index",title:"Kusion Commands",description:"Kusion is the Platform Orchestrator of KusionStack",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/index.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/",permalink:"/docs/kusion/reference/commands/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/index.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Using Cloud Secrets Manager",permalink:"/docs/kusion/user-guides/secrets-management/using-cloud-secrets"},next:{title:"kusion apply",permalink:"/docs/kusion/reference/commands/kusion-apply"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:u};function p(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-commands"},"Kusion Commands"),(0,o.kt)("p",null,"Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"As a Platform Orchestrator, Kusion delivers user intentions to Kubernetes, Clouds and On-Premise resources. Also enables asynchronous cooperation between the development and the platform team and drives the separation of concerns."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' -h, --help help for kusion\n --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-apply"},"kusion apply"),"\t - Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-build"},"kusion build"),"\t - Build Kusion modules in a Stack to the Intent"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-compile"},"kusion compile"),"\t - Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-destroy"},"kusion destroy"),"\t - Destroy resources within the stack."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-init"},"kusion init"),"\t - Initialize the scaffolding for a project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-preview"},"kusion preview"),"\t - Preview a series of resource changes within the stack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-version"},"kusion version"),"\t - Print the Kusion version information for the current context"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9c804087.6aaba070.js b/assets/js/9c804087.6aaba070.js new file mode 100644 index 00000000000..534086a1ee2 --- /dev/null +++ b/assets/js/9c804087.6aaba070.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9373],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},l=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=u(t),m=o,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||a;return t?r.createElement(f,i(i({ref:n},l),{},{components:t})):r.createElement(f,i({ref:n},l))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=d;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var r=t(87462),o=(t(67294),t(3905));const a={},i="Kusion Commands",s={unversionedId:"kusion/reference/commands/index",id:"version-v0.10/kusion/reference/commands/index",title:"Kusion Commands",description:"Kusion is the Platform Orchestrator of KusionStack",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/index.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/",permalink:"/docs/kusion/reference/commands/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/index.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Using Cloud Secrets Manager",permalink:"/docs/kusion/user-guides/secrets-management/using-cloud-secrets"},next:{title:"kusion apply",permalink:"/docs/kusion/reference/commands/kusion-apply"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:u};function p(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-commands"},"Kusion Commands"),(0,o.kt)("p",null,"Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"As a Platform Orchestrator, Kusion delivers user intentions to Kubernetes, Clouds and On-Premise resources. Also enables asynchronous cooperation between the development and the platform team and drives the separation of concerns."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' -h, --help help for kusion\n --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-apply"},"kusion apply"),"\t - Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-build"},"kusion build"),"\t - Build Kusion modules in a Stack to the Intent"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-compile"},"kusion compile"),"\t - Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-destroy"},"kusion destroy"),"\t - Destroy resources within the stack."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-init"},"kusion init"),"\t - Initialize the scaffolding for a project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-preview"},"kusion preview"),"\t - Preview a series of resource changes within the stack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-version"},"kusion version"),"\t - Print the Kusion version information for the current context"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9d1d9869.167e28fc.js b/assets/js/9d1d9869.167e28fc.js deleted file mode 100644 index 41d50dba54a..00000000000 --- a/assets/js/9d1d9869.167e28fc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5763],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=l(t),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||i;return t?r.createElement(m,s(s({ref:n},p),{},{components:t})):r.createElement(m,s({ref:n},p))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=d;var a={};for(var c in n)hasOwnProperty.call(n,c)&&(a[c]=n[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const i={},s="Kusion Modules",a={unversionedId:"kusion/reference/modules/index",id:"version-v0.10/kusion/reference/modules/index",title:"Kusion Modules",description:"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/index.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/",permalink:"/docs/kusion/reference/modules/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/index.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace",permalink:"/docs/kusion/reference/commands/kusion-workspace"},next:{title:"appconfiguration",permalink:"/docs/kusion/reference/modules/catalog-models/app-configuration"}},c={},l=[],p={toc:l};function u(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-modules"},"Kusion Modules"),(0,o.kt)("p",null,"KusionStack presets application configuration models described by KCL, where the model is called ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model"),". The GitHub repository ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," is used to store these models, which is known as ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model Library"),"."),(0,o.kt)("p",null,"The original intention of designing Kusion Model is to enhance the efficiency and improve the experience of YAML users. Through the unified application model defined by code, abstract and encapsulate complex configuration items, omit repetitive and derivable configurations, and supplement with necessary verification logic. Only the necessary attributes get exposed, users get an out-of-the-box, easy-to-understand configuration interface, which reduces the difficulty and improves the reliability of the configuration work."),(0,o.kt)("p",null,"Kusion Model Library currently provides the Kusion Model ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". The design of ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is developer-centric, based on Ant Group's decades of practice in building and managing hyperscale IDP (Internal Developer Platform), and the best practice of community. ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," describes the full lifecycle of an application."),(0,o.kt)("p",null,"A simple example of using ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to describe an application is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "wordpress": c.Container {\n image: "wordpress:latest"\n env: {\n "WORDPRESS_DB_HOST": "secret://wordpress-db/hostAddress"\n "WORDPRESS_DB_PASSWORD": "secret://wordpress-db/password"\n }\n resources: {\n "cpu": "1"\n "memory": "2Gi"\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n \n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n category: "serverless_basic"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9d1d9869.7c820359.js b/assets/js/9d1d9869.7c820359.js new file mode 100644 index 00000000000..1083114f8e2 --- /dev/null +++ b/assets/js/9d1d9869.7c820359.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5763],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=l(t),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||i;return t?r.createElement(m,s(s({ref:n},p),{},{components:t})):r.createElement(m,s({ref:n},p))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=d;var a={};for(var c in n)hasOwnProperty.call(n,c)&&(a[c]=n[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const i={},s="Kusion Modules",a={unversionedId:"kusion/reference/modules/index",id:"version-v0.10/kusion/reference/modules/index",title:"Kusion Modules",description:"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/index.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/",permalink:"/docs/kusion/reference/modules/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/index.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace",permalink:"/docs/kusion/reference/commands/kusion-workspace"},next:{title:"appconfiguration",permalink:"/docs/kusion/reference/modules/catalog-models/app-configuration"}},c={},l=[],p={toc:l};function u(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-modules"},"Kusion Modules"),(0,o.kt)("p",null,"KusionStack presets application configuration models described by KCL, where the model is called ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model"),". The GitHub repository ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," is used to store these models, which is known as ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model Library"),"."),(0,o.kt)("p",null,"The original intention of designing Kusion Model is to enhance the efficiency and improve the experience of YAML users. Through the unified application model defined by code, abstract and encapsulate complex configuration items, omit repetitive and derivable configurations, and supplement with necessary verification logic. Only the necessary attributes get exposed, users get an out-of-the-box, easy-to-understand configuration interface, which reduces the difficulty and improves the reliability of the configuration work."),(0,o.kt)("p",null,"Kusion Model Library currently provides the Kusion Model ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". The design of ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is developer-centric, based on Ant Group's decades of practice in building and managing hyperscale IDP (Internal Developer Platform), and the best practice of community. ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," describes the full lifecycle of an application."),(0,o.kt)("p",null,"A simple example of using ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to describe an application is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "wordpress": c.Container {\n image: "wordpress:latest"\n env: {\n "WORDPRESS_DB_HOST": "secret://wordpress-db/hostAddress"\n "WORDPRESS_DB_PASSWORD": "secret://wordpress-db/password"\n }\n resources: {\n "cpu": "1"\n "memory": "2Gi"\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n \n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n category: "serverless_basic"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9e3571d8.38e01710.js b/assets/js/9e3571d8.57689d11.js similarity index 54% rename from assets/js/9e3571d8.38e01710.js rename to assets/js/9e3571d8.57689d11.js index c8d415e9c40..74b810fbbd1 100644 --- a/assets/js/9e3571d8.38e01710.js +++ b/assets/js/9e3571d8.57689d11.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6103],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=l(n),f=o,d=m["".concat(c,".").concat(f)]||m[f]||u[f]||i;return n?r.createElement(d,a(a({ref:t},s),{},{components:n})):r.createElement(d,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p.mdxType="string"==typeof e?e:o,a[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={id:"configuration",sidebar_label:"Project Configuration"},a="Project Configuration",p={unversionedId:"kusion/concepts/project/configuration",id:"kusion/concepts/project/configuration",title:"Project Configuration",description:"Users can add config items of the project in project.yaml, such as the project name, generator type, Prometheus monitoring, etc.",source:"@site/docs/kusion/3-concepts/1-project/2-configuration.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/configuration",permalink:"/docs/next/kusion/concepts/project/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/1-project/2-configuration.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Project Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/next/kusion/concepts/project/overview"},next:{title:"Overview",permalink:"/docs/next/kusion/concepts/stack/overview"}},c={},l=[],s={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"project-configuration"},"Project Configuration"),(0,o.kt)("p",null,"Users can add config items of the project in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),", such as the project name, generator type, Prometheus monitoring, etc."),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The project basic info\nname: helloworld\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," are explained below."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"name"),": The name of the project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"generator"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"type"),": The type of the module generator, supports ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"KCL"),", default is ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration"),". If using the schema AppConfiguration, set type as AppConfiguration"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"prometheus"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"operatorMode"),": Decides whether Kusion runs Prometheus in ",(0,o.kt)("inlineCode",{parentName:"li"},"Operator")," mode. Kusion will generate a ",(0,o.kt)("inlineCode",{parentName:"li"},"Custom Resource")," if it is true, while generate some annotations if it is false"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"monitorType"),": The type of the monitored resource, which can be one of ",(0,o.kt)("inlineCode",{parentName:"li"},"Service")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"Pod"))))))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6103],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=l(n),f=o,d=m["".concat(c,".").concat(f)]||m[f]||u[f]||i;return n?r.createElement(d,a(a({ref:t},s),{},{components:n})):r.createElement(d,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p.mdxType="string"==typeof e?e:o,a[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={id:"configuration",sidebar_label:"Project Configuration"},a="Project Configuration",p={unversionedId:"kusion/concepts/project/configuration",id:"kusion/concepts/project/configuration",title:"Project Configuration",description:"Users can add config items of the project in project.yaml, such as the project name, generator type, Prometheus monitoring, etc.",source:"@site/docs/kusion/3-concepts/1-project/2-configuration.md",sourceDirName:"kusion/3-concepts/1-project",slug:"/kusion/concepts/project/configuration",permalink:"/docs/next/kusion/concepts/project/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/1-project/2-configuration.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Project Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/next/kusion/concepts/project/overview"},next:{title:"Overview",permalink:"/docs/next/kusion/concepts/stack/overview"}},c={},l=[],s={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"project-configuration"},"Project Configuration"),(0,o.kt)("p",null,"Users can add config items of the project in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),", such as the project name, generator type, Prometheus monitoring, etc."),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The project basic info\nname: helloworld\ngenerator:\n type: AppConfiguration\nprometheus:\n operatorMode: True\n monitorType: Service\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"project.yaml")," are explained below."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"name"),": The name of the project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"generator"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"type"),": The type of the module generator, supports ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"KCL"),", default is ",(0,o.kt)("inlineCode",{parentName:"li"},"AppConfiguration"),". If using the schema AppConfiguration, set type as AppConfiguration"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"prometheus"),":",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"operatorMode"),": Decides whether Kusion runs Prometheus in ",(0,o.kt)("inlineCode",{parentName:"li"},"Operator")," mode. Kusion will generate a ",(0,o.kt)("inlineCode",{parentName:"li"},"Custom Resource")," if it is true, while generate some annotations if it is false"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"monitorType"),": The type of the monitored resource, which can be one of ",(0,o.kt)("inlineCode",{parentName:"li"},"Service")," or ",(0,o.kt)("inlineCode",{parentName:"li"},"Pod"))))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9f069a65.668f0f89.js b/assets/js/9f069a65.668f0f89.js new file mode 100644 index 00000000000..6b65fbc82a4 --- /dev/null +++ b/assets/js/9f069a65.668f0f89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[963],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=o.createContext({}),u=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,h=m["".concat(p,".").concat(d)]||m[d]||c[d]||a;return n?o.createElement(h,i(i({ref:t},l),{},{components:n})):o.createElement(h,i({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const a={},i="Application Monitoring",s={unversionedId:"kusion/configuration-walkthrough/monitoring",id:"kusion/configuration-walkthrough/monitoring",title:"Application Monitoring",description:"You could also specify the collection of monitoring requirements for the application. That can be achieved via a monitoring module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.",source:"@site/docs/kusion/4-configuration-walkthrough/8-monitoring.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/monitoring",permalink:"/docs/next/kusion/configuration-walkthrough/monitoring",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/8-monitoring.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{},sidebar:"kusion",previous:{title:"Secrets",permalink:"/docs/next/kusion/configuration-walkthrough/secret"},next:{title:"Operational Rules",permalink:"/docs/next/kusion/configuration-walkthrough/operational-rules"}},p={},u=[{value:"Import",id:"import",level:2},{value:"Workspace configurations",id:"workspace-configurations",level:2},{value:"Managing Scraping Configuration",id:"managing-scraping-configuration",level:2},{value:"Default values",id:"default-values",level:2}],l={toc:u};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-monitoring"},"Application Monitoring"),(0,r.kt)("p",null,"You could also specify the collection of monitoring requirements for the application. That can be achieved via a ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," module (or bring-your-own-module) in the ",(0,r.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that."),(0,r.kt)("p",null,"As of version 0.11.0, Kusion supports integration with Prometheus by managing scraping behaviors in the configuration file."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For the monitoring configuration to work (more specifically, consumed by Prometheus), this requires the target cluster to have installed Prometheus correctly, either as a Kubernetes operator or a server/agent."),(0,r.kt)("p",{parentName:"admonition"},"More about how to set up Prometheus can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus"},"Prometheus User Guide for Kusion"))),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport monitoring as m\n")),(0,r.kt)("h2",{id:"workspace-configurations"},"Workspace configurations"),(0,r.kt)("p",null,"In addition to the KCL configuration file, there are also workspace-level configurations that should be set first. In an ideal scenario, this step is done by the platform engineers. "),(0,r.kt)("p",null,"In the event that they do not exist for you or your organization, e.g. if you are an individual developer, you can either do it yourself or use the ",(0,r.kt)("a",{parentName:"p",href:"#default-values"},"default values")," provided by the KusionStack team. The steps to do this yourself can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"Prometheus User Guide for Kusion"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For more details on how workspaces work, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/workspace"},"workspace concept"))),(0,r.kt)("p",null,"By separating configurations that the developers are interested in and those that platform owners are interested in, we can reduce the cognitive complexity of the application configuration and achieve separation of concern."),(0,r.kt)("p",null,"You can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n kusionstack/monitoring@v0.1.0:\n default:\n interval: 30s\n monitorType: Pod\n operatorMode: true\n scheme: http\n timeout: 15s\n")),(0,r.kt)("h2",{id:"managing-scraping-configuration"},"Managing Scraping Configuration"),(0,r.kt)("p",null,"To manage scrape configuration for the application:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n # Add the monitoring configuration backed by Prometheus\n accessories: {\n "monitoring": m.Prometheus {\n path: "/metrics"\n port: "web"\n }\n }\n}\n')),(0,r.kt)("p",null,"The example above will instruct the Prometheus job to scrape metrics from the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint of the application on the port named ",(0,r.kt)("inlineCode",{parentName:"p"},"web"),"."),(0,r.kt)("p",null,"To instruct Prometheus to scrape from ",(0,r.kt)("inlineCode",{parentName:"p"},"/actuator/metrics")," on port ",(0,r.kt)("inlineCode",{parentName:"p"},"9099")," instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n # Add the monitoring configuration backed by Prometheus\n accessories: {\n "monitoring": m.Prometheus {\n path: "/actuator/metrics"\n port: "9099"\n }\n }\n}\n')),(0,r.kt)("p",null,"Note that numbered ports only work when your Prometheus is not running as an operator. "),(0,r.kt)("p",null,"Neither ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," are required fields if Prometheus runs as an operator. If omitted, ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," defaults to the container port or service port, depending on which resource is being monitored. If Prometheus does not run as an operator, both fields are required."),(0,r.kt)("p",null,"Scraping scheme, interval and timeout are considered platform-managed configurations and are therefore managed as part of the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"workspace configurations"),"."),(0,r.kt)("p",null,"More details about how the Prometheus integration works can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md"},"design documentation"),"."),(0,r.kt)("h2",{id:"default-values"},"Default values"),(0,r.kt)("p",null,"If no workspace configurations are found, the default values provided by the KusionStack team are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Scraping interval defaults to 30 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping timeout defaults to 15 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping scheme defaults to http"),(0,r.kt)("li",{parentName:"ul"},"Defaults to NOT running as an operator")),(0,r.kt)("p",null,"If any of the default values does not meet your need, you can change them by ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"setting up the workspace configuration"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9f069a65.932ffb24.js b/assets/js/9f069a65.932ffb24.js deleted file mode 100644 index 98a4775196d..00000000000 --- a/assets/js/9f069a65.932ffb24.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[963],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=o.createContext({}),u=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,h=m["".concat(p,".").concat(d)]||m[d]||c[d]||a;return n?o.createElement(h,i(i({ref:t},l),{},{components:n})):o.createElement(h,i({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const a={},i="Application Monitoring",s={unversionedId:"kusion/configuration-walkthrough/monitoring",id:"kusion/configuration-walkthrough/monitoring",title:"Application Monitoring",description:"You could also specify the collection of monitoring requirements for the application. That can be achieved via a monitoring module (or bring-your-own-module) in the accessories field in AppConfiguration to achieve that.",source:"@site/docs/kusion/4-configuration-walkthrough/8-monitoring.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/monitoring",permalink:"/docs/next/kusion/configuration-walkthrough/monitoring",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/8-monitoring.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{},sidebar:"kusion",previous:{title:"Secrets",permalink:"/docs/next/kusion/configuration-walkthrough/secret"},next:{title:"Operational Rules",permalink:"/docs/next/kusion/configuration-walkthrough/operational-rules"}},p={},u=[{value:"Import",id:"import",level:2},{value:"Workspace configurations",id:"workspace-configurations",level:2},{value:"Managing Scraping Configuration",id:"managing-scraping-configuration",level:2},{value:"Default values",id:"default-values",level:2}],l={toc:u};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-monitoring"},"Application Monitoring"),(0,r.kt)("p",null,"You could also specify the collection of monitoring requirements for the application. That can be achieved via a ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," module (or bring-your-own-module) in the ",(0,r.kt)("inlineCode",{parentName:"p"},"accessories")," field in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to achieve that."),(0,r.kt)("p",null,"As of version 0.11.0, Kusion supports integration with Prometheus by managing scraping behaviors in the configuration file."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For the monitoring configuration to work (more specifically, consumed by Prometheus), this requires the target cluster to have installed Prometheus correctly, either as a Kubernetes operator or a server/agent."),(0,r.kt)("p",{parentName:"admonition"},"More about how to set up Prometheus can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus"},"Prometheus User Guide for Kusion"))),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"kam")," package and the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," Kusion Module. For more details on KCL package and module import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport monitoring as m\n")),(0,r.kt)("h2",{id:"workspace-configurations"},"Workspace configurations"),(0,r.kt)("p",null,"In addition to the KCL configuration file, there are also workspace-level configurations that should be set first. In an ideal scenario, this step is done by the platform engineers. "),(0,r.kt)("p",null,"In the event that they do not exist for you or your organization, e.g. if you are an individual developer, you can either do it yourself or use the ",(0,r.kt)("a",{parentName:"p",href:"#default-values"},"default values")," provided by the KusionStack team. The steps to do this yourself can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"Prometheus User Guide for Kusion"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For more details on how workspaces work, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/kusion/concepts/workspace"},"workspace concept"))),(0,r.kt)("p",null,"By separating configurations that the developers are interested in and those that platform owners are interested in, we can reduce the cognitive complexity of the application configuration and achieve separation of concern."),(0,r.kt)("p",null,"You can append the following YAML file to your own workspace configurations and update the corresponding workspace with command ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace update"),". "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n kusionstack/monitoring@v0.1.0:\n default:\n interval: 30s\n monitorType: Pod\n operatorMode: true\n scheme: http\n timeout: 15s\n")),(0,r.kt)("h2",{id:"managing-scraping-configuration"},"Managing Scraping Configuration"),(0,r.kt)("p",null,"To manage scrape configuration for the application:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n # Add the monitoring configuration backed by Prometheus\n accessories: {\n "monitoring": m.Prometheus {\n path: "/metrics"\n port: "web"\n }\n }\n}\n')),(0,r.kt)("p",null,"The example above will instruct the Prometheus job to scrape metrics from the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint of the application on the port named ",(0,r.kt)("inlineCode",{parentName:"p"},"web"),"."),(0,r.kt)("p",null,"To instruct Prometheus to scrape from ",(0,r.kt)("inlineCode",{parentName:"p"},"/actuator/metrics")," on port ",(0,r.kt)("inlineCode",{parentName:"p"},"9099")," instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n # Add the monitoring configuration backed by Prometheus\n accessories: {\n "monitoring": m.Prometheus {\n path: "/actuator/metrics"\n port: "9099"\n }\n }\n}\n')),(0,r.kt)("p",null,"Note that numbered ports only work when your Prometheus is not running as an operator. "),(0,r.kt)("p",null,"Neither ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," are required fields if Prometheus runs as an operator. If omitted, ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," defaults to the container port or service port, depending on which resource is being monitored. If Prometheus does not run as an operator, both fields are required."),(0,r.kt)("p",null,"Scraping scheme, interval and timeout are considered platform-managed configurations and are therefore managed as part of the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"workspace configurations"),"."),(0,r.kt)("p",null,"More details about how the Prometheus integration works can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md"},"design documentation"),"."),(0,r.kt)("h2",{id:"default-values"},"Default values"),(0,r.kt)("p",null,"If no workspace configurations are found, the default values provided by the KusionStack team are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Scraping interval defaults to 30 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping timeout defaults to 15 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping scheme defaults to http"),(0,r.kt)("li",{parentName:"ul"},"Defaults to NOT running as an operator")),(0,r.kt)("p",null,"If any of the default values does not meet your need, you can change them by ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"setting up the workspace configuration"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9fc66687.57aa4047.js b/assets/js/9fc66687.57aa4047.js new file mode 100644 index 00000000000..a393a5b1c73 --- /dev/null +++ b/assets/js/9fc66687.57aa4047.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7988],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),c=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,h=m["".concat(i,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(h,l(l({ref:t},p),{},{components:n})):r.createElement(h,l({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},l="Concepts",s={unversionedId:"ctrlmesh/concepts/concepts",id:"version-v0.9/ctrlmesh/concepts/concepts",title:"Concepts",description:"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.",source:"@site/versioned_docs/version-v0.9/ctrlmesh/concepts/concepts.md",sourceDirName:"ctrlmesh/concepts",slug:"/ctrlmesh/concepts/",permalink:"/docs/v0.9/ctrlmesh/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/concepts/concepts.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",previous:{title:"Controller Mesh",permalink:"/docs/v0.9/ctrlmesh/intro/"},next:{title:"Installation",permalink:"/docs/v0.9/ctrlmesh/started/install"}},i={},c=[],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"concepts"},"Concepts"),(0,o.kt)("p",null,"Generally, a ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy")," container will be injected into each operator Pod that has configured in ShardingConfigs.\nThis proxy container will intercept and handle the connection by between API/Oth Server and controllers/webhooks in the Pod."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"550",src:n(54038).Z})),(0,o.kt)("p",null,"ApiServer proxy method:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"iptables nat"),": "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"fake kubeconfig"),": ")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-manager")," dispatches rules to the proxies, so that they can route requests according to the rules."),(0,o.kt)("p",null,"A core CRD of ControllerMesh is ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),". It contains all rules for user's controller:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-demo\n namespace: operator-demo\nspec:\n controller:\n leaderElectionName: operator-leader\n webhook:\n certDir: /tmp/webhook-certs\n port: 9443\n limits:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - pods\n - services\n selector:\n matchExpressions:\n - key: ctrlmesh.kusionstack.io/namespace\n operator: In\n values:\n - ns-a\n - ns-b\n matchLabels:\n app: foo\n selector:\n matchExpressions:\n - key: statefulset.kubernetes.io/pod-name\n operator: In\n values:\n - operator-demo-0\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"selector: for all pods under a shard. It can be a subset of pods under a StatefulSet."),(0,o.kt)("li",{parentName:"ul"},"controller: configuration for controller, including leader election name"),(0,o.kt)("li",{parentName:"ul"},"webhook: configuration for webhook, including certDir and port of this webhook"),(0,o.kt)("li",{parentName:"ul"},"limits: shard isolation is achieved through a set of ",(0,o.kt)("inlineCode",{parentName:"li"},"ObjectSelector"),".")),(0,o.kt)("p",null,"When ",(0,o.kt)("inlineCode",{parentName:"p"},"manager")," is first launched, shard labels will be added to all configured resources."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/sharding-hash"),": the hash value calculated based on the namespace ranges from 0 to 31."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/namespace"),": the namespace referring to this resource."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/control"),": under ctrlmesh-manager control.")),(0,o.kt)("p",null,"In this repo, we only support ",(0,o.kt)("inlineCode",{parentName:"p"},"ObjectSelector")," type of flow control,\nwhich means the ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy "),"will proxy http/s requests to the ApiServer,\nand inject a ",(0,o.kt)("inlineCode",{parentName:"p"},"LabelSelector")," into the request param for the requested resource type."),(0,o.kt)("p",null,"Router:"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"600",src:n(26652).Z})))}u.isMDXComponent=!0},54038:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/fake-configmap-532e288cad1389abce66dcd4b67cd817.png"},26652:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/mesh-proxy-4103e0c9a907b1df91258341cd841c52.png"}}]); \ No newline at end of file diff --git a/assets/js/9fc66687.5b4b8dbc.js b/assets/js/9fc66687.5b4b8dbc.js deleted file mode 100644 index 4b9bdba027a..00000000000 --- a/assets/js/9fc66687.5b4b8dbc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7988],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),c=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,h=m["".concat(i,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(h,l(l({ref:t},p),{},{components:n})):r.createElement(h,l({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},l="Concepts",s={unversionedId:"ctrlmesh/concepts/concepts",id:"version-v0.9/ctrlmesh/concepts/concepts",title:"Concepts",description:"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.",source:"@site/versioned_docs/version-v0.9/ctrlmesh/concepts/concepts.md",sourceDirName:"ctrlmesh/concepts",slug:"/ctrlmesh/concepts/",permalink:"/docs/v0.9/ctrlmesh/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/concepts/concepts.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",previous:{title:"Controller Mesh",permalink:"/docs/v0.9/ctrlmesh/intro/"},next:{title:"Installation",permalink:"/docs/v0.9/ctrlmesh/started/install"}},i={},c=[],p={toc:c};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"concepts"},"Concepts"),(0,o.kt)("p",null,"Generally, a ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy")," container will be injected into each operator Pod that has configured in ShardingConfigs.\nThis proxy container will intercept and handle the connection by between API/Oth Server and controllers/webhooks in the Pod."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"550",src:n(54038).Z})),(0,o.kt)("p",null,"ApiServer proxy method:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"iptables nat"),": "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"fake kubeconfig"),": ")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-manager")," dispatches rules to the proxies, so that they can route requests according to the rules."),(0,o.kt)("p",null,"A core CRD of ControllerMesh is ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),". It contains all rules for user's controller:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-demo\n namespace: operator-demo\nspec:\n controller:\n leaderElectionName: operator-leader\n webhook:\n certDir: /tmp/webhook-certs\n port: 9443\n limits:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - pods\n - services\n selector:\n matchExpressions:\n - key: ctrlmesh.kusionstack.io/namespace\n operator: In\n values:\n - ns-a\n - ns-b\n matchLabels:\n app: foo\n selector:\n matchExpressions:\n - key: statefulset.kubernetes.io/pod-name\n operator: In\n values:\n - operator-demo-0\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"selector: for all pods under a shard. It can be a subset of pods under a StatefulSet."),(0,o.kt)("li",{parentName:"ul"},"controller: configuration for controller, including leader election name"),(0,o.kt)("li",{parentName:"ul"},"webhook: configuration for webhook, including certDir and port of this webhook"),(0,o.kt)("li",{parentName:"ul"},"limits: shard isolation is achieved through a set of ",(0,o.kt)("inlineCode",{parentName:"li"},"ObjectSelector"),".")),(0,o.kt)("p",null,"When ",(0,o.kt)("inlineCode",{parentName:"p"},"manager")," is first launched, shard labels will be added to all configured resources."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/sharding-hash"),": the hash value calculated based on the namespace ranges from 0 to 31."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/namespace"),": the namespace referring to this resource."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/control"),": under ctrlmesh-manager control.")),(0,o.kt)("p",null,"In this repo, we only support ",(0,o.kt)("inlineCode",{parentName:"p"},"ObjectSelector")," type of flow control,\nwhich means the ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy "),"will proxy http/s requests to the ApiServer,\nand inject a ",(0,o.kt)("inlineCode",{parentName:"p"},"LabelSelector")," into the request param for the requested resource type."),(0,o.kt)("p",null,"Router:"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"600",src:n(26652).Z})))}u.isMDXComponent=!0},54038:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/fake-configmap-532e288cad1389abce66dcd4b67cd817.png"},26652:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/mesh-proxy-4103e0c9a907b1df91258341cd841c52.png"}}]); \ No newline at end of file diff --git a/assets/js/a08f9b67.0653218e.js b/assets/js/a08f9b67.0653218e.js deleted file mode 100644 index 4bdcca4c5bc..00000000000 --- a/assets/js/a08f9b67.0653218e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6107],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),k=p(n),d=o,m=k["".concat(c,".").concat(d)]||k[d]||u[d]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=k;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace",i={unversionedId:"kusion/reference/commands/kusion-workspace",id:"kusion/reference/commands/kusion-workspace",title:"kusion workspace",description:"Workspace is a logical concept representing a target that stacks will be deployed to",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace",permalink:"/docs/next/kusion/reference/commands/kusion-workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace update",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-update"},next:{title:"Kusion Modules",permalink:"/docs/next/kusion/reference/modules/"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace"},"kusion workspace"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to."),(0,o.kt)("p",null," Workspace is managed by platform engineers, which contains a set of configurations that application developers do not want or should not concern, and is reused by multiple stacks belonging to different projects."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for workspace\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-create"},"kusion workspace create"),"\t - Create a new workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-delete"},"kusion workspace delete"),"\t - Delete a workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-list"},"kusion workspace list"),"\t - List all workspace names"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-show"},"kusion workspace show"),"\t - Show a workspace configuration"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-update"},"kusion workspace update"),"\t - Update a workspace configuration")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a08f9b67.4e677d30.js b/assets/js/a08f9b67.4e677d30.js new file mode 100644 index 00000000000..6fcccf68f1e --- /dev/null +++ b/assets/js/a08f9b67.4e677d30.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6107],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},k=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),k=p(n),d=o,m=k["".concat(c,".").concat(d)]||k[d]||u[d]||a;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=k;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace",i={unversionedId:"kusion/reference/commands/kusion-workspace",id:"kusion/reference/commands/kusion-workspace",title:"kusion workspace",description:"Workspace is a logical concept representing a target that stacks will be deployed to",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace",permalink:"/docs/next/kusion/reference/commands/kusion-workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace update",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-update"},next:{title:"Kusion Modules",permalink:"/docs/next/kusion/reference/modules/"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace"},"kusion workspace"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Workspace is a logical concept representing a target that stacks will be deployed to."),(0,o.kt)("p",null," Workspace is managed by platform engineers, which contains a set of configurations that application developers do not want or should not concern, and is reused by multiple stacks belonging to different projects."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for workspace\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-create"},"kusion workspace create"),"\t - Create a new workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-delete"},"kusion workspace delete"),"\t - Delete a workspace"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-list"},"kusion workspace list"),"\t - List all workspace names"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-show"},"kusion workspace show"),"\t - Show a workspace configuration"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace-update"},"kusion workspace update"),"\t - Update a workspace configuration")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a121ee0b.4f7f6d44.js b/assets/js/a121ee0b.8eda715d.js similarity index 67% rename from assets/js/a121ee0b.4f7f6d44.js rename to assets/js/a121ee0b.8eda715d.js index a01788be478..e8c755eeb1d 100644 --- a/assets/js/a121ee0b.4f7f6d44.js +++ b/assets/js/a121ee0b.8eda715d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2180],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(n),d=a,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||o;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const o={id:"configuration",sidebar_label:"Stack Configuration"},i="Stack Configuration",c={unversionedId:"kusion/concepts/stack/configuration",id:"kusion/concepts/stack/configuration",title:"Stack Configuration",description:"Users can add config items of the stack in stack.yaml, such as the stack name, etc.",source:"@site/docs/kusion/3-concepts/2-stack/2-configuration.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/configuration",permalink:"/docs/next/kusion/concepts/stack/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/2-stack/2-configuration.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Stack Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/next/kusion/concepts/stack/overview"},next:{title:"Kusion Module",permalink:"/docs/next/kusion/concepts/kusion-module"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"stack-configuration"},"Stack Configuration"),(0,a.kt)("p",null,"Users can add config items of the stack in ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml"),", such as the stack name, etc."),(0,a.kt)("p",null,"Here is an example of ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"# The stack basic info\nname: dev\n")),(0,a.kt)("p",null,"The config items in ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml")," are explained below."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"name"),": The name of the stack, should be same as the workspace name, such as ",(0,a.kt)("inlineCode",{parentName:"li"},"dev"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"pre")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"prod"),".")))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2180],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(n),d=a,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||o;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const o={id:"configuration",sidebar_label:"Stack Configuration"},i="Stack Configuration",c={unversionedId:"kusion/concepts/stack/configuration",id:"kusion/concepts/stack/configuration",title:"Stack Configuration",description:"Users can add config items of the stack in stack.yaml, such as the stack name, etc.",source:"@site/docs/kusion/3-concepts/2-stack/2-configuration.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/configuration",permalink:"/docs/next/kusion/concepts/stack/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/2-stack/2-configuration.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Stack Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/next/kusion/concepts/stack/overview"},next:{title:"Kusion Module",permalink:"/docs/next/kusion/concepts/kusion-module"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"stack-configuration"},"Stack Configuration"),(0,a.kt)("p",null,"Users can add config items of the stack in ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml"),", such as the stack name, etc."),(0,a.kt)("p",null,"Here is an example of ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"# The stack basic info\nname: dev\n")),(0,a.kt)("p",null,"The config items in ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml")," are explained below."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"name"),": The name of the stack, should be same as the workspace name, such as ",(0,a.kt)("inlineCode",{parentName:"li"},"dev"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"pre")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"prod"),".")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a27ca0d9.32308675.js b/assets/js/a27ca0d9.32308675.js new file mode 100644 index 00000000000..3be9f6fb904 --- /dev/null +++ b/assets/js/a27ca0d9.32308675.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7117],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>h});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=l(o),h=r,d=c["".concat(p,".").concat(h)]||c[h]||m[h]||i;return o?n.createElement(d,a(a({ref:t},u),{},{components:o})):n.createElement(d,a({ref:t},u))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=c;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=o(87462),r=(o(67294),o(3905));const i={},a="Configure Monitoring Behavior With Prometheus",s={unversionedId:"kusion/user-guides/observability/prometheus",id:"version-v0.10/kusion/user-guides/observability/prometheus",title:"Configure Monitoring Behavior With Prometheus",description:"This document provides the step-by-step instruction to set up monitoring for your application.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/3-observability/1-prometheus.md",sourceDirName:"kusion/5-user-guides/3-observability",slug:"/kusion/user-guides/observability/prometheus",permalink:"/docs/kusion/user-guides/observability/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/3-observability/1-prometheus.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Schedule a Job",permalink:"/docs/kusion/user-guides/working-with-k8s/job"},next:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions"}},p={},l=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Setting up your own Prometheus",id:"setting-up-your-own-prometheus",level:2},{value:"Installing Prometheus operator3.",id:"installing-prometheus-operator3",level:3},{value:"Make sure RBAC is properly set up",id:"make-sure-rbac-is-properly-set-up",level:3},{value:"Configure Prometheus instance via the operator",id:"configure-prometheus-instance-via-the-operator",level:3},{value:"Exposing the Prometheus portal (optional)",id:"exposing-the-prometheus-portal-optional",level:3},{value:"Setting up workspace configs",id:"setting-up-workspace-configs",level:2},{value:"Operator mode",id:"operator-mode",level:3},{value:"Monitor types",id:"monitor-types",level:3},{value:"Overriding with projectSelector",id:"overriding-with-projectselector",level:3},{value:"Updating the workspace config",id:"updating-the-workspace-config",level:2},{value:"Using kusion to deploy your application with monitoring requirements",id:"using-kusion-to-deploy-your-application-with-monitoring-requirements",level:2},{value:"References",id:"references",level:2}],u={toc:l};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-monitoring-behavior-with-prometheus"},"Configure Monitoring Behavior With Prometheus"),(0,r.kt)("p",null,"This document provides the step-by-step instruction to set up monitoring for your application. "),(0,r.kt)("p",null,"As of today, Kusion supports the configuration of Prometheus scraping behaviors for the target application. In the future, we will add more cloud-provider-native solutions, such as AWS CloudWatch, Azure Monitor, etc."),(0,r.kt)("p",null,"The user guide below is composed of the following components:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Namespace"),(0,r.kt)("li",{parentName:"ul"},"Deployment"),(0,r.kt)("li",{parentName:"ul"},"Service"),(0,r.kt)("li",{parentName:"ul"},"ServiceMonitor")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes and Prometheus.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"Prometheus Introduction")))),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"setting-up-your-own-prometheus"},"Setting up your own Prometheus"),(0,r.kt)("p",null,"There a quite a few ways to set up Prometheus in your cluster:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus operator"),(0,r.kt)("li",{parentName:"ol"},"Installing a standalone Prometheus server"),(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus agent and connect to a remote Prometheus server")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-401092041"},"The advice from the Prometheus team")," is to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"PodMonitor")," CRs via the Prometheus operator to manage scrape configs going forward",(0,r.kt)("sup",null,"[2]"),"."),(0,r.kt)("p",null,"In either case, you only have to do this setup once per cluster. This doc will use a minikube cluster and Prometheus operator as an example."),(0,r.kt)("h3",{id:"installing-prometheus-operator3"},"Installing Prometheus operator",(0,r.kt)("sup",null,"[3]"),"."),(0,r.kt)("p",null,"To get the example in this user guide working, all you need is a running Prometheus operator. You can have that installed by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)\ncurl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f -\n")),(0,r.kt)("p",null,"This will install all the necessary CRDs and the Prometheus operator itself in the default namespace. Wait a few minutes, you can confirm the operator is up by running: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl wait --for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n default\n")),(0,r.kt)("h3",{id:"make-sure-rbac-is-properly-set-up"},"Make sure RBAC is properly set up"),(0,r.kt)("p",null,"If you have RBAC enabled on the cluster, the following must be created for Prometheus to work properly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: prometheus\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: prometheus\nrules:\n- apiGroups: [""]\n resources:\n - nodes\n - nodes/metrics\n - services\n - endpoints\n - pods\n verbs: ["get", "list", "watch"]\n- apiGroups: [""]\n resources:\n - configmaps\n verbs: ["get"]\n- apiGroups:\n - networking.k8s.io\n resources:\n - ingresses\n verbs: ["get", "list", "watch"]\n- nonResourceURLs: ["/metrics"]\n verbs: ["get"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n name: prometheus\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus\nsubjects:\n- kind: ServiceAccount\n name: prometheus\n namespace: default\n')),(0,r.kt)("h3",{id:"configure-prometheus-instance-via-the-operator"},"Configure Prometheus instance via the operator"),(0,r.kt)("p",null,"Once all of the above is set up, you can then configure the Prometheus instance via the operator:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n name: prometheus\nspec:\n serviceAccountName: prometheus\n serviceMonitorNamespaceSelector: {}\n serviceMonitorSelector: {}\n podMonitorNamespaceSelector: {}\n podMonitorSelector: {}\n resources:\n requests:\n memory: 400Mi\n")),(0,r.kt)("p",null,"This Prometheus instance above will be cluster-wide, picking up ALL the service monitors and pod monitors across ALL the namespaces.\nYou can adjust the requests and limits accordingly if you have a larger cluster."),(0,r.kt)("h3",{id:"exposing-the-prometheus-portal-optional"},"Exposing the Prometheus portal (optional)"),(0,r.kt)("p",null,"Once you have the managed Prometheus instance created via the Prometheus CR above, you should be able to see a service created called ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus-operated"),":"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-operated",src:o(91512).Z,width:"631",height:"52"})),(0,r.kt)("p",null,"If you are also running on minikube, you can expose it onto your localhost via kubectl:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/prometheus-operated 9099:9090\n")),(0,r.kt)("p",null,"You should then be able to see the Prometheus portal via ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost:9099")," in your browser:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-portal",src:o(35443).Z,width:"2878",height:"1096"})),(0,r.kt)("p",null,"If you are running a non-local cluster, you can try to expose it via another way, through an ingress controller for example."),(0,r.kt)("h2",{id:"setting-up-workspace-configs"},"Setting up workspace configs"),(0,r.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,r.kt)("p",null,"In the case of setting up Prometheus, there are a few things to set up on the workspace level:"),(0,r.kt)("h3",{id:"operator-mode"},"Operator mode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," flag indicates to Kusion whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,r.kt)("p",null,"To see more about different ways to run Prometheus in the Kubernetes cluster, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md#prometheus-installation"},"design documentation"),"."),(0,r.kt)("p",null,"Most cloud vendors provide an out-of-the-box monitoring solutions for workloads running in a managed-Kubernetes cluster (EKS, AKS, etc), such as AWS CloudWatch, Azure Monitor, etc. These solutions mostly involve installing an agent (CloudWatch Agent, OMS Agent, etc) in the cluster and collecting the metrics to a centralized monitoring server. In those cases, you don't need to set ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". It only needs to be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when you have an installation of the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator")," running inside the Kubernetes cluster."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For differences between ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/kube-prometheus"},"kube-prometheus")," and the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack"},"community kube-prometheus-stack helm chart"),", the details are documented ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator#prometheus-operator-vs-kube-prometheus-vs-community-helm-chart"},"here"),".")),(0,r.kt)("h3",{id:"monitor-types"},"Monitor types"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitorType")," flag indicates the kind of monitor Kusion will create. It only applies when ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". As of version 0.10.0, Kusion provides options to scrape metrics from either the application pods or its corresponding Kubernetes services. This determines the different kinds of resources Kusion manages when Prometheus runs as an operator in the target cluster."),(0,r.kt)("p",null,"A sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with Prometheus settings:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n ...\n monitoring:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"To instruct Prometheus to scrape from pod targets instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n ...\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus")," section is missing from the ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", Kusion defaults ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to false."),(0,r.kt)("h3",{id:"overriding-with-projectselector"},"Overriding with projectSelector"),(0,r.kt)("p",null,"Workspace configurations contain a set of default setting group for all projects in the workspace, with means to override them by Projects using a ",(0,r.kt)("inlineCode",{parentName:"p"},"projectSelector")," keyword."),(0,r.kt)("p",null,"Projects with the name matching those in projectSelector will use the values defined in that override group instead of the default. If a key is not present in the override group, the default value will be used."),(0,r.kt)("p",null,"Take a look at the sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n ...\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n projectSelector:\n - foobar\n high_frequency:\n monitorType: Service\n projectSelector:\n - helloworld\n...\n")),(0,r.kt)("p",null,"In the example above, a project with the name ",(0,r.kt)("inlineCode",{parentName:"p"},"helloworld")," will have the monitoring settings where ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"False"),", a 2 minute scraping interval, 15 seconds timeout (coming from default) and http scheme (coming from default)."),(0,r.kt)("p",null,"You cannot have the same project appear in two projectSelectors."),(0,r.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,r.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/monitoring/prometheus"},"workspace reference"),"."),(0,r.kt)("h2",{id:"updating-the-workspace-config"},"Updating the workspace config"),(0,r.kt)("p",null,"Assuming you now have a ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," that looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n monitoring:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"Update the workspace configuration by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"Verify the workspace config is properly updated by running the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace show dev\n")),(0,r.kt)("h2",{id:"using-kusion-to-deploy-your-application-with-monitoring-requirements"},"Using kusion to deploy your application with monitoring requirements"),(0,r.kt)("p",null,"At this point we are set up for good! Any new applications you deploy via kusion will now automatically have the monitoring-related resources created, should you declare you want it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model."),(0,r.kt)("p",null,"The monitoring in an AppConfiguration is declared in the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field. See the example below for a full, deployable AppConfiguration."),(0,r.kt)("p",null,"Please note we are using a new image ",(0,r.kt)("inlineCode",{parentName:"p"},"quay.io/brancz/prometheus-example-app")," since the app itself need to expose metrics for Prometheus to scrape:"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "monitoring-sample-app": c.Container {\n image: "quay.io/brancz/prometheus-example-app:v0.3.0"\n }\n }\n ports: [\n n.Port {\n port: 8080\n }\n ]\n }\n monitoring: m.Prometheus{\n path: "/metrics"\n }\n}\n')),(0,r.kt)("p",null,"The KCL file above represents an application with a service type workload, exposing the port 8080, and would like Prometheus to scrape the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint every 2 minutes."),(0,r.kt)("p",null,"Running ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply")," would show that kusion will create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," and a ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor"),":\n",(0,r.kt)("img",{alt:"kusion-apply-with-monitor",src:o(448).Z,width:"705",height:"224"})),(0,r.kt)("p",null,"Continue applying all resources:\n",(0,r.kt)("img",{alt:"kusion-apply-success",src:o(56816).Z,width:"1047",height:"564"})),(0,r.kt)("p",null,"If we want to, we can verify the service monitor has been created successfully:\n",(0,r.kt)("img",{alt:"service-monitor",src:o(58232).Z,width:"693",height:"463"})),(0,r.kt)("p",null,"In a few seconds, you should be able to see in the Prometheus portal that the service we just deployed has now been discovered and monitored by Prometheus:\n",(0,r.kt)("img",{alt:"prometheus-targets",src:o(81187).Z,width:"2880",height:"1636"})),(0,r.kt)("p",null,"You can run a few simply queries for the data that Prometheus scraped from your application:\n",(0,r.kt)("img",{alt:"prometheus-simple-query",src:o(87695).Z,width:"2880",height:"1634"})),(0,r.kt)("p",null,"For more info about PromQL, you can find them ",(0,r.kt)("a",{parentName:"p",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"here"),(0,r.kt)("sup",null,"[4]"),"."),(0,r.kt)("h2",{id:"references"},"References"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Prometheus: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"https://prometheus.io/docs/introduction/overview/")),(0,r.kt)("li",{parentName:"ol"},"Prometheus team advise: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500"},"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500")),(0,r.kt)("li",{parentName:"ol"},"Prometheus operator getting started doc: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md"},"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md")),(0,r.kt)("li",{parentName:"ol"},"PromQL basics: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"https://prometheus.io/docs/prometheus/latest/querying/basics/"))))}m.isMDXComponent=!0},56816:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-success-52d04db670fd184959c3ea5c9e54f69d.png"},448:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-with-monitor-d27cd1443e1a324d514983d52c055b15.png"},91512:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-operated-4cf8308703e4ec9d06a5078bbceb8d5d.png"},35443:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-portal-b60d8654c309e675fc04f1e74c5c127a.png"},87695:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-simple-query-60205589e762105ebc850e70d8ea7b56.png"},81187:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-targets-05964bad58af16f2e02c57cafa8565e7.png"},58232:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/service-monitor-2374625bfd1180a978a2be50ad4648ce.png"}}]); \ No newline at end of file diff --git a/assets/js/a27ca0d9.d5833bb9.js b/assets/js/a27ca0d9.d5833bb9.js deleted file mode 100644 index d39acb455cf..00000000000 --- a/assets/js/a27ca0d9.d5833bb9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7117],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>h});var n=o(67294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=l(o),h=r,d=c["".concat(p,".").concat(h)]||c[h]||m[h]||i;return o?n.createElement(d,a(a({ref:t},u),{},{components:o})):n.createElement(d,a({ref:t},u))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=c;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=o(87462),r=(o(67294),o(3905));const i={},a="Configure Monitoring Behavior With Prometheus",s={unversionedId:"kusion/user-guides/observability/prometheus",id:"version-v0.10/kusion/user-guides/observability/prometheus",title:"Configure Monitoring Behavior With Prometheus",description:"This document provides the step-by-step instruction to set up monitoring for your application.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/3-observability/1-prometheus.md",sourceDirName:"kusion/5-user-guides/3-observability",slug:"/kusion/user-guides/observability/prometheus",permalink:"/docs/kusion/user-guides/observability/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/3-observability/1-prometheus.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Schedule a Job",permalink:"/docs/kusion/user-guides/working-with-k8s/job"},next:{title:"Deploy Application Securely and Efficiently via GitHub Actions",permalink:"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions"}},p={},l=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Setting up your own Prometheus",id:"setting-up-your-own-prometheus",level:2},{value:"Installing Prometheus operator3.",id:"installing-prometheus-operator3",level:3},{value:"Make sure RBAC is properly set up",id:"make-sure-rbac-is-properly-set-up",level:3},{value:"Configure Prometheus instance via the operator",id:"configure-prometheus-instance-via-the-operator",level:3},{value:"Exposing the Prometheus portal (optional)",id:"exposing-the-prometheus-portal-optional",level:3},{value:"Setting up workspace configs",id:"setting-up-workspace-configs",level:2},{value:"Operator mode",id:"operator-mode",level:3},{value:"Monitor types",id:"monitor-types",level:3},{value:"Overriding with projectSelector",id:"overriding-with-projectselector",level:3},{value:"Updating the workspace config",id:"updating-the-workspace-config",level:2},{value:"Using kusion to deploy your application with monitoring requirements",id:"using-kusion-to-deploy-your-application-with-monitoring-requirements",level:2},{value:"References",id:"references",level:2}],u={toc:l};function m(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-monitoring-behavior-with-prometheus"},"Configure Monitoring Behavior With Prometheus"),(0,r.kt)("p",null,"This document provides the step-by-step instruction to set up monitoring for your application. "),(0,r.kt)("p",null,"As of today, Kusion supports the configuration of Prometheus scraping behaviors for the target application. In the future, we will add more cloud-provider-native solutions, such as AWS CloudWatch, Azure Monitor, etc."),(0,r.kt)("p",null,"The user guide below is composed of the following components:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Namespace"),(0,r.kt)("li",{parentName:"ul"},"Deployment"),(0,r.kt)("li",{parentName:"ul"},"Service"),(0,r.kt)("li",{parentName:"ul"},"ServiceMonitor")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This guide requires you to have a basic understanding of Kubernetes and Prometheus.\nIf you are not familiar with the relevant concepts, please refer to the links below:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tutorials/kubernetes-basics/"},"Learn Kubernetes Basics")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"Prometheus Introduction")))),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"../working-with-k8s/deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,r.kt)("h2",{id:"setting-up-your-own-prometheus"},"Setting up your own Prometheus"),(0,r.kt)("p",null,"There a quite a few ways to set up Prometheus in your cluster:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus operator"),(0,r.kt)("li",{parentName:"ol"},"Installing a standalone Prometheus server"),(0,r.kt)("li",{parentName:"ol"},"Installing a Prometheus agent and connect to a remote Prometheus server")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-401092041"},"The advice from the Prometheus team")," is to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"PodMonitor")," CRs via the Prometheus operator to manage scrape configs going forward",(0,r.kt)("sup",null,"[2]"),"."),(0,r.kt)("p",null,"In either case, you only have to do this setup once per cluster. This doc will use a minikube cluster and Prometheus operator as an example."),(0,r.kt)("h3",{id:"installing-prometheus-operator3"},"Installing Prometheus operator",(0,r.kt)("sup",null,"[3]"),"."),(0,r.kt)("p",null,"To get the example in this user guide working, all you need is a running Prometheus operator. You can have that installed by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)\ncurl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f -\n")),(0,r.kt)("p",null,"This will install all the necessary CRDs and the Prometheus operator itself in the default namespace. Wait a few minutes, you can confirm the operator is up by running: "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl wait --for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n default\n")),(0,r.kt)("h3",{id:"make-sure-rbac-is-properly-set-up"},"Make sure RBAC is properly set up"),(0,r.kt)("p",null,"If you have RBAC enabled on the cluster, the following must be created for Prometheus to work properly:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: prometheus\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: prometheus\nrules:\n- apiGroups: [""]\n resources:\n - nodes\n - nodes/metrics\n - services\n - endpoints\n - pods\n verbs: ["get", "list", "watch"]\n- apiGroups: [""]\n resources:\n - configmaps\n verbs: ["get"]\n- apiGroups:\n - networking.k8s.io\n resources:\n - ingresses\n verbs: ["get", "list", "watch"]\n- nonResourceURLs: ["/metrics"]\n verbs: ["get"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n name: prometheus\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus\nsubjects:\n- kind: ServiceAccount\n name: prometheus\n namespace: default\n')),(0,r.kt)("h3",{id:"configure-prometheus-instance-via-the-operator"},"Configure Prometheus instance via the operator"),(0,r.kt)("p",null,"Once all of the above is set up, you can then configure the Prometheus instance via the operator:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n name: prometheus\nspec:\n serviceAccountName: prometheus\n serviceMonitorNamespaceSelector: {}\n serviceMonitorSelector: {}\n podMonitorNamespaceSelector: {}\n podMonitorSelector: {}\n resources:\n requests:\n memory: 400Mi\n")),(0,r.kt)("p",null,"This Prometheus instance above will be cluster-wide, picking up ALL the service monitors and pod monitors across ALL the namespaces.\nYou can adjust the requests and limits accordingly if you have a larger cluster."),(0,r.kt)("h3",{id:"exposing-the-prometheus-portal-optional"},"Exposing the Prometheus portal (optional)"),(0,r.kt)("p",null,"Once you have the managed Prometheus instance created via the Prometheus CR above, you should be able to see a service created called ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus-operated"),":"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-operated",src:o(91512).Z,width:"631",height:"52"})),(0,r.kt)("p",null,"If you are also running on minikube, you can expose it onto your localhost via kubectl:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl port-forward svc/prometheus-operated 9099:9090\n")),(0,r.kt)("p",null,"You should then be able to see the Prometheus portal via ",(0,r.kt)("inlineCode",{parentName:"p"},"localhost:9099")," in your browser:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"prometheus-portal",src:o(35443).Z,width:"2878",height:"1096"})),(0,r.kt)("p",null,"If you are running a non-local cluster, you can try to expose it via another way, through an ingress controller for example."),(0,r.kt)("h2",{id:"setting-up-workspace-configs"},"Setting up workspace configs"),(0,r.kt)("p",null,"Since v0.10.0, we have introduced the concept of ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/workspace"},"workspaces"),", whose configurations represent the part of the application behaviors that platform teams are interested in standardizing, or the ones to eliminate from developer's mind to make their lives easier."),(0,r.kt)("p",null,"In the case of setting up Prometheus, there are a few things to set up on the workspace level:"),(0,r.kt)("h3",{id:"operator-mode"},"Operator mode"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," flag indicates to Kusion whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,r.kt)("p",null,"To see more about different ways to run Prometheus in the Kubernetes cluster, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md#prometheus-installation"},"design documentation"),"."),(0,r.kt)("p",null,"Most cloud vendors provide an out-of-the-box monitoring solutions for workloads running in a managed-Kubernetes cluster (EKS, AKS, etc), such as AWS CloudWatch, Azure Monitor, etc. These solutions mostly involve installing an agent (CloudWatch Agent, OMS Agent, etc) in the cluster and collecting the metrics to a centralized monitoring server. In those cases, you don't need to set ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". It only needs to be set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True")," when you have an installation of the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator")," running inside the Kubernetes cluster."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For differences between ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator"},"Prometheus operator"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/kube-prometheus"},"kube-prometheus")," and the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack"},"community kube-prometheus-stack helm chart"),", the details are documented ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/prometheus-operator/prometheus-operator#prometheus-operator-vs-kube-prometheus-vs-community-helm-chart"},"here"),".")),(0,r.kt)("h3",{id:"monitor-types"},"Monitor types"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitorType")," flag indicates the kind of monitor Kusion will create. It only applies when ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"True"),". As of version 0.10.0, Kusion provides options to scrape metrics from either the application pods or its corresponding Kubernetes services. This determines the different kinds of resources Kusion manages when Prometheus runs as an operator in the target cluster."),(0,r.kt)("p",null,"A sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," with Prometheus settings:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n ...\n monitoring:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"To instruct Prometheus to scrape from pod targets instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n ...\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"If the ",(0,r.kt)("inlineCode",{parentName:"p"},"prometheus")," section is missing from the ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),", Kusion defaults ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," to false."),(0,r.kt)("h3",{id:"overriding-with-projectselector"},"Overriding with projectSelector"),(0,r.kt)("p",null,"Workspace configurations contain a set of default setting group for all projects in the workspace, with means to override them by Projects using a ",(0,r.kt)("inlineCode",{parentName:"p"},"projectSelector")," keyword."),(0,r.kt)("p",null,"Projects with the name matching those in projectSelector will use the values defined in that override group instead of the default. If a key is not present in the override group, the default value will be used."),(0,r.kt)("p",null,"Take a look at the sample ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n ...\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n projectSelector:\n - foobar\n high_frequency:\n monitorType: Service\n projectSelector:\n - helloworld\n...\n")),(0,r.kt)("p",null,"In the example above, a project with the name ",(0,r.kt)("inlineCode",{parentName:"p"},"helloworld")," will have the monitoring settings where ",(0,r.kt)("inlineCode",{parentName:"p"},"operatorMode")," is set to ",(0,r.kt)("inlineCode",{parentName:"p"},"False"),", a 2 minute scraping interval, 15 seconds timeout (coming from default) and http scheme (coming from default)."),(0,r.kt)("p",null,"You cannot have the same project appear in two projectSelectors."),(0,r.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,r.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/monitoring/prometheus"},"workspace reference"),"."),(0,r.kt)("h2",{id:"updating-the-workspace-config"},"Updating the workspace config"),(0,r.kt)("p",null,"Assuming you now have a ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace.yaml")," that looks like the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"modules:\n monitoring:\n default:\n operatorMode: True\n monitorType: Service\n scheme: http\n interval: 30s\n timeout: 15s\n...\n")),(0,r.kt)("p",null,"Update the workspace configuration by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace update dev -f workspace.yaml\n")),(0,r.kt)("p",null,"Verify the workspace config is properly updated by running the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace show dev\n")),(0,r.kt)("h2",{id:"using-kusion-to-deploy-your-application-with-monitoring-requirements"},"Using kusion to deploy your application with monitoring requirements"),(0,r.kt)("p",null,"At this point we are set up for good! Any new applications you deploy via kusion will now automatically have the monitoring-related resources created, should you declare you want it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model."),(0,r.kt)("p",null,"The monitoring in an AppConfiguration is declared in the ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," field. See the example below for a full, deployable AppConfiguration."),(0,r.kt)("p",null,"Please note we are using a new image ",(0,r.kt)("inlineCode",{parentName:"p"},"quay.io/brancz/prometheus-example-app")," since the app itself need to expose metrics for Prometheus to scrape:"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.monitoring as m\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "monitoring-sample-app": c.Container {\n image: "quay.io/brancz/prometheus-example-app:v0.3.0"\n }\n }\n ports: [\n n.Port {\n port: 8080\n }\n ]\n }\n monitoring: m.Prometheus{\n path: "/metrics"\n }\n}\n')),(0,r.kt)("p",null,"The KCL file above represents an application with a service type workload, exposing the port 8080, and would like Prometheus to scrape the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint every 2 minutes."),(0,r.kt)("p",null,"Running ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion apply")," would show that kusion will create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Deployment"),", a ",(0,r.kt)("inlineCode",{parentName:"p"},"Service")," and a ",(0,r.kt)("inlineCode",{parentName:"p"},"ServiceMonitor"),":\n",(0,r.kt)("img",{alt:"kusion-apply-with-monitor",src:o(448).Z,width:"705",height:"224"})),(0,r.kt)("p",null,"Continue applying all resources:\n",(0,r.kt)("img",{alt:"kusion-apply-success",src:o(56816).Z,width:"1047",height:"564"})),(0,r.kt)("p",null,"If we want to, we can verify the service monitor has been created successfully:\n",(0,r.kt)("img",{alt:"service-monitor",src:o(58232).Z,width:"693",height:"463"})),(0,r.kt)("p",null,"In a few seconds, you should be able to see in the Prometheus portal that the service we just deployed has now been discovered and monitored by Prometheus:\n",(0,r.kt)("img",{alt:"prometheus-targets",src:o(81187).Z,width:"2880",height:"1636"})),(0,r.kt)("p",null,"You can run a few simply queries for the data that Prometheus scraped from your application:\n",(0,r.kt)("img",{alt:"prometheus-simple-query",src:o(87695).Z,width:"2880",height:"1634"})),(0,r.kt)("p",null,"For more info about PromQL, you can find them ",(0,r.kt)("a",{parentName:"p",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"here"),(0,r.kt)("sup",null,"[4]"),"."),(0,r.kt)("h2",{id:"references"},"References"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Prometheus: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/introduction/overview/"},"https://prometheus.io/docs/introduction/overview/")),(0,r.kt)("li",{parentName:"ol"},"Prometheus team advise: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500"},"https://github.com/prometheus-operator/prometheus-operator/issues/1547#issuecomment-446691500")),(0,r.kt)("li",{parentName:"ol"},"Prometheus operator getting started doc: ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md"},"https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md")),(0,r.kt)("li",{parentName:"ol"},"PromQL basics: ",(0,r.kt)("a",{parentName:"li",href:"https://prometheus.io/docs/prometheus/latest/querying/basics/"},"https://prometheus.io/docs/prometheus/latest/querying/basics/"))))}m.isMDXComponent=!0},56816:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-success-52d04db670fd184959c3ea5c9e54f69d.png"},448:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/kusion-apply-with-monitor-d27cd1443e1a324d514983d52c055b15.png"},91512:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-operated-4cf8308703e4ec9d06a5078bbceb8d5d.png"},35443:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-portal-b60d8654c309e675fc04f1e74c5c127a.png"},87695:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-simple-query-60205589e762105ebc850e70d8ea7b56.png"},81187:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/prometheus-targets-05964bad58af16f2e02c57cafa8565e7.png"},58232:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/service-monitor-2374625bfd1180a978a2be50ad4648ce.png"}}]); \ No newline at end of file diff --git a/assets/js/a28f322c.64c84735.js b/assets/js/a28f322c.64c84735.js new file mode 100644 index 00000000000..c8eacff78e1 --- /dev/null +++ b/assets/js/a28f322c.64c84735.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[905],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,i=new Array(s);i[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const s={},i="kusion destroy",a={unversionedId:"kusion/reference/commands/kusion-destroy",id:"kusion/reference/commands/kusion-destroy",title:"kusion destroy",description:"Destroy resources within the stack.",source:"@site/docs/kusion/6-reference/1-commands/kusion-destroy.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-destroy",permalink:"/docs/next/kusion/reference/commands/kusion-destroy",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-destroy.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion compile",permalink:"/docs/next/kusion/reference/commands/kusion-compile"},next:{title:"kusion init",permalink:"/docs/next/kusion/reference/commands/kusion-init"}},c={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-destroy"},"kusion destroy"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("p",null," Please note that the destroy command does NOT perform resource version checks. Therefore, if someone submits an update to a resource at the same time you execute a destroy command, their update will be lost along with the rest of the resource."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion destroy [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete resources of current stack\n kusion destroy\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details after previewing it\n -h, --help help for destroy\n --operator string Specify the operator\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a28f322c.efc35126.js b/assets/js/a28f322c.efc35126.js deleted file mode 100644 index a49ed866fb6..00000000000 --- a/assets/js/a28f322c.efc35126.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[905],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,i=new Array(s);i[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const s={},i="kusion destroy",a={unversionedId:"kusion/reference/commands/kusion-destroy",id:"kusion/reference/commands/kusion-destroy",title:"kusion destroy",description:"Destroy resources within the stack.",source:"@site/docs/kusion/6-reference/1-commands/kusion-destroy.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-destroy",permalink:"/docs/next/kusion/reference/commands/kusion-destroy",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-destroy.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion compile",permalink:"/docs/next/kusion/reference/commands/kusion-compile"},next:{title:"kusion init",permalink:"/docs/next/kusion/reference/commands/kusion-init"}},c={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-destroy"},"kusion destroy"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("p",null," Please note that the destroy command does NOT perform resource version checks. Therefore, if someone submits an update to a resource at the same time you execute a destroy command, their update will be lost along with the rest of the resource."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion destroy [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete resources of current stack\n kusion destroy\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details after previewing it\n -h, --help help for destroy\n --operator string Specify the operator\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a5969c3a.2e2ca053.js b/assets/js/a5969c3a.2e2ca053.js deleted file mode 100644 index ea92eae44a8..00000000000 --- a/assets/js/a5969c3a.2e2ca053.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2933],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),f=i,y=d["".concat(l,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(y,a(a({ref:t},c),{},{components:n})):r.createElement(y,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion apply",s={unversionedId:"kusion/reference/cli/kusion/kusion_apply",id:"version-v0.9/kusion/reference/cli/kusion/kusion_apply",title:"kusion apply",description:"Apply the operation intents of various resources to multiple runtimes",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_apply.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_apply",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_apply.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Commands",permalink:"/docs/v0.9/kusion/reference/cli/kusion/"},next:{title:"kusion build",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_build"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-apply"},"kusion apply"),(0,i.kt)("p",null,"Apply the operation intents of various resources to multiple runtimes"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"Apply a series of resource changes within the stack."),(0,i.kt)("p",null," Create or update or delete resources according to the KCL files within a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,i.kt)("p",null," You can check the plan details and then decide if the actions should be taken or aborted."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion apply [flags]\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," # Apply with specifying work directory\n kusion apply -w /path/to/workdir\n \n # Apply with specifying arguments\n kusion apply -D name=test -D age=18\n \n # Apply with specifying setting file\n kusion apply -Y settings.yaml\n \n # Apply with specifying spec file\n kusion apply --spec-file spec.yaml\n \n # Skip interactive approval of plan details before applying\n kusion apply --yes\n \n # Apply without output style and color\n kusion apply --no-style=true\n")),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n --dry-run Preview the execution effect (always successful) without actually applying the changes\n -h, --help help for apply\n --ignore-fields strings Ignore differences of target fields\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -O, --overrides strings Specify the configuration override path and value\n -Y, --setting strings Specify the command line setting files\n --spec-file string Specify the spec file path as input, and the spec file must be located in the working directory or its subdirectories\n --watch After creating/updating/deleting the requested object, watch for changes\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a5969c3a.f64b85e6.js b/assets/js/a5969c3a.f64b85e6.js new file mode 100644 index 00000000000..f14062c1f2f --- /dev/null +++ b/assets/js/a5969c3a.f64b85e6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2933],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),f=i,y=d["".concat(l,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(y,a(a({ref:t},c),{},{components:n})):r.createElement(y,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const o={},a="kusion apply",s={unversionedId:"kusion/reference/cli/kusion/kusion_apply",id:"version-v0.9/kusion/reference/cli/kusion/kusion_apply",title:"kusion apply",description:"Apply the operation intents of various resources to multiple runtimes",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_apply.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_apply",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_apply.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Commands",permalink:"/docs/v0.9/kusion/reference/cli/kusion/"},next:{title:"kusion build",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_build"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kusion-apply"},"kusion apply"),(0,i.kt)("p",null,"Apply the operation intents of various resources to multiple runtimes"),(0,i.kt)("h3",{id:"synopsis"},"Synopsis"),(0,i.kt)("p",null,"Apply a series of resource changes within the stack."),(0,i.kt)("p",null," Create or update or delete resources according to the KCL files within a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,i.kt)("p",null," You can check the plan details and then decide if the actions should be taken or aborted."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kusion apply [flags]\n")),(0,i.kt)("h3",{id:"examples"},"Examples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," # Apply with specifying work directory\n kusion apply -w /path/to/workdir\n \n # Apply with specifying arguments\n kusion apply -D name=test -D age=18\n \n # Apply with specifying setting file\n kusion apply -Y settings.yaml\n \n # Apply with specifying spec file\n kusion apply --spec-file spec.yaml\n \n # Skip interactive approval of plan details before applying\n kusion apply --yes\n \n # Apply without output style and color\n kusion apply --no-style=true\n")),(0,i.kt)("h3",{id:"options"},"Options"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n --dry-run Preview the execution effect (always successful) without actually applying the changes\n -h, --help help for apply\n --ignore-fields strings Ignore differences of target fields\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -O, --overrides strings Specify the configuration override path and value\n -Y, --setting strings Specify the command line setting files\n --spec-file string Specify the spec file path as input, and the spec file must be located in the working directory or its subdirectories\n --watch After creating/updating/deleting the requested object, watch for changes\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,i.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,i.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a8f9fa37.c668e600.js b/assets/js/a8f9fa37.32f56175.js similarity index 50% rename from assets/js/a8f9fa37.c668e600.js rename to assets/js/a8f9fa37.32f56175.js index 05ea8bd35b6..c72188c36d9 100644 --- a/assets/js/a8f9fa37.c668e600.js +++ b/assets/js/a8f9fa37.32f56175.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7092],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=s(r),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(k,l(l({ref:t},c),{},{components:r})):n.createElement(k,l({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/catalog-models/internal/network/port",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/network/port",title:"port",description:"Schema Port",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/network",slug:"/kusion/reference/modules/catalog-models/internal/network/port",permalink:"/docs/kusion/reference/modules/catalog-models/internal/network/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"probe",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/"},next:{title:"secret",permalink:"/docs/kusion/reference/modules/catalog-models/internal/secret/"}},p={},s=[{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],c={toc:s};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("h2",{id:"schema-port"},"Schema Port"),(0,a.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,a.kt)("br",null),"get accessed."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The exposed port of the Service."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"80"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"targetPort"),(0,a.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"protocol"),(0,a.kt)("br",null),"The protocol to access the port."),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"public"),(0,a.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"False"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7092],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=s(r),m=a,k=d["".concat(p,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(k,l(l({ref:t},c),{},{components:r})):n.createElement(k,l({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/catalog-models/internal/network/port",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/network/port",title:"port",description:"Schema Port",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/network",slug:"/kusion/reference/modules/catalog-models/internal/network/port",permalink:"/docs/kusion/reference/modules/catalog-models/internal/network/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"probe",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/"},next:{title:"secret",permalink:"/docs/kusion/reference/modules/catalog-models/internal/secret/"}},p={},s=[{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],c={toc:s};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("h2",{id:"schema-port"},"Schema Port"),(0,a.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,a.kt)("br",null),"get accessed."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The exposed port of the Service."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"80"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"targetPort"),(0,a.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"protocol"),(0,a.kt)("br",null),"The protocol to access the port."),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,a.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"public"),(0,a.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"False"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/abc4e0a8.01396e1a.js b/assets/js/abc4e0a8.01396e1a.js deleted file mode 100644 index 442d3d5c47c..00000000000 --- a/assets/js/abc4e0a8.01396e1a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2204],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={id:"overview"},r="Configuration File Overview",l={unversionedId:"kusion/configuration-walkthrough/overview",id:"kusion/configuration-walkthrough/overview",title:"Configuration File Overview",description:"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.",source:"@site/docs/kusion/4-configuration-walkthrough/1-overview.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/overview",permalink:"/docs/next/kusion/configuration-walkthrough/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/1-overview.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview"},sidebar:"kusion",previous:{title:"How Kusion Works?",permalink:"/docs/next/kusion/concepts/how-kusion-works"},next:{title:"KCL Basics",permalink:"/docs/next/kusion/configuration-walkthrough/kcl-basics"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Directory Structure",id:"directory-structure",level:2},{value:"AppConfiguration Model",id:"appconfiguration-model",level:2},{value:"Authoring Configuration Files",id:"authoring-configuration-files",level:2},{value:"Identifying KCL file",id:"identifying-kcl-file",level:3},{value:"KCL Schemas and KAM",id:"kcl-schemas-and-kam",level:3},{value:"Kusion Modules",id:"kusion-modules",level:3},{value:"Import Statements",id:"import-statements",level:3},{value:"Understanding kcl.mod",id:"understanding-kclmod",level:3},{value:"Building Blocks",id:"building-blocks",level:3},{value:"Instantiating an application",id:"instantiating-an-application",level:3},{value:"Using kusion init",id:"using-kusion-init",level:3},{value:"Using references",id:"using-references",level:3}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"configuration-file-overview"},"Configuration File Overview"),(0,a.kt)("p",null,"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure."),(0,a.kt)("p",null,"This documentation series walks you through the odds and ends of managing such configuration files."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configuration-file-overview"},"Configuration File Overview"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#table-of-content"},"Table of Content")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#directory-structure"},"Directory Structure")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#appconfiguration-model"},"AppConfiguration Model")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#authoring-configuration-files"},"Authoring Configuration Files"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#identifying-kcl-file"},"Identifying KCL file")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#kcl-packages-and-import"},"KCL Packages and Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#understanding-kclmod"},"Understanding kcl.mod")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#building-blocks"},"Building Blocks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#instantiating-an-application"},"Instantiating an application")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#using-kusion-init"},"Using ",(0,a.kt)("inlineCode",{parentName:"a"},"kusion init"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#using-references"},"Using references"))))))),(0,a.kt)("h2",{id:"directory-structure"},"Directory Structure"),(0,a.kt)("p",null,"Kusion expects the configuration file to be placed in a certain directory structure because it might need some metadata (that is not stored in the application configuration itself) in order to proceed."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See ",(0,a.kt)("a",{parentName:"p",href:"../concepts/project/overview"},"Project")," and ",(0,a.kt)("a",{parentName:"p",href:"../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,a.kt)("p",null,"A sample multi-stack directory structure looks like the following:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"~/playground$ tree multi-stack-project/\nmulti-stack-project/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 base\n\u2502\xa0\xa0 \u2514\u2500\u2500 base.k\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u251c\u2500\u2500 prod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n")),(0,a.kt)("p",null,"In general, the directory structure follows a hierarchy where the top-level is the project configurations, and the sub-directories represent stack-level configurations."),(0,a.kt)("p",null,"You may notice there is a ",(0,a.kt)("inlineCode",{parentName:"p"},"base")," directory besides all the stacks. The ",(0,a.kt)("inlineCode",{parentName:"p"},"base")," directory is not mandatory, but rather a place to store common configurations between different stacks. A common pattern we observed is to use stacks to represent different stages (dev, stage, prod, etc.) in the software development lifecycle, and/or different deployment targets (azure-eastus, aws-us-east-1, etc). A project can have as many stacks as needed."),(0,a.kt)("p",null,"In practice, the applications deployed into dev and prod might very likely end up with a similar set of configurations except a few fields such as the application image (dev might be on newer versions), resource requirements (prod might require more resources), etc."),(0,a.kt)("p",null,"As a general best practice, we recommend managing the common configurations in ",(0,a.kt)("inlineCode",{parentName:"p"},"base.k")," as much as possible to minimize duplicate code. We will cover how override works in ",(0,a.kt)("a",{parentName:"p",href:"base-override"},"Base and Override"),"."),(0,a.kt)("h2",{id:"appconfiguration-model"},"AppConfiguration Model"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is the out-of-the-box model we build that describes an application. It serves as the declarative intent for a given application."),(0,a.kt)("p",null,"The schema for ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is defined in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kam/blob/main/v1/app_configuration.k"},"KusionStack/kam")," repository. It is designed as a unified, application-centric model that encapsulates the comprehensive configuration details and in the meantime, hides the complexity of the infrastructure as much as possible."),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," consists of multiple sub-components that each represent either the application workload itself, its dependencies (in the form of ",(0,a.kt)("a",{parentName:"p",href:"../concepts/kusion-module"},"Kusion Modules"),"), relevant workflows or operational expectations. We will deep dive into the details on how to author each of these elements in this upcoming documentation series."),(0,a.kt)("p",null,"For more details on the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", please refer to the ",(0,a.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"design documentation"),"."),(0,a.kt)("h2",{id:"authoring-configuration-files"},"Authoring Configuration Files"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open-source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,a.kt)("h3",{id:"identifying-kcl-file"},"Identifying KCL file"),(0,a.kt)("p",null,"KCL files are identified with ",(0,a.kt)("inlineCode",{parentName:"p"},".k")," suffix in the filename."),(0,a.kt)("h3",{id:"kcl-schemas-and-kam"},"KCL Schemas and KAM"),(0,a.kt)("p",null,"Similar to most modern General Programming Languages (GPLs), KCL provide packages that are used to organize collections of related KCL source files into modular and re-usable units."),(0,a.kt)("p",null,"In the context of Kusion, we abstracted a core set of KCL Schemas (such as the aforementioned ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Workload"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),", etc)that represent the concepts that we believe that are relatively universal and developer-friendly, also known as ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kam"},"Kusion Application Model"),", or KAM."),(0,a.kt)("h3",{id:"kusion-modules"},"Kusion Modules"),(0,a.kt)("p",null,"To extend the capabilities beyond the core KAM model, we use a concept known as ",(0,a.kt)("a",{parentName:"p",href:"../concepts/kusion-module"},"Kusion Modules")," to define components that could best abstract the capabilities during an application delivery. We provide a collection of official out-of-the-box Kusion Modules that represents the most common capabilities. They are maintained in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/orgs/KusionStack/packages"},"KusionStack's GitHub container registry"),". When authoring an application configuration file, you can simply declare said Kusion Modules as dependencies and import them to declare ship-time capabilities that the application requires."),(0,a.kt)("p",null,"If the modules in the KusionStack container registry does not meet the needs of your applications, Kusion provides the necessary mechanisms to extend with custom-built Kusion Modules. You can always create and publish your own module, then import the new module in your application configuration written in KCL."),(0,a.kt)("p",null,"For the steps to develop your own module, please refer to the Module developer guide."),(0,a.kt)("h3",{id:"import-statements"},"Import Statements"),(0,a.kt)("p",null,"An example of the import looks like the following:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"### import from the official kam package\nimport kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\n\n### import kusion modules\nimport monitoring as m\nimport network.network as n\n")),(0,a.kt)("p",null,"Take ",(0,a.kt)("inlineCode",{parentName:"p"},"import kam.v1.workload as wl")," as an example, the ",(0,a.kt)("inlineCode",{parentName:"p"},".v1.workload")," part after ",(0,a.kt)("inlineCode",{parentName:"p"},"import kam")," represents the relative path of a specific schema to import. In this case, the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," schema is defined under ",(0,a.kt)("inlineCode",{parentName:"p"},"v1/workload")," directory in the ",(0,a.kt)("inlineCode",{parentName:"p"},"kam")," package."),(0,a.kt)("h3",{id:"understanding-kclmod"},"Understanding kcl.mod"),(0,a.kt)("p",null,"Much similar to the concept of ",(0,a.kt)("inlineCode",{parentName:"p"},"go.mod"),", Kusion uses ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," as the source of truth to manage metadata (such as package name, dependencies, etc.) for the current package. Kusion will also auto-generate a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod.lock")," as the dependency lock file."),(0,a.kt)("p",null,"The most common usage for ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," is to manage the dependency of your application configuration file. "),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Please note this ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," will be automatically generated if you are using ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," to initialize a project with a template. You will only need to modify this file if you are modifying the project metadata outside the initialization process, such as upgrading the dependency version or adding a new dependency altogether, etc.")),(0,a.kt)("p",null,"There are 3 sections in a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"package"),", representing the metadata for the current package."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dependencies"),", describing the packages the current package depends on. Supports referencing either a git repository or an OCI artifact."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"profile"),", defining the behavior for Kusion. In the example below, it describes the list of files Kusion should look for when parsing the application configuration.")),(0,a.kt)("p",null,"An example of ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'[package]\nname = "multi-stack-project"\nedition = "0.5.0"\nversion = "0.1.0"\n\n[dependencies]\nmonitoring = { oci = "oci://ghcr.io/kusionstack/monitoring", tag = "0.1.0" }\nkam = { git = "https://github.com/KusionStack/kam.git", tag = "0.1.0" }\n# Uncomment the line below to use your own modified module\n# my-module = { oci = "oci://ghcr.io/my-repository/my-package", tag = "my-version" }\n\n[profile]\nentries = ["../base/base.k", "main.k"]\n')),(0,a.kt)("h3",{id:"building-blocks"},"Building Blocks"),(0,a.kt)("p",null,"Configuration files consist of building blocks that are made of instances of schemas. An ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance consists of several child schemas, most of which are optional. The only mandatory one is the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance. We will take a closer look in the ",(0,a.kt)("a",{parentName:"p",href:"workload"},"workload walkthrough"),". The order of the building blocks does NOT matter."),(0,a.kt)("p",null,"The major building blocks as of version ",(0,a.kt)("inlineCode",{parentName:"p"},"0.11.0"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n ...\n }\n secrets: {}\n ...\n }\n # optional dependencies, usually expressed in kusion modules\n accessories: {\n ...\n }\n ...\n}\n')),(0,a.kt)("p",null,"We will deep dive into each one of the building blocks in this documentation series."),(0,a.kt)("h3",{id:"instantiating-an-application"},"Instantiating an application"),(0,a.kt)("p",null,"In Kusion's out-of-the-box experience, an application is identified with an instance of ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". You may have more than one application in the same project or stack."),(0,a.kt)("p",null,"Here's an example of a configuration that can be consumed by Kusion (assuming it is placed inside the proper directory structure that includes project and stack configurations, with a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," present):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport network.network as n\n\ngocity: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "gocity": c.Container {\n image = "howieyuen/gocity:latest"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n }\n}\n')),(0,a.kt)("p",null,"Don't worry about what ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"n.Network")," stand for at the moment. We will deep dive into each one of them in this upcoming documentation series."),(0,a.kt)("h3",{id:"using-kusion-init"},"Using ",(0,a.kt)("inlineCode",{parentName:"h3"},"kusion init")),(0,a.kt)("p",null,"Kusion offers a ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," sub-command which initializes a new project using some pre-built templates, which saves you from the hassle of manually building the aforementioned directory structure that Kusion expects."),(0,a.kt)("p",null,"There is a built-in template ",(0,a.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," in the Kusion binary that can be used offline. "),(0,a.kt)("p",null,"We also maintain a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion-templates"},"kusion-templates repository")," that hosts a list of more comprehensive project scaffolds. You can access them via ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init --online")," command which requires connectivity to ",(0,a.kt)("inlineCode",{parentName:"p"},"github.com"),"."),(0,a.kt)("p",null,"The pre-built templates are meant to help you get off the ground quickly with some simple out-of-the-box examples. You can refer to the ",(0,a.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"QuickStart documentation")," for some step-by-step tutorials."),(0,a.kt)("h3",{id:"using-references"},"Using references"),(0,a.kt)("p",null,"The reference documentation for the ",(0,a.kt)("inlineCode",{parentName:"p"},"kam")," package and the official Kusion Modules is located in ",(0,a.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/app-configuration"},"Reference"),"."),(0,a.kt)("p",null,"If you are using them out of the box, the reference documentation provides a comprehensive view for each schema involved, including all the attribute names and description, their types, default value if any, and whether a particular attribute is required or not. There will also be an example attached to each schema reference."),(0,a.kt)("p",null,"We will also deep dive into some common examples in the upcoming sections."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/abc4e0a8.40e42a93.js b/assets/js/abc4e0a8.40e42a93.js new file mode 100644 index 00000000000..bf291eca3ac --- /dev/null +++ b/assets/js/abc4e0a8.40e42a93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2204],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?i.createElement(k,r(r({ref:t},c),{},{components:n})):i.createElement(k,r({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={id:"overview"},r="Configuration File Overview",l={unversionedId:"kusion/configuration-walkthrough/overview",id:"kusion/configuration-walkthrough/overview",title:"Configuration File Overview",description:"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure.",source:"@site/docs/kusion/4-configuration-walkthrough/1-overview.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/overview",permalink:"/docs/next/kusion/configuration-walkthrough/overview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/1-overview.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview"},sidebar:"kusion",previous:{title:"How Kusion Works?",permalink:"/docs/next/kusion/concepts/how-kusion-works"},next:{title:"KCL Basics",permalink:"/docs/next/kusion/configuration-walkthrough/kcl-basics"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Directory Structure",id:"directory-structure",level:2},{value:"AppConfiguration Model",id:"appconfiguration-model",level:2},{value:"Authoring Configuration Files",id:"authoring-configuration-files",level:2},{value:"Identifying KCL file",id:"identifying-kcl-file",level:3},{value:"KCL Schemas and KAM",id:"kcl-schemas-and-kam",level:3},{value:"Kusion Modules",id:"kusion-modules",level:3},{value:"Import Statements",id:"import-statements",level:3},{value:"Understanding kcl.mod",id:"understanding-kclmod",level:3},{value:"Building Blocks",id:"building-blocks",level:3},{value:"Instantiating an application",id:"instantiating-an-application",level:3},{value:"Using kusion init",id:"using-kusion-init",level:3},{value:"Using references",id:"using-references",level:3}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"configuration-file-overview"},"Configuration File Overview"),(0,a.kt)("p",null,"Kusion consumes one or more declarative configuration files (written in KCL) that describe the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure."),(0,a.kt)("p",null,"This documentation series walks you through the odds and ends of managing such configuration files."),(0,a.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#configuration-file-overview"},"Configuration File Overview"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#table-of-content"},"Table of Content")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#directory-structure"},"Directory Structure")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#appconfiguration-model"},"AppConfiguration Model")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#authoring-configuration-files"},"Authoring Configuration Files"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#identifying-kcl-file"},"Identifying KCL file")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#kcl-packages-and-import"},"KCL Packages and Import")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#understanding-kclmod"},"Understanding kcl.mod")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#building-blocks"},"Building Blocks")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#instantiating-an-application"},"Instantiating an application")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#using-kusion-init"},"Using ",(0,a.kt)("inlineCode",{parentName:"a"},"kusion init"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#using-references"},"Using references"))))))),(0,a.kt)("h2",{id:"directory-structure"},"Directory Structure"),(0,a.kt)("p",null,"Kusion expects the configuration file to be placed in a certain directory structure because it might need some metadata (that is not stored in the application configuration itself) in order to proceed."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See ",(0,a.kt)("a",{parentName:"p",href:"../concepts/project/overview"},"Project")," and ",(0,a.kt)("a",{parentName:"p",href:"../concepts/stack/overview"},"Stack")," for more details about Project and Stack.")),(0,a.kt)("p",null,"A sample multi-stack directory structure looks like the following:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"~/playground$ tree multi-stack-project/\nmulti-stack-project/\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 base\n\u2502\xa0\xa0 \u2514\u2500\u2500 base.k\n\u251c\u2500\u2500 dev\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u251c\u2500\u2500 prod\n\u2502\xa0\xa0 \u251c\u2500\u2500 kcl.mod\n\u2502\xa0\xa0 \u251c\u2500\u2500 main.k\n\u2502\xa0\xa0 \u2514\u2500\u2500 stack.yaml\n\u2514\u2500\u2500 project.yaml\n")),(0,a.kt)("p",null,"In general, the directory structure follows a hierarchy where the top-level is the project configurations, and the sub-directories represent stack-level configurations."),(0,a.kt)("p",null,"You may notice there is a ",(0,a.kt)("inlineCode",{parentName:"p"},"base")," directory besides all the stacks. The ",(0,a.kt)("inlineCode",{parentName:"p"},"base")," directory is not mandatory, but rather a place to store common configurations between different stacks. A common pattern we observed is to use stacks to represent different stages (dev, stage, prod, etc.) in the software development lifecycle, and/or different deployment targets (azure-eastus, aws-us-east-1, etc). A project can have as many stacks as needed."),(0,a.kt)("p",null,"In practice, the applications deployed into dev and prod might very likely end up with a similar set of configurations except a few fields such as the application image (dev might be on newer versions), resource requirements (prod might require more resources), etc."),(0,a.kt)("p",null,"As a general best practice, we recommend managing the common configurations in ",(0,a.kt)("inlineCode",{parentName:"p"},"base.k")," as much as possible to minimize duplicate code. We will cover how override works in ",(0,a.kt)("a",{parentName:"p",href:"base-override"},"Base and Override"),"."),(0,a.kt)("h2",{id:"appconfiguration-model"},"AppConfiguration Model"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is the out-of-the-box model we build that describes an application. It serves as the declarative intent for a given application."),(0,a.kt)("p",null,"The schema for ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is defined in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kam/blob/main/v1/app_configuration.k"},"KusionStack/kam")," repository. It is designed as a unified, application-centric model that encapsulates the comprehensive configuration details and in the meantime, hides the complexity of the infrastructure as much as possible."),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," consists of multiple sub-components that each represent either the application workload itself, its dependencies (in the form of ",(0,a.kt)("a",{parentName:"p",href:"../concepts/kusion-module"},"Kusion Modules"),"), relevant workflows or operational expectations. We will deep dive into the details on how to author each of these elements in this upcoming documentation series."),(0,a.kt)("p",null,"For more details on the ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", please refer to the ",(0,a.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"design documentation"),"."),(0,a.kt)("h2",{id:"authoring-configuration-files"},"Authoring Configuration Files"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open-source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,a.kt)("h3",{id:"identifying-kcl-file"},"Identifying KCL file"),(0,a.kt)("p",null,"KCL files are identified with ",(0,a.kt)("inlineCode",{parentName:"p"},".k")," suffix in the filename."),(0,a.kt)("h3",{id:"kcl-schemas-and-kam"},"KCL Schemas and KAM"),(0,a.kt)("p",null,"Similar to most modern General Programming Languages (GPLs), KCL provide packages that are used to organize collections of related KCL source files into modular and re-usable units."),(0,a.kt)("p",null,"In the context of Kusion, we abstracted a core set of KCL Schemas (such as the aforementioned ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Workload"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Container"),", etc)that represent the concepts that we believe that are relatively universal and developer-friendly, also known as ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kam"},"Kusion Application Model"),", or KAM."),(0,a.kt)("h3",{id:"kusion-modules"},"Kusion Modules"),(0,a.kt)("p",null,"To extend the capabilities beyond the core KAM model, we use a concept known as ",(0,a.kt)("a",{parentName:"p",href:"../concepts/kusion-module"},"Kusion Modules")," to define components that could best abstract the capabilities during an application delivery. We provide a collection of official out-of-the-box Kusion Modules that represents the most common capabilities. They are maintained in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/orgs/KusionStack/packages"},"KusionStack's GitHub container registry"),". When authoring an application configuration file, you can simply declare said Kusion Modules as dependencies and import them to declare ship-time capabilities that the application requires."),(0,a.kt)("p",null,"If the modules in the KusionStack container registry does not meet the needs of your applications, Kusion provides the necessary mechanisms to extend with custom-built Kusion Modules. You can always create and publish your own module, then import the new module in your application configuration written in KCL."),(0,a.kt)("p",null,"For the steps to develop your own module, please refer to the Module developer guide."),(0,a.kt)("h3",{id:"import-statements"},"Import Statements"),(0,a.kt)("p",null,"An example of the import looks like the following:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"### import from the official kam package\nimport kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\n\n### import kusion modules\nimport monitoring as m\nimport network.network as n\n")),(0,a.kt)("p",null,"Take ",(0,a.kt)("inlineCode",{parentName:"p"},"import kam.v1.workload as wl")," as an example, the ",(0,a.kt)("inlineCode",{parentName:"p"},".v1.workload")," part after ",(0,a.kt)("inlineCode",{parentName:"p"},"import kam")," represents the relative path of a specific schema to import. In this case, the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," schema is defined under ",(0,a.kt)("inlineCode",{parentName:"p"},"v1/workload")," directory in the ",(0,a.kt)("inlineCode",{parentName:"p"},"kam")," package."),(0,a.kt)("h3",{id:"understanding-kclmod"},"Understanding kcl.mod"),(0,a.kt)("p",null,"Much similar to the concept of ",(0,a.kt)("inlineCode",{parentName:"p"},"go.mod"),", Kusion uses ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," as the source of truth to manage metadata (such as package name, dependencies, etc.) for the current package. Kusion will also auto-generate a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod.lock")," as the dependency lock file."),(0,a.kt)("p",null,"The most common usage for ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," is to manage the dependency of your application configuration file. "),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Please note this ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," will be automatically generated if you are using ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," to initialize a project with a template. You will only need to modify this file if you are modifying the project metadata outside the initialization process, such as upgrading the dependency version or adding a new dependency altogether, etc.")),(0,a.kt)("p",null,"There are 3 sections in a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"package"),", representing the metadata for the current package."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dependencies"),", describing the packages the current package depends on. Supports referencing either a git repository or an OCI artifact."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"profile"),", defining the behavior for Kusion. In the example below, it describes the list of files Kusion should look for when parsing the application configuration.")),(0,a.kt)("p",null,"An example of ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'[package]\nname = "multi-stack-project"\nedition = "0.5.0"\nversion = "0.1.0"\n\n[dependencies]\nmonitoring = { oci = "oci://ghcr.io/kusionstack/monitoring", tag = "0.1.0" }\nkam = { git = "https://github.com/KusionStack/kam.git", tag = "0.1.0" }\n# Uncomment the line below to use your own modified module\n# my-module = { oci = "oci://ghcr.io/my-repository/my-package", tag = "my-version" }\n\n[profile]\nentries = ["../base/base.k", "main.k"]\n')),(0,a.kt)("h3",{id:"building-blocks"},"Building Blocks"),(0,a.kt)("p",null,"Configuration files consist of building blocks that are made of instances of schemas. An ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance consists of several child schemas, most of which are optional. The only mandatory one is the ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," instance. We will take a closer look in the ",(0,a.kt)("a",{parentName:"p",href:"workload"},"workload walkthrough"),". The order of the building blocks does NOT matter."),(0,a.kt)("p",null,"The major building blocks as of version ",(0,a.kt)("inlineCode",{parentName:"p"},"0.11.0"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {}\n ...\n }\n secrets: {}\n ...\n }\n # optional dependencies, usually expressed in kusion modules\n accessories: {\n ...\n }\n ...\n}\n')),(0,a.kt)("p",null,"We will deep dive into each one of the building blocks in this documentation series."),(0,a.kt)("h3",{id:"instantiating-an-application"},"Instantiating an application"),(0,a.kt)("p",null,"In Kusion's out-of-the-box experience, an application is identified with an instance of ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". You may have more than one application in the same project or stack."),(0,a.kt)("p",null,"Here's an example of a configuration that can be consumed by Kusion (assuming it is placed inside the proper directory structure that includes project and stack configurations, with a ",(0,a.kt)("inlineCode",{parentName:"p"},"kcl.mod")," present):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport network.network as n\n\ngocity: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "gocity": c.Container {\n image = "howieyuen/gocity:latest"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n }\n}\n')),(0,a.kt)("p",null,"Don't worry about what ",(0,a.kt)("inlineCode",{parentName:"p"},"workload")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"n.Network")," stand for at the moment. We will deep dive into each one of them in this upcoming documentation series."),(0,a.kt)("h3",{id:"using-kusion-init"},"Using ",(0,a.kt)("inlineCode",{parentName:"h3"},"kusion init")),(0,a.kt)("p",null,"Kusion offers a ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," sub-command which initializes a new project using some pre-built templates, which saves you from the hassle of manually building the aforementioned directory structure that Kusion expects."),(0,a.kt)("p",null,"There is a built-in template ",(0,a.kt)("inlineCode",{parentName:"p"},"single-stack-sample")," in the Kusion binary that can be used offline. "),(0,a.kt)("p",null,"We also maintain a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion-templates"},"kusion-templates repository")," that hosts a list of more comprehensive project scaffolds. You can access them via ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init --online")," command which requires connectivity to ",(0,a.kt)("inlineCode",{parentName:"p"},"github.com"),"."),(0,a.kt)("p",null,"The pre-built templates are meant to help you get off the ground quickly with some simple out-of-the-box examples. You can refer to the ",(0,a.kt)("a",{parentName:"p",href:"../getting-started/deliver-wordpress"},"QuickStart documentation")," for some step-by-step tutorials."),(0,a.kt)("h3",{id:"using-references"},"Using references"),(0,a.kt)("p",null,"The reference documentation for the ",(0,a.kt)("inlineCode",{parentName:"p"},"kam")," package and the official Kusion Modules is located in ",(0,a.kt)("a",{parentName:"p",href:"../reference/modules/catalog-models/app-configuration"},"Reference"),"."),(0,a.kt)("p",null,"If you are using them out of the box, the reference documentation provides a comprehensive view for each schema involved, including all the attribute names and description, their types, default value if any, and whether a particular attribute is required or not. There will also be an example attached to each schema reference."),(0,a.kt)("p",null,"We will also deep dive into some common examples in the upcoming sections."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ad602bef.54441f42.js b/assets/js/ad602bef.54441f42.js deleted file mode 100644 index 3b5dd2b4c72..00000000000 --- a/assets/js/ad602bef.54441f42.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2222],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),h=l(a),d=i,k=h["".concat(c,".").concat(d)]||h[d]||u[d]||o;return a?n.createElement(k,r(r({ref:t},p),{},{components:a})):n.createElement(k,r({ref:t},p))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=a(87462),i=(a(67294),a(3905));const o={sidebar_position:1},r="Deploy Application Securely and Efficiently via GitHub Actions",s={unversionedId:"kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",id:"version-v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",title:"Deploy Application Securely and Efficiently via GitHub Actions",description:"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.",source:"@site/versioned_docs/version-v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions.md",sourceDirName:"kusion/guides/github-actions",slug:"/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",permalink:"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/v0.9/kusion/guides/observability/prometheus"},next:{title:"Command Line Tools",permalink:"/docs/v0.9/kusion/reference/cli/"}},c={},l=[{value:"GitHub Actions Workflow",id:"github-actions-workflow",level:2},{value:"Get Changed Project and Stack",id:"get-changed-project-and-stack",level:2},{value:"Check Project and Stack Structure",id:"check-project-and-stack-structure",level:2},{value:"Test Code Correctness",id:"test-code-correctness",level:2},{value:"Preview Changed Stack",id:"preview-changed-stack",level:2},{value:"Apply Changed Stack",id:"apply-changed-stack",level:2},{value:"Summary",id:"summary",level:2}],p={toc:l};function u(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deploy-application-securely-and-efficiently-via-github-actions"},"Deploy Application Securely and Efficiently via GitHub Actions"),(0,i.kt)("p",null,"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions."),(0,i.kt)("p",null,"Using git repository is a very reliable and common way to manage code, and the same goes for Kusion-managed configuration code. ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," is a CI/CD platform. By customizing ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/using-workflows/about-workflows"},"GitHub Actions workflow"),", the pipeline such as building, testing, and deploying will be executed automatically."),(0,i.kt)("p",null,"Kusion has a commendable integration with Github Actions. You can use Github Actions to test configuration correctness, preview change, and deploy application. This tutorial demonstrates how to deploy and operate an application through GitHub Actions."),(0,i.kt)("h2",{id:"github-actions-workflow"},"GitHub Actions Workflow"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig"},"KusionStack/konfig")," is the official example repository, and provides the GitHub Actions workflow ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml"},"main.yml"),". The main.yml is triggered by a push or a pull request on the main branch, and includes multiple jobs, which ensures the reliability of configuration code, and deploys the changed application."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"workflow",src:a(74559).Z,width:"2594",height:"1364"})),(0,i.kt)("p",null,"The workflow to deploy an application is shown above, which includes the following jobs:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Get changed project and stack"),(0,i.kt)("li",{parentName:"ul"},"Check project and stack structure"),(0,i.kt)("li",{parentName:"ul"},"Test code correctness"),(0,i.kt)("li",{parentName:"ul"},"Preview changed stack"),(0,i.kt)("li",{parentName:"ul"},"Apply changed stack")),(0,i.kt)("p",null,"These jobs ensure the security and efficiency of the application deployment. Next, this tutorial will introduce the usage and function of these jobs. To show how they work more visually, ",(0,i.kt)("em",{parentName:"p"},(0,i.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/actions/runs/6325390734"},"updating port configuration of multi-stack"),' (referred to "the example" in the below)')," is given as an example."),(0,i.kt)("h2",{id:"get-changed-project-and-stack"},"Get Changed Project and Stack"),(0,i.kt)("p",null,"As Kusion organizes code by ",(0,i.kt)("strong",{parentName:"p"},"project")," and ",(0,i.kt)("strong",{parentName:"p"},"stack"),", to deploy the affected applications, analyze the changed project and stack is the first step."),(0,i.kt)("p",null,"The jobs, ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L10"},"get-changed-project-stack")," perfectly accomplish the analysis. The main steps are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Obtain the list of changed files through ",(0,i.kt)("inlineCode",{parentName:"li"},"git diff"),";"),(0,i.kt)("li",{parentName:"ul"},"Based on the changed file list, obtain the changed projects and stacks which are indicated by ",(0,i.kt)("inlineCode",{parentName:"li"},"project.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"stack.yaml")," respectively.")),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176584497"},"example")," changes the file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/base/base.k"),", where the affected project is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack"),", and the stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),". Delightfully, the result, which is shown below, meets our expectation."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"changed-project-stack",src:a(465).Z,width:"1758",height:"1038"})),(0,i.kt)("h2",{id:"check-project-and-stack-structure"},"Check Project and Stack Structure"),(0,i.kt)("p",null,"The job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L39"},"check-structure")," guarantees the structure legality of the changed project and stack, so that Kusion CLI tools can be used correctly. The check items are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in project.yaml;"),(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in stack.yaml.")),(0,i.kt)("p",null,"The success of structure-check means the correctness of structure. A ",(0,i.kt)("a",{parentName:"p",href:"https://docs.pytest.org/en/7.3.x/"},"pytest")," report ",(0,i.kt)("inlineCode",{parentName:"p"},"check-structure-report")," is also generated, and you can get it from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/managing-workflow-runs/downloading-workflow-artifacts"},"GithHub Actions Artifacts")," ."),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176592318"},"example")," passes the directory structure verification. It is clear from the report that the changed project and stack have get checked, and the result is passed."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"check-structure",src:a(71020).Z,width:"1452",height:"482"})),(0,i.kt)("h2",{id:"test-code-correctness"},"Test Code Correctness"),(0,i.kt)("p",null,"Besides a rightful structure, the code must have correct syntax and semantics, and the job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L65"},"test-correctness")," ensures the correctness. ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion compile")," get executed on the changed stacks. If succeeded, there are no syntax errors; or the configuration code is illegal, and the following application deployment will fail."),(0,i.kt)("p",null,"The report whose name is ",(0,i.kt)("inlineCode",{parentName:"p"},"test-correctness-report")," get generated."),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176592034"},"example")," passes the code correctness test. The report shows that the tested stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),", and the result is passed."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"test-correctness",src:a(48848).Z,width:"1626",height:"404"})),(0,i.kt)("h2",{id:"preview-changed-stack"},"Preview Changed Stack"),(0,i.kt)("p",null,"After passing the above jobs, security of the configuration change is guaranteed, and it's time to deploy your application. Before applying the change to the real infrastructure, it's necessary to get the expected result of the application deployment. The job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L90"},"preview")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion preview")," to get the expected change result, the result is uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"preview-report"),". If the result meets your requirement, you can go to the next job and deploy the application."),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176612053"},"example")," changes stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),". The following picture shows the preview result of ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),", where the result is to create a Kubernetes Namespace, Service and Deployment if call ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"preview",src:a(72915).Z,width:"1424",height:"264"})),(0,i.kt)("h2",{id:"apply-changed-stack"},"Apply Changed Stack"),(0,i.kt)("p",null,"Finally, the last step is arrived, i.e. deploy application. The job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L121"},"apply")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply")," to apply the configuration change to the real infrastructure. If the job succeeded, the result will be uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"apply-report"),"."),(0,i.kt)("p",null,"For the stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod")," in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176645252"},"example"),", a Kubernetes Namespace, Service and Deployment get created, which is consistent with the preview result."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"apply",src:a(32965).Z,width:"1456",height:"554"})),(0,i.kt)("h2",{id:"summary"},"Summary"),(0,i.kt)("p",null,"This tutorial demonstrates how Kusion integrates with GitHub Actions to deploy an application. By structure check, correctness test, preview and apply, Kusion with GitHub Actions enables you deploy application efficiently and securely."))}u.isMDXComponent=!0},32965:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-3197adde2cbda84d3e032918679c17cb.png"},465:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/changed-project-stack-0055bea978f129b99b6e74c5b7c4ab88.png"},71020:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/check-structure-2e3226c0efbdbf41b4d7ae70bd16df28.png"},72915:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/preview-4f2aae42391f5decddfcac6107d53a25.png"},48848:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/test-correctness-a6846c2c32c4129b816b6463927325b8.png"},74559:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/workflow-052aa326816199187357363891109493.png"}}]); \ No newline at end of file diff --git a/assets/js/ad602bef.d706b590.js b/assets/js/ad602bef.d706b590.js new file mode 100644 index 00000000000..a3202fcc331 --- /dev/null +++ b/assets/js/ad602bef.d706b590.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2222],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),h=l(a),d=i,k=h["".concat(c,".").concat(d)]||h[d]||u[d]||o;return a?n.createElement(k,r(r({ref:t},p),{},{components:a})):n.createElement(k,r({ref:t},p))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=a(87462),i=(a(67294),a(3905));const o={sidebar_position:1},r="Deploy Application Securely and Efficiently via GitHub Actions",s={unversionedId:"kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",id:"version-v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",title:"Deploy Application Securely and Efficiently via GitHub Actions",description:"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.",source:"@site/versioned_docs/version-v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions.md",sourceDirName:"kusion/guides/github-actions",slug:"/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",permalink:"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/v0.9/kusion/guides/observability/prometheus"},next:{title:"Command Line Tools",permalink:"/docs/v0.9/kusion/reference/cli/"}},c={},l=[{value:"GitHub Actions Workflow",id:"github-actions-workflow",level:2},{value:"Get Changed Project and Stack",id:"get-changed-project-and-stack",level:2},{value:"Check Project and Stack Structure",id:"check-project-and-stack-structure",level:2},{value:"Test Code Correctness",id:"test-code-correctness",level:2},{value:"Preview Changed Stack",id:"preview-changed-stack",level:2},{value:"Apply Changed Stack",id:"apply-changed-stack",level:2},{value:"Summary",id:"summary",level:2}],p={toc:l};function u(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deploy-application-securely-and-efficiently-via-github-actions"},"Deploy Application Securely and Efficiently via GitHub Actions"),(0,i.kt)("p",null,"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions."),(0,i.kt)("p",null,"Using git repository is a very reliable and common way to manage code, and the same goes for Kusion-managed configuration code. ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," is a CI/CD platform. By customizing ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/using-workflows/about-workflows"},"GitHub Actions workflow"),", the pipeline such as building, testing, and deploying will be executed automatically."),(0,i.kt)("p",null,"Kusion has a commendable integration with Github Actions. You can use Github Actions to test configuration correctness, preview change, and deploy application. This tutorial demonstrates how to deploy and operate an application through GitHub Actions."),(0,i.kt)("h2",{id:"github-actions-workflow"},"GitHub Actions Workflow"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig"},"KusionStack/konfig")," is the official example repository, and provides the GitHub Actions workflow ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml"},"main.yml"),". The main.yml is triggered by a push or a pull request on the main branch, and includes multiple jobs, which ensures the reliability of configuration code, and deploys the changed application."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"workflow",src:a(74559).Z,width:"2594",height:"1364"})),(0,i.kt)("p",null,"The workflow to deploy an application is shown above, which includes the following jobs:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Get changed project and stack"),(0,i.kt)("li",{parentName:"ul"},"Check project and stack structure"),(0,i.kt)("li",{parentName:"ul"},"Test code correctness"),(0,i.kt)("li",{parentName:"ul"},"Preview changed stack"),(0,i.kt)("li",{parentName:"ul"},"Apply changed stack")),(0,i.kt)("p",null,"These jobs ensure the security and efficiency of the application deployment. Next, this tutorial will introduce the usage and function of these jobs. To show how they work more visually, ",(0,i.kt)("em",{parentName:"p"},(0,i.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/actions/runs/6325390734"},"updating port configuration of multi-stack"),' (referred to "the example" in the below)')," is given as an example."),(0,i.kt)("h2",{id:"get-changed-project-and-stack"},"Get Changed Project and Stack"),(0,i.kt)("p",null,"As Kusion organizes code by ",(0,i.kt)("strong",{parentName:"p"},"project")," and ",(0,i.kt)("strong",{parentName:"p"},"stack"),", to deploy the affected applications, analyze the changed project and stack is the first step."),(0,i.kt)("p",null,"The jobs, ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L10"},"get-changed-project-stack")," perfectly accomplish the analysis. The main steps are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Obtain the list of changed files through ",(0,i.kt)("inlineCode",{parentName:"li"},"git diff"),";"),(0,i.kt)("li",{parentName:"ul"},"Based on the changed file list, obtain the changed projects and stacks which are indicated by ",(0,i.kt)("inlineCode",{parentName:"li"},"project.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"stack.yaml")," respectively.")),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176584497"},"example")," changes the file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/base/base.k"),", where the affected project is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack"),", and the stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),". Delightfully, the result, which is shown below, meets our expectation."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"changed-project-stack",src:a(465).Z,width:"1758",height:"1038"})),(0,i.kt)("h2",{id:"check-project-and-stack-structure"},"Check Project and Stack Structure"),(0,i.kt)("p",null,"The job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L39"},"check-structure")," guarantees the structure legality of the changed project and stack, so that Kusion CLI tools can be used correctly. The check items are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in project.yaml;"),(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in stack.yaml.")),(0,i.kt)("p",null,"The success of structure-check means the correctness of structure. A ",(0,i.kt)("a",{parentName:"p",href:"https://docs.pytest.org/en/7.3.x/"},"pytest")," report ",(0,i.kt)("inlineCode",{parentName:"p"},"check-structure-report")," is also generated, and you can get it from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/managing-workflow-runs/downloading-workflow-artifacts"},"GithHub Actions Artifacts")," ."),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176592318"},"example")," passes the directory structure verification. It is clear from the report that the changed project and stack have get checked, and the result is passed."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"check-structure",src:a(71020).Z,width:"1452",height:"482"})),(0,i.kt)("h2",{id:"test-code-correctness"},"Test Code Correctness"),(0,i.kt)("p",null,"Besides a rightful structure, the code must have correct syntax and semantics, and the job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L65"},"test-correctness")," ensures the correctness. ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion compile")," get executed on the changed stacks. If succeeded, there are no syntax errors; or the configuration code is illegal, and the following application deployment will fail."),(0,i.kt)("p",null,"The report whose name is ",(0,i.kt)("inlineCode",{parentName:"p"},"test-correctness-report")," get generated."),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176592034"},"example")," passes the code correctness test. The report shows that the tested stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),", and the result is passed."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"test-correctness",src:a(48848).Z,width:"1626",height:"404"})),(0,i.kt)("h2",{id:"preview-changed-stack"},"Preview Changed Stack"),(0,i.kt)("p",null,"After passing the above jobs, security of the configuration change is guaranteed, and it's time to deploy your application. Before applying the change to the real infrastructure, it's necessary to get the expected result of the application deployment. The job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L90"},"preview")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion preview")," to get the expected change result, the result is uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"preview-report"),". If the result meets your requirement, you can go to the next job and deploy the application."),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176612053"},"example")," changes stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),". The following picture shows the preview result of ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod"),", where the result is to create a Kubernetes Namespace, Service and Deployment if call ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"preview",src:a(72915).Z,width:"1424",height:"264"})),(0,i.kt)("h2",{id:"apply-changed-stack"},"Apply Changed Stack"),(0,i.kt)("p",null,"Finally, the last step is arrived, i.e. deploy application. The job ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/main.yml#L121"},"apply")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply")," to apply the configuration change to the real infrastructure. If the job succeeded, the result will be uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"apply-report"),"."),(0,i.kt)("p",null,"For the stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/multi-stack/prod")," in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/actions/runs/6325320773/job/17176645252"},"example"),", a Kubernetes Namespace, Service and Deployment get created, which is consistent with the preview result."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"apply",src:a(32965).Z,width:"1456",height:"554"})),(0,i.kt)("h2",{id:"summary"},"Summary"),(0,i.kt)("p",null,"This tutorial demonstrates how Kusion integrates with GitHub Actions to deploy an application. By structure check, correctness test, preview and apply, Kusion with GitHub Actions enables you deploy application efficiently and securely."))}u.isMDXComponent=!0},32965:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/apply-3197adde2cbda84d3e032918679c17cb.png"},465:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/changed-project-stack-0055bea978f129b99b6e74c5b7c4ab88.png"},71020:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/check-structure-2e3226c0efbdbf41b4d7ae70bd16df28.png"},72915:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/preview-4f2aae42391f5decddfcac6107d53a25.png"},48848:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/test-correctness-a6846c2c32c4129b816b6463927325b8.png"},74559:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/workflow-052aa326816199187357363891109493.png"}}]); \ No newline at end of file diff --git a/assets/js/adf149f0.635eafd2.js b/assets/js/adf149f0.635eafd2.js new file mode 100644 index 00000000000..356ff42ac71 --- /dev/null +++ b/assets/js/adf149f0.635eafd2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5385],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>d});var i=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),c=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=c(e.components);return i.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},f=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=c(t),d=r,k=f["".concat(l,".").concat(d)]||f[d]||u[d]||o;return t?i.createElement(k,s(s({ref:n},p),{},{components:t})):i.createElement(k,s({ref:n},p))}));function d(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,s=new Array(o);s[0]=f;var a={};for(var l in n)hasOwnProperty.call(n,l)&&(a[l]=n[l]);a.originalType=e,a.mdxType="string"==typeof e?e:r,s[1]=a;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var i=t(87462),r=(t(67294),t(3905));const o={},s="kusion preview",a={unversionedId:"kusion/reference/cli/kusion/kusion_preview",id:"version-v0.9/kusion/reference/cli/kusion/kusion_preview",title:"kusion preview",description:"Preview a series of resource changes within the stack",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_preview.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_preview",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_preview.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion init",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init"},next:{title:"kusion version",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version"}},l={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],p={toc:c};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,i.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-preview"},"kusion preview"),(0,r.kt)("p",null,"Preview a series of resource changes within the stack"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Preview a series of resource changes within the stack."),(0,r.kt)("p",null," Create or update or delete resources according to the KCL files within a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion preview [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' # Preview with specifying work directory\n kusion preview -w /path/to/workdir\n \n # Preview with specifying arguments\n kusion preview -D name=test -D age=18\n \n # Preview with specifying setting file\n kusion preview -Y settings.yaml\n \n # Preview with specifying spec file\n kusion preview --spec-file spec.yaml\n \n # Preview with ignored fields\n kusion preview --ignore-fields="metadata.generation,metadata.managedFields\n \n # Preview with json format result\n kusion preview -o json\n \n # Preview without output style and color\n kusion preview --no-style=true\n')),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n -h, --help help for preview\n --ignore-fields strings Ignore differences of target fields\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -O, --overrides strings Specify the configuration override path and value\n -Y, --setting strings Specify the command line setting files\n --spec-file string Specify the spec file path as input, and the spec file must be located in the working directory or its subdirectories\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/adf149f0.6a84419c.js b/assets/js/adf149f0.6a84419c.js deleted file mode 100644 index 53e52aaefe0..00000000000 --- a/assets/js/adf149f0.6a84419c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5385],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>d});var i=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),c=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=c(e.components);return i.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},f=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=c(t),d=r,k=f["".concat(l,".").concat(d)]||f[d]||u[d]||o;return t?i.createElement(k,s(s({ref:n},p),{},{components:t})):i.createElement(k,s({ref:n},p))}));function d(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,s=new Array(o);s[0]=f;var a={};for(var l in n)hasOwnProperty.call(n,l)&&(a[l]=n[l]);a.originalType=e,a.mdxType="string"==typeof e?e:r,s[1]=a;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var i=t(87462),r=(t(67294),t(3905));const o={},s="kusion preview",a={unversionedId:"kusion/reference/cli/kusion/kusion_preview",id:"version-v0.9/kusion/reference/cli/kusion/kusion_preview",title:"kusion preview",description:"Preview a series of resource changes within the stack",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_preview.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_preview",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_preview.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion init",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init"},next:{title:"kusion version",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version"}},l={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],p={toc:c};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,i.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-preview"},"kusion preview"),(0,r.kt)("p",null,"Preview a series of resource changes within the stack"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Preview a series of resource changes within the stack."),(0,r.kt)("p",null," Create or update or delete resources according to the KCL files within a stack. By default, Kusion will generate an execution plan and present it for your approval before taking any action."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion preview [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' # Preview with specifying work directory\n kusion preview -w /path/to/workdir\n \n # Preview with specifying arguments\n kusion preview -D name=test -D age=18\n \n # Preview with specifying setting file\n kusion preview -Y settings.yaml\n \n # Preview with specifying spec file\n kusion preview --spec-file spec.yaml\n \n # Preview with ignored fields\n kusion preview --ignore-fields="metadata.generation,metadata.managedFields\n \n # Preview with json format result\n kusion preview -o json\n \n # Preview without output style and color\n kusion preview --no-style=true\n')),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -a, --all --detail Automatically show all plan details, combined use with flag --detail\n -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details with interactive options\n -h, --help help for preview\n --ignore-fields strings Ignore differences of target fields\n --no-style no-style sets to RawOutput mode and disables all of styling\n --operator string Specify the operator\n -o, --output string Specify the output format\n -O, --overrides strings Specify the configuration override path and value\n -Y, --setting strings Specify the command line setting files\n --spec-file string Specify the spec file path as input, and the spec file must be located in the working directory or its subdirectories\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/aec48fb4.47698132.js b/assets/js/aec48fb4.47698132.js deleted file mode 100644 index 1a519d6e586..00000000000 --- a/assets/js/aec48fb4.47698132.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9858],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>k});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),k=r,c=u["".concat(p,".").concat(k)]||u[k]||m[k]||l;return a?n.createElement(c,i(i({ref:e},d),{},{components:a})):n.createElement(c,i({ref:e},d))}));function k(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="service",o={unversionedId:"kusion/reference/modules/catalog-models/workload/service",id:"kusion/reference/modules/catalog-models/workload/service",title:"service",description:"Schemas",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/service",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/job"},next:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/mysql"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Service",id:"schema-service",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3},{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes-9",level:3},{value:"Examples",id:"examples-9",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"service"},"service"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-service"},"Service"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-port"},"Port"))))),(0,r.kt)("h2",{id:"schema-service"},"Schema Service"),(0,r.kt)("p",null,"Service is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),'is typically used for long-running web applications that should "never" go down, and handle',(0,r.kt)("br",null),"short-lived latency-sensitive web requests, or events."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"ports"),(0,r.kt)("br",null),"The list of ports of the Service should get exposed."),(0,r.kt)("td",{parentName:"tr",align:null},"[",(0,r.kt)("a",{parentName:"td",href:"#schema-port"},"network.Port"),"]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,r.kt)("br",null),"types, including Deployment and CollaSet."),(0,r.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nsvc = wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9090\n }\n ]\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')),(0,r.kt)("h2",{id:"schema-port"},"Schema Port"),(0,r.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,r.kt)("br",null),"get accessed."),(0,r.kt)("h3",{id:"attributes-9"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"port"),(0,r.kt)("br",null),"The exposed port of the Service."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"80"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"protocol"),(0,r.kt)("br",null),"The protocol to access the port."),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"public"),(0,r.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"False"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"targetPort"),(0,r.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-9"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/aec48fb4.e21b233c.js b/assets/js/aec48fb4.e21b233c.js new file mode 100644 index 00000000000..8c0a8ccd8e4 --- /dev/null +++ b/assets/js/aec48fb4.e21b233c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9858],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>k});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),k=r,c=u["".concat(p,".").concat(k)]||u[k]||m[k]||l;return a?n.createElement(c,i(i({ref:e},d),{},{components:a})):n.createElement(c,i({ref:e},d))}));function k(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="service",o={unversionedId:"kusion/reference/modules/catalog-models/workload/service",id:"kusion/reference/modules/catalog-models/workload/service",title:"service",description:"Schemas",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/service",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/next/kusion/reference/modules/catalog-models/workload/job"},next:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/mysql"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Service",id:"schema-service",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3},{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes-9",level:3},{value:"Examples",id:"examples-9",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"service"},"service"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-service"},"Service"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-port"},"Port"))))),(0,r.kt)("h2",{id:"schema-service"},"Schema Service"),(0,r.kt)("p",null,"Service is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),'is typically used for long-running web applications that should "never" go down, and handle',(0,r.kt)("br",null),"short-lived latency-sensitive web requests, or events."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"ports"),(0,r.kt)("br",null),"The list of ports of the Service should get exposed."),(0,r.kt)("td",{parentName:"tr",align:null},"[",(0,r.kt)("a",{parentName:"td",href:"#schema-port"},"network.Port"),"]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,r.kt)("br",null),"types, including Deployment and CollaSet."),(0,r.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nsvc = wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9090\n }\n ]\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')),(0,r.kt)("h2",{id:"schema-port"},"Schema Port"),(0,r.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,r.kt)("br",null),"get accessed."),(0,r.kt)("h3",{id:"attributes-9"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"port"),(0,r.kt)("br",null),"The exposed port of the Service."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"80"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"protocol"),(0,r.kt)("br",null),"The protocol to access the port."),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"public"),(0,r.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"False"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"targetPort"),(0,r.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-9"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/af046d03.0c8d20c1.js b/assets/js/af046d03.0c8d20c1.js new file mode 100644 index 00000000000..9c937364fc9 --- /dev/null +++ b/assets/js/af046d03.0c8d20c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6047],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=d(n),u=r,k=c["".concat(s,".").concat(u)]||c[u]||p[u]||l;return n?a.createElement(k,i(i({ref:t},m),{},{components:n})):a.createElement(k,i({ref:t},m))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},i="container",o={unversionedId:"kusion/reference/modules/catalog-models/internal/container/container",id:"kusion/reference/modules/catalog-models/internal/container/container",title:"container",description:"Schema Container",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container",slug:"/kusion/reference/modules/catalog-models/internal/container/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"common",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/common"},next:{title:"lifecycle",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/"}},s={},d=[{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3}],m={toc:d};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"container"},"container"),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/af046d03.6f24420a.js b/assets/js/af046d03.6f24420a.js deleted file mode 100644 index 87797cdb609..00000000000 --- a/assets/js/af046d03.6f24420a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6047],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=d(n),u=r,k=c["".concat(s,".").concat(u)]||c[u]||p[u]||l;return n?a.createElement(k,i(i({ref:t},m),{},{components:n})):a.createElement(k,i({ref:t},m))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const l={},i="container",o={unversionedId:"kusion/reference/modules/catalog-models/internal/container/container",id:"kusion/reference/modules/catalog-models/internal/container/container",title:"container",description:"Schema Container",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container",slug:"/kusion/reference/modules/catalog-models/internal/container/",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"common",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/common"},next:{title:"lifecycle",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/"}},s={},d=[{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3}],m={toc:d};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"container"},"container"),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/af2e79ee.00cacc63.js b/assets/js/af2e79ee.00cacc63.js deleted file mode 100644 index 1c59640a4e7..00000000000 --- a/assets/js/af2e79ee.00cacc63.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7926],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(n),d=o,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||a;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const a={id:"configuration",sidebar_label:"Stack Configuration"},i="Stack Configuration",c={unversionedId:"kusion/concepts/stack/configuration",id:"version-v0.10/kusion/concepts/stack/configuration",title:"Stack Configuration",description:"Users can add config items of the stack in stack.yaml, such as the stack name, etc.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/2-configuration.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/configuration",permalink:"/docs/kusion/concepts/stack/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/2-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Stack Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/kusion/concepts/stack/overview"},next:{title:"Kusion Module",permalink:"/docs/kusion/concepts/kusion-module"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"stack-configuration"},"Stack Configuration"),(0,o.kt)("p",null,"Users can add config items of the stack in ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml"),", such as the stack name, etc."),(0,o.kt)("p",null,"Here is an example of ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# The stack basic info\nname: dev\n")),(0,o.kt)("p",null,"The config items in ",(0,o.kt)("inlineCode",{parentName:"p"},"stack.yaml")," are explained below."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"name"),": The name of the stack, should be same as the workspace name, such as ",(0,o.kt)("inlineCode",{parentName:"li"},"dev"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"pre")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"prod"),".")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/af2e79ee.9daf7eac.js b/assets/js/af2e79ee.9daf7eac.js new file mode 100644 index 00000000000..121805e7fbc --- /dev/null +++ b/assets/js/af2e79ee.9daf7eac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7926],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(n),d=a,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||o;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const o={id:"configuration",sidebar_label:"Stack Configuration"},i="Stack Configuration",c={unversionedId:"kusion/concepts/stack/configuration",id:"version-v0.10/kusion/concepts/stack/configuration",title:"Stack Configuration",description:"Users can add config items of the stack in stack.yaml, such as the stack name, etc.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/2-configuration.md",sourceDirName:"kusion/3-concepts/2-stack",slug:"/kusion/concepts/stack/configuration",permalink:"/docs/kusion/concepts/stack/configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/2-configuration.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"configuration",sidebar_label:"Stack Configuration"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/kusion/concepts/stack/overview"},next:{title:"Kusion Module",permalink:"/docs/kusion/concepts/kusion-module"}},s={},l=[],u={toc:l};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"stack-configuration"},"Stack Configuration"),(0,a.kt)("p",null,"Users can add config items of the stack in ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml"),", such as the stack name, etc."),(0,a.kt)("p",null,"Here is an example of ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"# The stack basic info\nname: dev\n")),(0,a.kt)("p",null,"The config items in ",(0,a.kt)("inlineCode",{parentName:"p"},"stack.yaml")," are explained below."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"name"),": The name of the stack, should be same as the workspace name, such as ",(0,a.kt)("inlineCode",{parentName:"li"},"dev"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"pre")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"prod"),".")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b049517a.75e46ed3.js b/assets/js/b049517a.75e46ed3.js new file mode 100644 index 00000000000..e4aa6dd6261 --- /dev/null +++ b/assets/js/b049517a.75e46ed3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[550],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),d=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var r=n(87462),a=(n(67294),n(3905));const o={id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},l="Resource Naming Conventions",i={unversionedId:"kusion/reference/modules/naming-conventions",id:"version-v0.10/kusion/reference/modules/naming-conventions",title:"Resource Naming Conventions",description:"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/3-naming-conventions.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/naming-conventions",permalink:"/docs/kusion/reference/modules/naming-conventions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/3-naming-conventions.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},sidebar:"kusion",previous:{title:"service",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/service"},next:{title:"Roadmap",permalink:"/docs/kusion/reference/roadmap"}},s={},d=[{value:"Kubernetes Resources",id:"kubernetes-resources",level:2},{value:"Terraform Resources",id:"terraform-resources",level:2}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"resource-naming-conventions"},"Resource Naming Conventions"),(0,a.kt)("p",null,"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources. "),(0,a.kt)("h2",{id:"kubernetes-resources"},"Kubernetes Resources"),(0,a.kt)("p",null,"Kusion adheres to specific rules when generating the Kubernetes resources for users' applications. The table below lists some common Kubernetes resource naming conventions. Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"Namespace")," can now be specified by users. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Namespace"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Namespace:wordpress-local-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"apps/v1:Deployment:wordpress-local-db:wordpress-local-db-dev-wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"CronJob"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"batch/v1:CronJob:helloworld:helloworld-dev-helloworld")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Service"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"}," or ")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Service:helloworld:helloworld-dev-helloworld-public")))),(0,a.kt)("h2",{id:"terraform-resources"},"Terraform Resources"),(0,a.kt)("p",null,"Similarly, Kusion also adheres to specific naming conventions when generating the Terraform Resources. Some common resources are listed below. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"random_password"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:random:random_password:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_security_group"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_security_group:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_connection"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_connection:wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_rds_account"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_rds_account:wordpress")))),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,a.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,a.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,a.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,a.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b049517a.e4ec7dff.js b/assets/js/b049517a.e4ec7dff.js deleted file mode 100644 index eb427438369..00000000000 --- a/assets/js/b049517a.e4ec7dff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[550],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),d=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var r=n(87462),a=(n(67294),n(3905));const o={id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},l="Resource Naming Conventions",i={unversionedId:"kusion/reference/modules/naming-conventions",id:"version-v0.10/kusion/reference/modules/naming-conventions",title:"Resource Naming Conventions",description:"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/3-naming-conventions.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/naming-conventions",permalink:"/docs/kusion/reference/modules/naming-conventions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/3-naming-conventions.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"naming-conventions",sidebar_label:"Resource Naming Conventions"},sidebar:"kusion",previous:{title:"service",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/service"},next:{title:"Roadmap",permalink:"/docs/kusion/reference/roadmap"}},s={},d=[{value:"Kubernetes Resources",id:"kubernetes-resources",level:2},{value:"Terraform Resources",id:"terraform-resources",level:2}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"resource-naming-conventions"},"Resource Naming Conventions"),(0,a.kt)("p",null,"Kusion will automatically create Kubernetes or Terraform resources for the applications, many of which do not require users' awareness. This document will introduce the naming conventions for these related resources. "),(0,a.kt)("h2",{id:"kubernetes-resources"},"Kubernetes Resources"),(0,a.kt)("p",null,"Kusion adheres to specific rules when generating the Kubernetes resources for users' applications. The table below lists some common Kubernetes resource naming conventions. Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"Namespace")," can now be specified by users. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Namespace"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Namespace:wordpress-local-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"apps/v1:Deployment:wordpress-local-db:wordpress-local-db-dev-wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"CronJob"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"batch/v1:CronJob:helloworld:helloworld-dev-helloworld")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Service"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"}," or ")),(0,a.kt)("td",{parentName:"tr",align:null},"v1:Service:helloworld:helloworld-dev-helloworld-public")))),(0,a.kt)("h2",{id:"terraform-resources"},"Terraform Resources"),(0,a.kt)("p",null,"Similarly, Kusion also adheres to specific naming conventions when generating the Terraform Resources. Some common resources are listed below. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Resource"),(0,a.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,a.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"random_password"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:random:random_password:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_security_group"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},""),"-",(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_security_group:wordpress-db-mysql")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"aws_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_instance"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_instance:wordpress-db")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_db_connection"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_connection:wordpress")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"alicloud_rds_account"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"")),(0,a.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_rds_account:wordpress")))),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,a.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,a.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,a.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,a.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,a.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b075c519.7635c071.js b/assets/js/b075c519.7635c071.js new file mode 100644 index 00000000000..0fa09e56cb8 --- /dev/null +++ b/assets/js/b075c519.7635c071.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3464],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),i=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=i(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=i(n),d=o,h=m["".concat(s,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(h,l(l({ref:t},p),{},{components:n})):r.createElement(h,l({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,l[1]=c;for(var i=2;i{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var r=n(87462),o=(n(67294),n(3905));const a={},l="Concepts",c={unversionedId:"ctrlmesh/concepts/concepts",id:"ctrlmesh/concepts/concepts",title:"Concepts",description:"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.",source:"@site/docs/ctrlmesh/concepts/concepts.md",sourceDirName:"ctrlmesh/concepts",slug:"/ctrlmesh/concepts/",permalink:"/docs/next/ctrlmesh/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/concepts/concepts.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",previous:{title:"Controller Mesh",permalink:"/docs/next/ctrlmesh/intro/"},next:{title:"Installation",permalink:"/docs/next/ctrlmesh/started/install"}},s={},i=[],p={toc:i};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"concepts"},"Concepts"),(0,o.kt)("p",null,"Generally, a ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy")," container will be injected into each operator Pod that has configured in ShardingConfigs.\nThis proxy container will intercept and handle the connection by between API/Oth Server and controllers/webhooks in the Pod."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"550",src:n(3400).Z})),(0,o.kt)("p",null,"ApiServer proxy method:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"iptables nat"),": "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"fake kubeconfig"),": ")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-manager")," dispatches rules to the proxies, so that they can route requests according to the rules."),(0,o.kt)("p",null,"A core CRD of ControllerMesh is ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),". It contains all rules for user's controller:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-demo\n namespace: operator-demo\nspec:\n controller:\n leaderElectionName: operator-leader\n webhook:\n certDir: /tmp/webhook-certs\n port: 9443\n limits:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - pods\n - services\n selector:\n matchExpressions:\n - key: ctrlmesh.kusionstack.io/namespace\n operator: In\n values:\n - ns-a\n - ns-b\n matchLabels:\n app: foo\n selector:\n matchExpressions:\n - key: statefulset.kubernetes.io/pod-name\n operator: In\n values:\n - operator-demo-0\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"selector: for all pods under a shard. It can be a subset of pods under a StatefulSet."),(0,o.kt)("li",{parentName:"ul"},"controller: configuration for controller, including leader election name"),(0,o.kt)("li",{parentName:"ul"},"webhook: configuration for webhook, including certDir and port of this webhook"),(0,o.kt)("li",{parentName:"ul"},"limits: shard isolation is achieved through a set of ",(0,o.kt)("inlineCode",{parentName:"li"},"ObjectSelector"),".")),(0,o.kt)("p",null,"When ",(0,o.kt)("inlineCode",{parentName:"p"},"manager")," is first launched, shard labels will be added to all configured resources."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/sharding-hash"),": the hash value calculated based on the namespace ranges from 0 to 31."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/namespace"),": the namespace referring to this resource."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/control"),": under ctrlmesh-manager control.")),(0,o.kt)("p",null,"In this repo, we only support ",(0,o.kt)("inlineCode",{parentName:"p"},"ObjectSelector")," type of flow control,\nwhich means the ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy "),"will proxy http/s requests to the ApiServer,\nand inject a ",(0,o.kt)("inlineCode",{parentName:"p"},"LabelSelector")," into the request param for the requested resource type."),(0,o.kt)("p",null,"Router:"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"600",src:n(85321).Z})))}u.isMDXComponent=!0},3400:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/fake-configmap-532e288cad1389abce66dcd4b67cd817.png"},85321:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/mesh-proxy-4103e0c9a907b1df91258341cd841c52.png"}}]); \ No newline at end of file diff --git a/assets/js/b075c519.ce1d6b1a.js b/assets/js/b075c519.ce1d6b1a.js deleted file mode 100644 index d9ec3460702..00000000000 --- a/assets/js/b075c519.ce1d6b1a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3464],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),i=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=i(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=i(n),d=o,h=m["".concat(c,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(h,l(l({ref:t},p),{},{components:n})):r.createElement(h,l({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var i=2;i{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>i});var r=n(87462),o=(n(67294),n(3905));const a={},l="Concepts",s={unversionedId:"ctrlmesh/concepts/concepts",id:"ctrlmesh/concepts/concepts",title:"Concepts",description:"Generally, a ctrlmesh-proxy container will be injected into each operator Pod that has configured in ShardingConfigs.",source:"@site/docs/ctrlmesh/concepts/concepts.md",sourceDirName:"ctrlmesh/concepts",slug:"/ctrlmesh/concepts/",permalink:"/docs/next/ctrlmesh/concepts/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/concepts/concepts.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"ctrlmesh",previous:{title:"Controller Mesh",permalink:"/docs/next/ctrlmesh/intro/"},next:{title:"Installation",permalink:"/docs/next/ctrlmesh/started/install"}},c={},i=[],p={toc:i};function u(e){let{components:t,...a}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"concepts"},"Concepts"),(0,o.kt)("p",null,"Generally, a ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy")," container will be injected into each operator Pod that has configured in ShardingConfigs.\nThis proxy container will intercept and handle the connection by between API/Oth Server and controllers/webhooks in the Pod."),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"550",src:n(3400).Z})),(0,o.kt)("p",null,"ApiServer proxy method:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"iptables nat"),": "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("em",{parentName:"li"},"fake kubeconfig"),": ")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-manager")," dispatches rules to the proxies, so that they can route requests according to the rules."),(0,o.kt)("p",null,"A core CRD of ControllerMesh is ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),". It contains all rules for user's controller:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-demo\n namespace: operator-demo\nspec:\n controller:\n leaderElectionName: operator-leader\n webhook:\n certDir: /tmp/webhook-certs\n port: 9443\n limits:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - pods\n - services\n selector:\n matchExpressions:\n - key: ctrlmesh.kusionstack.io/namespace\n operator: In\n values:\n - ns-a\n - ns-b\n matchLabels:\n app: foo\n selector:\n matchExpressions:\n - key: statefulset.kubernetes.io/pod-name\n operator: In\n values:\n - operator-demo-0\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"selector: for all pods under a shard. It can be a subset of pods under a StatefulSet."),(0,o.kt)("li",{parentName:"ul"},"controller: configuration for controller, including leader election name"),(0,o.kt)("li",{parentName:"ul"},"webhook: configuration for webhook, including certDir and port of this webhook"),(0,o.kt)("li",{parentName:"ul"},"limits: shard isolation is achieved through a set of ",(0,o.kt)("inlineCode",{parentName:"li"},"ObjectSelector"),".")),(0,o.kt)("p",null,"When ",(0,o.kt)("inlineCode",{parentName:"p"},"manager")," is first launched, shard labels will be added to all configured resources."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/sharding-hash"),": the hash value calculated based on the namespace ranges from 0 to 31."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/namespace"),": the namespace referring to this resource."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ctrlmesh.kusionstack.io/control"),": under ctrlmesh-manager control.")),(0,o.kt)("p",null,"In this repo, we only support ",(0,o.kt)("inlineCode",{parentName:"p"},"ObjectSelector")," type of flow control,\nwhich means the ",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh-proxy "),"will proxy http/s requests to the ApiServer,\nand inject a ",(0,o.kt)("inlineCode",{parentName:"p"},"LabelSelector")," into the request param for the requested resource type."),(0,o.kt)("p",null,"Router:"),(0,o.kt)("p",{align:"center"},(0,o.kt)("img",{width:"600",src:n(85321).Z})))}u.isMDXComponent=!0},3400:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/fake-configmap-532e288cad1389abce66dcd4b67cd817.png"},85321:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/mesh-proxy-4103e0c9a907b1df91258341cd841c52.png"}}]); \ No newline at end of file diff --git a/assets/js/b2f45e36.6ac4def4.js b/assets/js/b2f45e36.6ac4def4.js new file mode 100644 index 00000000000..55a6f478149 --- /dev/null +++ b/assets/js/b2f45e36.6ac4def4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9434],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=l(a),h=i,m=d["".concat(c,".").concat(h)]||d[h]||u[h]||r;return a?n.createElement(m,s(s({ref:t},p),{},{components:a})):n.createElement(m,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=d;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o.mdxType="string"==typeof e?e:i,s[1]=o;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=a(87462),i=(a(67294),a(3905));const r={},s="Deploy Application Securely and Efficiently via GitHub Actions",o={unversionedId:"kusion/user-guides/github-actions/deploy-application-via-github-actions",id:"kusion/user-guides/github-actions/deploy-application-via-github-actions",title:"Deploy Application Securely and Efficiently via GitHub Actions",description:"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.",source:"@site/docs/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",sourceDirName:"kusion/5-user-guides/4-github-actions",slug:"/kusion/user-guides/github-actions/deploy-application-via-github-actions",permalink:"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/next/kusion/user-guides/observability/prometheus"},next:{title:"Using Cloud Secrets Manager",permalink:"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets"}},c={},l=[{value:"GitHub Actions Workflow",id:"github-actions-workflow",level:2},{value:"Get Changed Project and Stack",id:"get-changed-project-and-stack",level:2},{value:"Check Project and Stack Structure",id:"check-project-and-stack-structure",level:2},{value:"Test Code Correctness",id:"test-code-correctness",level:2},{value:"Preview Changed Stack",id:"preview-changed-stack",level:2},{value:"Apply Changed Stack",id:"apply-changed-stack",level:2},{value:"Summary",id:"summary",level:2}],p={toc:l};function u(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deploy-application-securely-and-efficiently-via-github-actions"},"Deploy Application Securely and Efficiently via GitHub Actions"),(0,i.kt)("p",null,"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions."),(0,i.kt)("p",null,"Using git repository is a very reliable and common way to manage code, and the same goes for Kusion-managed configuration code. ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," is a CI/CD platform. By customizing ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/using-workflows/about-workflows"},"GitHub Actions workflow"),", the pipeline such as building, testing, and deploying will be executed automatically."),(0,i.kt)("p",null,"Kusion has a commendable integration with GitHub Actions. You can use GitHub Actions to test configuration correctness, preview change, and deploy application. This tutorial demonstrates how to deploy and operate an application through GitHub Actions."),(0,i.kt)("h2",{id:"github-actions-workflow"},"GitHub Actions Workflow"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig"},"KusionStack/konfig")," is the official example repository, and provides the GitHub Actions workflow ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/deploy/deploy.yml"},(0,i.kt)("em",{parentName:"a"},"deploy")),". The workflow is triggered by a push on the main branch, and includes multiple jobs, which ensures the reliability of configuration code, and deploys the changed application."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"workflow",src:a(74559).Z,width:"2594",height:"1364"})),(0,i.kt)("p",null,"The workflow to deploy an application is shown above, which includes the following jobs:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Get changed project and stack"),(0,i.kt)("li",{parentName:"ul"},"Check project and stack structure"),(0,i.kt)("li",{parentName:"ul"},"Test code correctness"),(0,i.kt)("li",{parentName:"ul"},"Preview changed stack"),(0,i.kt)("li",{parentName:"ul"},"Apply changed stack")),(0,i.kt)("p",null,"These jobs ensure the security and efficiency of the application deployment. Next, this tutorial will introduce the usage and function of these jobs. To show how they work more visually, updating port configuration in file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k")," of ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/service-multi-stack"},(0,i.kt)("em",{parentName:"a"},"service-multi-stack")),' (referred to "the example" in the below) is given as an example.'),(0,i.kt)("h2",{id:"get-changed-project-and-stack"},"Get Changed Project and Stack"),(0,i.kt)("p",null,"As Kusion organizes code by project and stack, to deploy the affected applications, analyze the changed project and stack is the first step."),(0,i.kt)("p",null,"The job, ",(0,i.kt)("strong",{parentName:"p"},"get-changed-project-stack")," perfectly accomplish the analysis. The main steps are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Obtain the list of changed files through ",(0,i.kt)("inlineCode",{parentName:"li"},"git diff"),";"),(0,i.kt)("li",{parentName:"ul"},"Based on the changed file list, obtain the changed projects and stacks which are indicated by ",(0,i.kt)("inlineCode",{parentName:"li"},"project.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"stack.yaml")," respectively.")),(0,i.kt)("p",null,"The example changes the file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k"),", where the affected project is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack"),", and the stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". Delightfully, the result, which is shown below, meets our expectation."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"changed-project-stack",src:a(15203).Z,width:"2248",height:"1104"})),(0,i.kt)("h2",{id:"check-project-and-stack-structure"},"Check Project and Stack Structure"),(0,i.kt)("p",null,"The job ",(0,i.kt)("strong",{parentName:"p"},"check-structure")," guarantees the structure legality of the changed project and stack, so that Kusion CLI tools can be used correctly. The check items are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in project.yaml;"),(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in stack.yaml.")),(0,i.kt)("p",null,"The success of structure-check means the correctness of structure. A ",(0,i.kt)("a",{parentName:"p",href:"https://docs.pytest.org/en/7.3.x/"},"pytest")," report ",(0,i.kt)("inlineCode",{parentName:"p"},"check-structure-report")," is also generated, and you can get it from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/managing-workflow-runs/downloading-workflow-artifacts"},"GithHub Actions Artifacts")," ."),(0,i.kt)("p",null,"The example passes the directory structure verification. It is clear from the report that the changed project and stack have get checked, and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n \n\n')),(0,i.kt)("h2",{id:"test-code-correctness"},"Test Code Correctness"),(0,i.kt)("p",null,"Besides a rightful structure, the code must have correct syntax and semantics, and the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," ensures the correctness. ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," get executed on the changed stacks. If succeeded, there are no syntax errors; or the configuration code is illegal, and the following application deployment will fail."),(0,i.kt)("p",null,"In this job, not only the correctness of AppConfiguration is checked, but also the workspace configuration. Hence, you should prepare workspace configuration in advance. Now, the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," supports you put workspace configuration files under directory ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces")," with file name's prefix the same as the workspace name and suffix ",(0,i.kt)("inlineCode",{parentName:"p"},".yaml"),". For example, if you have two workspaces named ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"prod"),", you should provide files ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/dev.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/prod.yaml")," with corresponding workspace configuration."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"The jobs preview and apply also ask for the workspace configuration files."),(0,i.kt)("p",{parentName:"admonition"},"Putting AppConfiguration and workspace configuration in one repository seems not a good idea. Doing this is to give a simple illustration. You can change it in your real production practice, and you can get more information of ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/app-configuration"},"AppConfiguration")," and ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspace")," here.")),(0,i.kt)("p",null,"The report whose name is ",(0,i.kt)("inlineCode",{parentName:"p"},"test-correctness-report")," get generated."),(0,i.kt)("p",null,"The example passes the code correctness test. The report shows that the tested stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n\n')),(0,i.kt)("h2",{id:"preview-changed-stack"},"Preview Changed Stack"),(0,i.kt)("p",null,"After passing the above jobs, security of the configuration change is guaranteed, and it's time to deploy your application. Before applying the change to the real infrastructure, it's necessary to get the expected result of the application deployment. The job ",(0,i.kt)("strong",{parentName:"p"},"preview")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion preview")," to get the expected change result, the result is uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"preview-report"),". If the result meets your requirement, you can go to the next job and deploy the application."),(0,i.kt)("p",null,"The example changes stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". The following picture shows the preview result of ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", where the result is to create a Kubernetes Namespace, Service and Deployment if call ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack Create\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n")),(0,i.kt)("h2",{id:"apply-changed-stack"},"Apply Changed Stack"),(0,i.kt)("p",null,"Finally, the last step is arrived, i.e. deploy application. The job ",(0,i.kt)("strong",{parentName:"p"},"apply")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply")," to apply the configuration change to the real infrastructure. If the job succeeded, the result will be uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"apply-report"),"."),(0,i.kt)("p",null,"For the stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod")," in the example, a Kubernetes Namespace, Service and Deployment get created, which is consistent with the preview result."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack UnChanged\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n\nStart applying diffs ...\n \nSUCCESS: UnChanged v1:Namespace:service-multi-stack, skip \nSUCCESS: Create v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public success \nSUCCESS: Create apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver success\n\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"summary"},"Summary"),(0,i.kt)("p",null,"This tutorial demonstrates how Kusion integrates with GitHub Actions to deploy an application. By structure check, correctness test, preview and apply, Kusion with GitHub Actions enables you deploy application efficiently and securely."))}u.isMDXComponent=!0},15203:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-changed-project-stack-de4c7df77236ad9eeb758f1f9e2af703.png"},74559:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/workflow-052aa326816199187357363891109493.png"}}]); \ No newline at end of file diff --git a/assets/js/b2f45e36.99cc16c4.js b/assets/js/b2f45e36.99cc16c4.js deleted file mode 100644 index c84feb2dd92..00000000000 --- a/assets/js/b2f45e36.99cc16c4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9434],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=l(a),h=i,m=d["".concat(c,".").concat(h)]||d[h]||u[h]||r;return a?n.createElement(m,s(s({ref:t},p),{},{components:a})):n.createElement(m,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=d;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o.mdxType="string"==typeof e?e:i,s[1]=o;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=a(87462),i=(a(67294),a(3905));const r={},s="Deploy Application Securely and Efficiently via GitHub Actions",o={unversionedId:"kusion/user-guides/github-actions/deploy-application-via-github-actions",id:"kusion/user-guides/github-actions/deploy-application-via-github-actions",title:"Deploy Application Securely and Efficiently via GitHub Actions",description:"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.",source:"@site/docs/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",sourceDirName:"kusion/5-user-guides/4-github-actions",slug:"/kusion/user-guides/github-actions/deploy-application-via-github-actions",permalink:"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/next/kusion/user-guides/observability/prometheus"},next:{title:"Using Cloud Secrets Manager",permalink:"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets"}},c={},l=[{value:"GitHub Actions Workflow",id:"github-actions-workflow",level:2},{value:"Get Changed Project and Stack",id:"get-changed-project-and-stack",level:2},{value:"Check Project and Stack Structure",id:"check-project-and-stack-structure",level:2},{value:"Test Code Correctness",id:"test-code-correctness",level:2},{value:"Preview Changed Stack",id:"preview-changed-stack",level:2},{value:"Apply Changed Stack",id:"apply-changed-stack",level:2},{value:"Summary",id:"summary",level:2}],p={toc:l};function u(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deploy-application-securely-and-efficiently-via-github-actions"},"Deploy Application Securely and Efficiently via GitHub Actions"),(0,i.kt)("p",null,"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions."),(0,i.kt)("p",null,"Using git repository is a very reliable and common way to manage code, and the same goes for Kusion-managed configuration code. ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," is a CI/CD platform. By customizing ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/using-workflows/about-workflows"},"GitHub Actions workflow"),", the pipeline such as building, testing, and deploying will be executed automatically."),(0,i.kt)("p",null,"Kusion has a commendable integration with GitHub Actions. You can use GitHub Actions to test configuration correctness, preview change, and deploy application. This tutorial demonstrates how to deploy and operate an application through GitHub Actions."),(0,i.kt)("h2",{id:"github-actions-workflow"},"GitHub Actions Workflow"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig"},"KusionStack/konfig")," is the official example repository, and provides the GitHub Actions workflow ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/deploy/deploy.yml"},(0,i.kt)("em",{parentName:"a"},"deploy")),". The workflow is triggered by a push on the main branch, and includes multiple jobs, which ensures the reliability of configuration code, and deploys the changed application."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"workflow",src:a(74559).Z,width:"2594",height:"1364"})),(0,i.kt)("p",null,"The workflow to deploy an application is shown above, which includes the following jobs:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Get changed project and stack"),(0,i.kt)("li",{parentName:"ul"},"Check project and stack structure"),(0,i.kt)("li",{parentName:"ul"},"Test code correctness"),(0,i.kt)("li",{parentName:"ul"},"Preview changed stack"),(0,i.kt)("li",{parentName:"ul"},"Apply changed stack")),(0,i.kt)("p",null,"These jobs ensure the security and efficiency of the application deployment. Next, this tutorial will introduce the usage and function of these jobs. To show how they work more visually, updating port configuration in file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k")," of ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/service-multi-stack"},(0,i.kt)("em",{parentName:"a"},"service-multi-stack")),' (referred to "the example" in the below) is given as an example.'),(0,i.kt)("h2",{id:"get-changed-project-and-stack"},"Get Changed Project and Stack"),(0,i.kt)("p",null,"As Kusion organizes code by project and stack, to deploy the affected applications, analyze the changed project and stack is the first step."),(0,i.kt)("p",null,"The job, ",(0,i.kt)("strong",{parentName:"p"},"get-changed-project-stack")," perfectly accomplish the analysis. The main steps are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Obtain the list of changed files through ",(0,i.kt)("inlineCode",{parentName:"li"},"git diff"),";"),(0,i.kt)("li",{parentName:"ul"},"Based on the changed file list, obtain the changed projects and stacks which are indicated by ",(0,i.kt)("inlineCode",{parentName:"li"},"project.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"stack.yaml")," respectively.")),(0,i.kt)("p",null,"The example changes the file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k"),", where the affected project is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack"),", and the stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". Delightfully, the result, which is shown below, meets our expectation."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"changed-project-stack",src:a(15203).Z,width:"2248",height:"1104"})),(0,i.kt)("h2",{id:"check-project-and-stack-structure"},"Check Project and Stack Structure"),(0,i.kt)("p",null,"The job ",(0,i.kt)("strong",{parentName:"p"},"check-structure")," guarantees the structure legality of the changed project and stack, so that Kusion CLI tools can be used correctly. The check items are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in project.yaml;"),(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in stack.yaml.")),(0,i.kt)("p",null,"The success of structure-check means the correctness of structure. A ",(0,i.kt)("a",{parentName:"p",href:"https://docs.pytest.org/en/7.3.x/"},"pytest")," report ",(0,i.kt)("inlineCode",{parentName:"p"},"check-structure-report")," is also generated, and you can get it from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/managing-workflow-runs/downloading-workflow-artifacts"},"GithHub Actions Artifacts")," ."),(0,i.kt)("p",null,"The example passes the directory structure verification. It is clear from the report that the changed project and stack have get checked, and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n \n\n')),(0,i.kt)("h2",{id:"test-code-correctness"},"Test Code Correctness"),(0,i.kt)("p",null,"Besides a rightful structure, the code must have correct syntax and semantics, and the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," ensures the correctness. ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," get executed on the changed stacks. If succeeded, there are no syntax errors; or the configuration code is illegal, and the following application deployment will fail."),(0,i.kt)("p",null,"In this job, not only the correctness of AppConfiguration is checked, but also the workspace configuration. Hence, you should prepare workspace configuration in advance. Now, the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," supports you put workspace configuration files under directory ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces")," with file name's prefix the same as the workspace name and suffix ",(0,i.kt)("inlineCode",{parentName:"p"},".yaml"),". For example, if you have two workspaces named ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"prod"),", you should provide files ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/dev.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/prod.yaml")," with corresponding workspace configuration."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"The jobs preview and apply also ask for the workspace configuration files."),(0,i.kt)("p",{parentName:"admonition"},"Putting AppConfiguration and workspace configuration in one repository seems not a good idea. Doing this is to give a simple illustration. You can change it in your real production practice, and you can get more information of ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/app-configuration"},"AppConfiguration")," and ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspace")," here.")),(0,i.kt)("p",null,"The report whose name is ",(0,i.kt)("inlineCode",{parentName:"p"},"test-correctness-report")," get generated."),(0,i.kt)("p",null,"The example passes the code correctness test. The report shows that the tested stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n\n')),(0,i.kt)("h2",{id:"preview-changed-stack"},"Preview Changed Stack"),(0,i.kt)("p",null,"After passing the above jobs, security of the configuration change is guaranteed, and it's time to deploy your application. Before applying the change to the real infrastructure, it's necessary to get the expected result of the application deployment. The job ",(0,i.kt)("strong",{parentName:"p"},"preview")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion preview")," to get the expected change result, the result is uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"preview-report"),". If the result meets your requirement, you can go to the next job and deploy the application."),(0,i.kt)("p",null,"The example changes stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". The following picture shows the preview result of ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", where the result is to create a Kubernetes Namespace, Service and Deployment if call ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack Create\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n")),(0,i.kt)("h2",{id:"apply-changed-stack"},"Apply Changed Stack"),(0,i.kt)("p",null,"Finally, the last step is arrived, i.e. deploy application. The job ",(0,i.kt)("strong",{parentName:"p"},"apply")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply")," to apply the configuration change to the real infrastructure. If the job succeeded, the result will be uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"apply-report"),"."),(0,i.kt)("p",null,"For the stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod")," in the example, a Kubernetes Namespace, Service and Deployment get created, which is consistent with the preview result."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack UnChanged\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n\nStart applying diffs ...\n \nSUCCESS: UnChanged v1:Namespace:service-multi-stack, skip \nSUCCESS: Create v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public success \nSUCCESS: Create apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver success\n\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"summary"},"Summary"),(0,i.kt)("p",null,"This tutorial demonstrates how Kusion integrates with GitHub Actions to deploy an application. By structure check, correctness test, preview and apply, Kusion with GitHub Actions enables you deploy application efficiently and securely."))}u.isMDXComponent=!0},15203:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-changed-project-stack-de4c7df77236ad9eeb758f1f9e2af703.png"},74559:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/workflow-052aa326816199187357363891109493.png"}}]); \ No newline at end of file diff --git a/assets/js/b3471d8e.746a2f4c.js b/assets/js/b3471d8e.746a2f4c.js deleted file mode 100644 index 196a6b5cd41..00000000000 --- a/assets/js/b3471d8e.746a2f4c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3229],{3905:(e,n,t)=>{t.d(n,{Zo:()=>d,kt:()=>u});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function l(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=a.createContext({}),s=function(e){var n=a.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d=function(e){var n=s(e.components);return a.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),m=s(t),u=o,f=m["".concat(p,".").concat(u)]||m[u]||c[u]||i;return t?a.createElement(f,l(l({ref:n},d),{},{components:t})):a.createElement(f,l({ref:n},d))}));function u(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,l=new Array(i);l[0]=m;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r.mdxType="string"==typeof e?e:o,l[1]=r;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>i,metadata:()=>r,toc:()=>s});var a=t(87462),o=(t(67294),t(3905));const i={sidebar_position:4},l="PodDecoration",r={unversionedId:"operating/manuals/poddecoration",id:"operating/manuals/poddecoration",title:"PodDecoration",description:"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.",source:"@site/docs/operating/manuals/poddecoration.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/poddecoration",permalink:"/docs/next/operating/manuals/poddecoration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/poddecoration.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"operating",previous:{title:"PodTransitionRule",permalink:"/docs/next/operating/manuals/podtransitionrule"}},p={},s=[{value:"Create CollaSet",id:"create-collaset",level:2},{value:"Create PodDecoration",id:"create-poddecoration",level:2},{value:"Update PodDecoration",id:"update-poddecoration",level:2},{value:"Rolling update v1",id:"rolling-update-v1",level:3},{value:"Rolling update v1 -> v2",id:"rolling-update-v1---v2",level:3},{value:"Injection",id:"injection",level:2},{value:"Metadata",id:"metadata",level:3},{value:"Primary Container",id:"primary-container",level:3},{value:"Sidecar Container",id:"sidecar-container",level:3},{value:"InitContainer",id:"initcontainer",level:3},{value:"Upgrade strategy",id:"upgrade-strategy",level:2}],d={toc:s};function c(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"poddecoration"},"PodDecoration"),(0,o.kt)("p",null,"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria. "),(0,o.kt)("p",null,"PodDecoration not only allows injecting sidecar containers to Pods but also enables modifying existing container configurations, metadata, and scheduling parameters etc.\nThe PodDecoration controller does not control the upgrade of Pods. The actual upgrade process is fully controlled by the CollaSet controller. This means that the injection upgrade of PodDecoration can also be performed ",(0,o.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible"),"."),(0,o.kt)("p",null,"About ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/operating/manuals/collaset"},"CollaSet"),"."),(0,o.kt)("h1",{id:"example"},"Example"),(0,o.kt)("h2",{id:"create-collaset"},"Create CollaSet"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# collaset.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: foo\n namespace: default\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: foo\n")),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"collaset.yaml")," to create three pods under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," management."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f collaset.yaml\ncollaset.apps.kusionstack.io/foo created\n\n$ kubectl get cls\nNAME DESIRED CURRENT AVAILABLE UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\nfoo 3 3 3 3 3 3 foo-7bdb974bc7 foo-7bdb974bc7 7s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2wnnf 1/1 Running 0 41s\nfoo-hqpx7 1/1 Running 0 41s\nfoo-mqt48 1/1 Running 0 41s\n")),(0,o.kt)("h2",{id:"create-poddecoration"},"Create PodDecoration"),(0,o.kt)("p",null,"The following ",(0,o.kt)("inlineCode",{parentName:"p"},"poddecoration.yaml")," file describes a PodDecoration, which selects the pod under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," and injects the content in ",(0,o.kt)("inlineCode",{parentName:"p"},"template")," into the pod with ",(0,o.kt)("inlineCode",{parentName:"p"},"instance-id=0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nmetadata:\n name: sample-pd\nspec:\n selector: # selected pod range in which PodDecoration takes effect\n matchLabels:\n app: foo\n updateStrategy:\n rollingUpdate:\n selector: # select pod to upgrade in effect range\n matchLabels:\n collaset.kusionstack.io/instance-id: "0"\n template:\n metadata:\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v1"\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n command: ["sleep", "2h"]\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n')),(0,o.kt)("p",null,"Create PodDecoration ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to upgrade selected pod "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f poddecoration.yaml\npoddecoration.apps.kusionstack.io/sample-pd created\n")),(0,o.kt)("p",null,"The status of PodDecoration is updated, and one pod is injected with sidecar through recreate."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 1 1 1 sample-pd-9465f4c84 20s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 15s\nfoo-2wnnf 1/1 Running 0 2m\nfoo-hqpx7 1/1 Running 0 2m\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-2wnnf\n escaped: true\n - name: foo-hqpx7\n escaped: true\n matchedPods: 3\n injectedPods: 1\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h2",{id:"update-poddecoration"},"Update PodDecoration"),(0,o.kt)("h3",{id:"rolling-update-v1"},"Rolling update v1"),(0,o.kt)("p",null,"Edit ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to expand the upgrade scope."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Edit updateStrategy to select instance-id in [0, 1, 2]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector: \n matchExpressions:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n - "1" \n - "2" \n template:\n ...\n')),(0,o.kt)("p",null,"All pods updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 3 3 sample-pd-9465f4c84 sample-pd-9465f4c84 3m\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 3m\nfoo-lftw8 2/2 Running 0 8s\nfoo-n57rr 2/2 Running 0 8s\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n currentRevision: sample-pd-9465f4c84\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 3\n updatedReadyPods: 3\n updatedAvailablePods: 3\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h3",{id:"rolling-update-v1---v2"},"Rolling update v1 -> v2"),(0,o.kt)("p",null,"Update ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd"),"'s sidecar container image and ",(0,o.kt)("inlineCode",{parentName:"p"},"updateStrategy"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Update sidecar-a\'s image with ubuntu:22.10\n# Edit updateStrategy to select instance-id in [0]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n template:\n ...\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.10\n ...\n')),(0,o.kt)("p",null,"Pod ",(0,o.kt)("inlineCode",{parentName:"p"},"foo-2gnnl")," in-place upgrade sidecar container image."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 1 1 sample-pd-9465f4c84 sample-pd-8697d4bf8c 6min\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 1 (12s ago) 6m\nfoo-lftw8 2/2 Running 0 3min\nfoo-n57rr 2/2 Running 0 3min\n\n$ kubectl get pod foo-2gnnl -o yaml | grep "image: ubuntu"\n image: ubuntu:22.10\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-8697d4bf8c\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-8697d4bf8c\n')),(0,o.kt)("h1",{id:"features"},"Features"),(0,o.kt)("h2",{id:"injection"},"Injection"),(0,o.kt)("h3",{id:"metadata"},"Metadata"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n metadata:\n - patchPolicy: MergePatchJson\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"sample-pd","version":"v2"}]\'\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-name: sample-pd\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"patchPolicy")," is the injected policy, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Retain"),": The original value of annotations and labels will be retained."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Overwrite"),": The value of annotations and labels corresponding to the existing key will be overwritten."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MergePatchJson"),": It only takes effect for annotation. If the key does not exist, the value will be written directly. Otherwise, the json value will be merged.")),(0,o.kt)("p",null,"For example\uff1a"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# Old pod metadata\nmetadata:\n labels:\n custom.io/sidecar-version: "v1"\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}]\'\n\n# After metadata injected\nmetadata:\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-type: sample-pd\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}, {"name":"sample-pd","version":"v2"}]\'\n')),(0,o.kt)("h3",{id:"primary-container"},"Primary Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n primaryContainers:\n - targetPolicy: ByName\n name: foo\n image: foo:v2\n env: \n - name: APP_NAME\n value: foo\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n")),(0,o.kt)("p",null,"Injection into the primary containers only supports limited fields: ",(0,o.kt)("inlineCode",{parentName:"p"},"image"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"env")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"volumeMounts"),"."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"targetPolicy")," indicates which existed container these configuration should inject into, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ByName"),": Only inject containers matching ",(0,o.kt)("inlineCode",{parentName:"li"},"name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"All"),": Inject all primary containers."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"First"),": Inject into first primary container."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Last"),": Inject into last primary container.")),(0,o.kt)("h3",{id:"sidecar-container"},"Sidecar Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n containers:\n - injectPolicy: AfterPrimaryContainer # Container injected policy, AfterPrimaryContainer or BeforePrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n ...\n")),(0,o.kt)("p",null,"Inject a new sidecar container. Optional, it can be placed in front or behind the primary container."),(0,o.kt)("h3",{id:"initcontainer"},"InitContainer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n initContainers:\n - name: init\n image: custom-init-image:v1\n ...\n")),(0,o.kt)("h2",{id:"upgrade-strategy"},"Upgrade strategy"),(0,o.kt)("p",null,"Coming soon..."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b3471d8e.ad00d781.js b/assets/js/b3471d8e.ad00d781.js new file mode 100644 index 00000000000..4558edc4acd --- /dev/null +++ b/assets/js/b3471d8e.ad00d781.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3229],{3905:(e,n,t)=>{t.d(n,{Zo:()=>d,kt:()=>u});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function l(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=a.createContext({}),s=function(e){var n=a.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d=function(e){var n=s(e.components);return a.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),m=s(t),u=o,f=m["".concat(p,".").concat(u)]||m[u]||c[u]||i;return t?a.createElement(f,l(l({ref:n},d),{},{components:t})):a.createElement(f,l({ref:n},d))}));function u(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,l=new Array(i);l[0]=m;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r.mdxType="string"==typeof e?e:o,l[1]=r;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>i,metadata:()=>r,toc:()=>s});var a=t(87462),o=(t(67294),t(3905));const i={sidebar_position:4},l="PodDecoration",r={unversionedId:"operating/manuals/poddecoration",id:"operating/manuals/poddecoration",title:"PodDecoration",description:"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.",source:"@site/docs/operating/manuals/poddecoration.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/poddecoration",permalink:"/docs/next/operating/manuals/poddecoration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/poddecoration.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"operating",previous:{title:"PodTransitionRule",permalink:"/docs/next/operating/manuals/podtransitionrule"}},p={},s=[{value:"Create CollaSet",id:"create-collaset",level:2},{value:"Create PodDecoration",id:"create-poddecoration",level:2},{value:"Update PodDecoration",id:"update-poddecoration",level:2},{value:"Rolling update v1",id:"rolling-update-v1",level:3},{value:"Rolling update v1 -> v2",id:"rolling-update-v1---v2",level:3},{value:"Injection",id:"injection",level:2},{value:"Metadata",id:"metadata",level:3},{value:"Primary Container",id:"primary-container",level:3},{value:"Sidecar Container",id:"sidecar-container",level:3},{value:"InitContainer",id:"initcontainer",level:3},{value:"Upgrade strategy",id:"upgrade-strategy",level:2}],d={toc:s};function c(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,a.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"poddecoration"},"PodDecoration"),(0,o.kt)("p",null,"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria. "),(0,o.kt)("p",null,"PodDecoration not only allows injecting sidecar containers to Pods but also enables modifying existing container configurations, metadata, and scheduling parameters etc.\nThe PodDecoration controller does not control the upgrade of Pods. The actual upgrade process is fully controlled by the CollaSet controller. This means that the injection upgrade of PodDecoration can also be performed ",(0,o.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible"),"."),(0,o.kt)("p",null,"About ",(0,o.kt)("a",{parentName:"p",href:"/docs/next/operating/manuals/collaset"},"CollaSet"),"."),(0,o.kt)("h1",{id:"example"},"Example"),(0,o.kt)("h2",{id:"create-collaset"},"Create CollaSet"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# collaset.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: foo\n namespace: default\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: foo\n")),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"collaset.yaml")," to create three pods under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," management."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f collaset.yaml\ncollaset.apps.kusionstack.io/foo created\n\n$ kubectl get cls\nNAME DESIRED CURRENT AVAILABLE UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\nfoo 3 3 3 3 3 3 foo-7bdb974bc7 foo-7bdb974bc7 7s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2wnnf 1/1 Running 0 41s\nfoo-hqpx7 1/1 Running 0 41s\nfoo-mqt48 1/1 Running 0 41s\n")),(0,o.kt)("h2",{id:"create-poddecoration"},"Create PodDecoration"),(0,o.kt)("p",null,"The following ",(0,o.kt)("inlineCode",{parentName:"p"},"poddecoration.yaml")," file describes a PodDecoration, which selects the pod under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," and injects the content in ",(0,o.kt)("inlineCode",{parentName:"p"},"template")," into the pod with ",(0,o.kt)("inlineCode",{parentName:"p"},"instance-id=0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nmetadata:\n name: sample-pd\nspec:\n selector: # selected pod range in which PodDecoration takes effect\n matchLabels:\n app: foo\n updateStrategy:\n rollingUpdate:\n selector: # select pod to upgrade in effect range\n matchLabels:\n collaset.kusionstack.io/instance-id: "0"\n template:\n metadata:\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v1"\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n command: ["sleep", "2h"]\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n')),(0,o.kt)("p",null,"Create PodDecoration ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to upgrade selected pod "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f poddecoration.yaml\npoddecoration.apps.kusionstack.io/sample-pd created\n")),(0,o.kt)("p",null,"The status of PodDecoration is updated, and one pod is injected with sidecar through recreate."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 1 1 1 sample-pd-9465f4c84 20s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 15s\nfoo-2wnnf 1/1 Running 0 2m\nfoo-hqpx7 1/1 Running 0 2m\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-2wnnf\n escaped: true\n - name: foo-hqpx7\n escaped: true\n matchedPods: 3\n injectedPods: 1\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h2",{id:"update-poddecoration"},"Update PodDecoration"),(0,o.kt)("h3",{id:"rolling-update-v1"},"Rolling update v1"),(0,o.kt)("p",null,"Edit ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to expand the upgrade scope."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Edit updateStrategy to select instance-id in [0, 1, 2]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector: \n matchExpressions:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n - "1" \n - "2" \n template:\n ...\n')),(0,o.kt)("p",null,"All pods updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 3 3 sample-pd-9465f4c84 sample-pd-9465f4c84 3m\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 3m\nfoo-lftw8 2/2 Running 0 8s\nfoo-n57rr 2/2 Running 0 8s\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n currentRevision: sample-pd-9465f4c84\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 3\n updatedReadyPods: 3\n updatedAvailablePods: 3\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h3",{id:"rolling-update-v1---v2"},"Rolling update v1 -> v2"),(0,o.kt)("p",null,"Update ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd"),"'s sidecar container image and ",(0,o.kt)("inlineCode",{parentName:"p"},"updateStrategy"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Update sidecar-a\'s image with ubuntu:22.10\n# Edit updateStrategy to select instance-id in [0]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n template:\n ...\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.10\n ...\n')),(0,o.kt)("p",null,"Pod ",(0,o.kt)("inlineCode",{parentName:"p"},"foo-2gnnl")," in-place upgrade sidecar container image."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 1 1 sample-pd-9465f4c84 sample-pd-8697d4bf8c 6min\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 1 (12s ago) 6m\nfoo-lftw8 2/2 Running 0 3min\nfoo-n57rr 2/2 Running 0 3min\n\n$ kubectl get pod foo-2gnnl -o yaml | grep "image: ubuntu"\n image: ubuntu:22.10\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-8697d4bf8c\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-8697d4bf8c\n')),(0,o.kt)("h1",{id:"features"},"Features"),(0,o.kt)("h2",{id:"injection"},"Injection"),(0,o.kt)("h3",{id:"metadata"},"Metadata"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n metadata:\n - patchPolicy: MergePatchJson\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"sample-pd","version":"v2"}]\'\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-name: sample-pd\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"patchPolicy")," is the injected policy, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Retain"),": The original value of annotations and labels will be retained."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Overwrite"),": The value of annotations and labels corresponding to the existing key will be overwritten."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MergePatchJson"),": It only takes effect for annotation. If the key does not exist, the value will be written directly. Otherwise, the json value will be merged.")),(0,o.kt)("p",null,"For example\uff1a"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# Old pod metadata\nmetadata:\n labels:\n custom.io/sidecar-version: "v1"\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}]\'\n\n# After metadata injected\nmetadata:\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-type: sample-pd\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}, {"name":"sample-pd","version":"v2"}]\'\n')),(0,o.kt)("h3",{id:"primary-container"},"Primary Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n primaryContainers:\n - targetPolicy: ByName\n name: foo\n image: foo:v2\n env: \n - name: APP_NAME\n value: foo\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n")),(0,o.kt)("p",null,"Injection into the primary containers only supports limited fields: ",(0,o.kt)("inlineCode",{parentName:"p"},"image"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"env")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"volumeMounts"),"."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"targetPolicy")," indicates which existed container these configuration should inject into, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ByName"),": Only inject containers matching ",(0,o.kt)("inlineCode",{parentName:"li"},"name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"All"),": Inject all primary containers."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"First"),": Inject into first primary container."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Last"),": Inject into last primary container.")),(0,o.kt)("h3",{id:"sidecar-container"},"Sidecar Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n containers:\n - injectPolicy: AfterPrimaryContainer # Container injected policy, AfterPrimaryContainer or BeforePrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n ...\n")),(0,o.kt)("p",null,"Inject a new sidecar container. Optional, it can be placed in front or behind the primary container."),(0,o.kt)("h3",{id:"initcontainer"},"InitContainer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n initContainers:\n - name: init\n image: custom-init-image:v1\n ...\n")),(0,o.kt)("h2",{id:"upgrade-strategy"},"Upgrade strategy"),(0,o.kt)("p",null,"Coming soon..."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b34bf6de.6ed79029.js b/assets/js/b34bf6de.6ed79029.js new file mode 100644 index 00000000000..0d0d55c7913 --- /dev/null +++ b/assets/js/b34bf6de.6ed79029.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[851],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>m});var t=a(67294);function i(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function o(e){for(var n=1;n=0||(i[a]=e[a]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=t.createContext({}),p=function(e){var n=t.useContext(s),a=n;return e&&(a="function"==typeof e?e(n):o(o({},n),e)),a},d=function(e){var n=p(e.components);return t.createElement(s.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(a),m=i,h=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return a?t.createElement(h,o(o({ref:n},d),{},{components:a})):t.createElement(h,o({ref:n},d))}));function m(e,n){var a=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{a.r(n),a.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),i=(a(67294),a(3905));const r={sidebar_position:3},o="PodTransitionRule",l={unversionedId:"operating/manuals/podtransitionrule",id:"operating/manuals/podtransitionrule",title:"PodTransitionRule",description:"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.",source:"@site/docs/operating/manuals/podtransitionrule.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/podtransitionrule",permalink:"/docs/next/operating/manuals/podtransitionrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/podtransitionrule.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"operating",previous:{title:"ResourceConsist",permalink:"/docs/next/operating/manuals/resourceconsist"},next:{title:"PodDecoration",permalink:"/docs/next/operating/manuals/poddecoration"}},s={},p=[{value:"Rule Definition",id:"rule-definition",level:2},{value:"Available Policy",id:"available-policy",level:3},{value:"maxUnavailable",id:"maxunavailable",level:4},{value:"minAvailable",id:"minavailable",level:4},{value:"Label Check",id:"label-check",level:3},{value:"Webhook",id:"webhook",level:3}],d={toc:p};function c(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"podtransitionrule"},"PodTransitionRule"),(0,i.kt)("p",null,"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pending")," phase, moving through ",(0,i.kt)("inlineCode",{parentName:"p"},"Running")," if at least one of its primary containers starts ",(0,i.kt)("inlineCode",{parentName:"p"},"OK"),", and then through either the ",(0,i.kt)("inlineCode",{parentName:"p"},"Succeeded")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"Failed")," phases depending on whether any container in the Pod terminated in failure."),(0,i.kt)("p",null,"These phase definitions can fulfill basic Pod change scenarios, but it are ambiguous.\nActually, before pod upgrade or ready, it is necessary to have some check mechanisms in place to ensure the safety of pod changes. Fortunately, ",(0,i.kt)("a",{parentName:"p",href:"/docs/next/operating/concepts/podopslifecycle"},"PodOpsLifecycle")," extends and supports some check stages: ",(0,i.kt)("inlineCode",{parentName:"p"},"PreCheck")," before pod upgrade and ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," before pod ready."),(0,i.kt)("p",null,"To ensure a more fine-grained and controlled change process for Pods, we introduce custom rules or perform additional tasks as prerequisites for state transitions before the desired state of a Pod is achieved. Similar to the Pod ",(0,i.kt)("inlineCode",{parentName:"p"},"readinessGates"),", where certain conditions must be met for a Pod to be considered readiness. For example, we consider a Pod ready for the ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," phase only if it has specific labels. For this purpose, we introduce the ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," as a prerequisite for the state transition of a Pod."),(0,i.kt)("h2",{id:"rule-definition"},"Rule Definition"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," to define a set of transition rules for your workload pods.\nEach rule will be executed at the corresponding stage, and it will be blocked if the conditions are not met."),(0,i.kt)("p",null,"Here is an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n name: podtransitionrule-sample\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n - stage: PreCheck # stages are supported by PodOpsLifecycle. Defaults to PreCheck.\n labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n name: labelCheck\n - stage: PostCheck\n webhook:\n clientConfig:\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id # URL parameter key to carry trace ID when fetching result. Defaults to task-id in form 'QueryUrl=URL?rawQueryKey='\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef: \n fieldPath: status.podIP\n name: webhookCheck\n selector: # select pods in effect\n matchLabels:\n app: foo\n")),(0,i.kt)("h3",{id:"available-policy"},"Available Policy"),(0,i.kt)("p",null,"An ",(0,i.kt)("inlineCode",{parentName:"p"},"availablePolicy")," rule defines the availability strategy during the Pod update process."),(0,i.kt)("h4",{id:"maxunavailable"},"maxUnavailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n maxUnavailable: \n value: 50% # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailableValue")," is the maximum number of pods that can be unavailable during the update.\nValue can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).\nAbsolute number is calculated from percentage by rounding down.\nThis can not be 0."),(0,i.kt)("h4",{id:"minavailable"},"minAvailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n minAvailable:\n value: 5 # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"minAvailableValue")," is the minimum number of pods that should be available during the update."),(0,i.kt)("h3",{id:"label-check"},"Label Check"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"labelCheck")," rule is used to check if labels are satisfied.\nYou can define your own labels as change check conditions and modify the labels according to your needs."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n matchExpressions:\n - key: app.custom/forbidden \n operator: DoesNotExist\n")),(0,i.kt)("h3",{id:"webhook"},"Webhook"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"webhook")," is an HTTP callback, based on which a external web application can determine whether a pod can pass this check."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"An HTTP POST occurs first when pods entries the configured stage which defaults PreCheck."),(0,i.kt)("li",{parentName:"ul"},"If ",(0,i.kt)("inlineCode",{parentName:"li"},"poll")," is provided, this rule then keeps calling polling url to fetch a long running job result. This job can be located by ",(0,i.kt)("inlineCode",{parentName:"li"},"task-id")," returned from the response of the first request. ")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"webhook:\n clientConfig: # custom server config\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol without poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": false,\n "message": "msg", \n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating all pods approved or not. If it's ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", the ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," field can be used to approve partial pods."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol with poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "poll": true, // required to indicate polling calls is necessary\n "taskId": , // required to to fetch polling result\n "message": "msg"\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating whether the first request is success or not. If true and field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true")," (or field ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),"), PodTransisionRule will then begin to keep calling poll URL to fetch process result.\nField ",(0,i.kt)("inlineCode",{parentName:"p"},"taskId")," is required for polling. "),(0,i.kt)("p",null,"The request for polling is GET method and in form of ",(0,i.kt)("inlineCode",{parentName:"p"},"QueryUrl=URL?task-id="),". The parameter key in this URL defaults ",(0,i.kt)("inlineCode",{parentName:"p"},"task-id"),", if using ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in above response. It would be ",(0,i.kt)("inlineCode",{parentName:"p"},"trace-id")," if using ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in above response.\nUsers can also indicate the key by field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll.rawQueryKey"),"."),(0,i.kt)("p",null,"The response from polling call is expected like following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "message": "msg",\n "finished": false,\n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"success")," is supposed to be true, if there is no error. If all pods is approved, ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," should be ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),".\nIf ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," can be used to allow partial pods to be approved."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b34bf6de.838dcca3.js b/assets/js/b34bf6de.838dcca3.js deleted file mode 100644 index 05ac2c0ed9b..00000000000 --- a/assets/js/b34bf6de.838dcca3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[851],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>m});var t=a(67294);function i(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function o(e){for(var n=1;n=0||(i[a]=e[a]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=t.createContext({}),p=function(e){var n=t.useContext(s),a=n;return e&&(a="function"==typeof e?e(n):o(o({},n),e)),a},d=function(e){var n=p(e.components);return t.createElement(s.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(a),m=i,h=u["".concat(s,".").concat(m)]||u[m]||c[m]||r;return a?t.createElement(h,o(o({ref:n},d),{},{components:a})):t.createElement(h,o({ref:n},d))}));function m(e,n){var a=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{a.r(n),a.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),i=(a(67294),a(3905));const r={sidebar_position:3},o="PodTransitionRule",l={unversionedId:"operating/manuals/podtransitionrule",id:"operating/manuals/podtransitionrule",title:"PodTransitionRule",description:"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the Pending phase, moving through Running if at least one of its primary containers starts OK, and then through either the Succeeded or Failed phases depending on whether any container in the Pod terminated in failure.",source:"@site/docs/operating/manuals/podtransitionrule.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/podtransitionrule",permalink:"/docs/next/operating/manuals/podtransitionrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/podtransitionrule.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"operating",previous:{title:"ResourceConsist",permalink:"/docs/next/operating/manuals/resourceconsist"},next:{title:"PodDecoration",permalink:"/docs/next/operating/manuals/poddecoration"}},s={},p=[{value:"Rule Definition",id:"rule-definition",level:2},{value:"Available Policy",id:"available-policy",level:3},{value:"maxUnavailable",id:"maxunavailable",level:4},{value:"minAvailable",id:"minavailable",level:4},{value:"Label Check",id:"label-check",level:3},{value:"Webhook",id:"webhook",level:3}],d={toc:p};function c(e){let{components:n,...a}=e;return(0,i.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"podtransitionrule"},"PodTransitionRule"),(0,i.kt)("p",null,"In normal pod lifecycle, some phases are defined. For example, K8s Pods follow a defined lifecycle\uff0cstarting in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pending")," phase, moving through ",(0,i.kt)("inlineCode",{parentName:"p"},"Running")," if at least one of its primary containers starts ",(0,i.kt)("inlineCode",{parentName:"p"},"OK"),", and then through either the ",(0,i.kt)("inlineCode",{parentName:"p"},"Succeeded")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"Failed")," phases depending on whether any container in the Pod terminated in failure."),(0,i.kt)("p",null,"These phase definitions can fulfill basic Pod change scenarios, but it are ambiguous.\nActually, before pod upgrade or ready, it is necessary to have some check mechanisms in place to ensure the safety of pod changes. Fortunately, ",(0,i.kt)("a",{parentName:"p",href:"/docs/next/operating/concepts/podopslifecycle"},"PodOpsLifecycle")," extends and supports some check stages: ",(0,i.kt)("inlineCode",{parentName:"p"},"PreCheck")," before pod upgrade and ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," before pod ready."),(0,i.kt)("p",null,"To ensure a more fine-grained and controlled change process for Pods, we introduce custom rules or perform additional tasks as prerequisites for state transitions before the desired state of a Pod is achieved. Similar to the Pod ",(0,i.kt)("inlineCode",{parentName:"p"},"readinessGates"),", where certain conditions must be met for a Pod to be considered readiness. For example, we consider a Pod ready for the ",(0,i.kt)("inlineCode",{parentName:"p"},"PostCheck")," phase only if it has specific labels. For this purpose, we introduce the ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," as a prerequisite for the state transition of a Pod."),(0,i.kt)("h2",{id:"rule-definition"},"Rule Definition"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"PodTransitionRule")," to define a set of transition rules for your workload pods.\nEach rule will be executed at the corresponding stage, and it will be blocked if the conditions are not met."),(0,i.kt)("p",null,"Here is an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n name: podtransitionrule-sample\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n - stage: PreCheck # stages are supported by PodOpsLifecycle. Defaults to PreCheck.\n labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n name: labelCheck\n - stage: PostCheck\n webhook:\n clientConfig:\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id # URL parameter key to carry trace ID when fetching result. Defaults to task-id in form 'QueryUrl=URL?rawQueryKey='\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef: \n fieldPath: status.podIP\n name: webhookCheck\n selector: # select pods in effect\n matchLabels:\n app: foo\n")),(0,i.kt)("h3",{id:"available-policy"},"Available Policy"),(0,i.kt)("p",null,"An ",(0,i.kt)("inlineCode",{parentName:"p"},"availablePolicy")," rule defines the availability strategy during the Pod update process."),(0,i.kt)("h4",{id:"maxunavailable"},"maxUnavailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n maxUnavailable: \n value: 50% # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailableValue")," is the maximum number of pods that can be unavailable during the update.\nValue can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).\nAbsolute number is calculated from percentage by rounding down.\nThis can not be 0."),(0,i.kt)("h4",{id:"minavailable"},"minAvailable"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"availablePolicy:\n minAvailable:\n value: 5 # int or string \n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"minAvailableValue")," is the minimum number of pods that should be available during the update."),(0,i.kt)("h3",{id:"label-check"},"Label Check"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"labelCheck")," rule is used to check if labels are satisfied.\nYou can define your own labels as change check conditions and modify the labels according to your needs."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"labelCheck:\n requires:\n matchLabels:\n app.custom/ready: 'true' \n matchExpressions:\n - key: app.custom/forbidden \n operator: DoesNotExist\n")),(0,i.kt)("h3",{id:"webhook"},"Webhook"),(0,i.kt)("p",null,"A ",(0,i.kt)("inlineCode",{parentName:"p"},"webhook")," is an HTTP callback, based on which a external web application can determine whether a pod can pass this check."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"An HTTP POST occurs first when pods entries the configured stage which defaults PreCheck."),(0,i.kt)("li",{parentName:"ul"},"If ",(0,i.kt)("inlineCode",{parentName:"li"},"poll")," is provided, this rule then keeps calling polling url to fetch a long running job result. This job can be located by ",(0,i.kt)("inlineCode",{parentName:"li"},"task-id")," returned from the response of the first request. ")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"webhook:\n clientConfig: # custom server config\n url: https://1.1.1.1:8089/post-stop\n caBundle: Cg==\n poll:\n url: http://1.1.1.1:8089/fetch-result\n rawQueryKey: task-id\n intervalSeconds: 5\n timeoutSeconds: 60\n failurePolicy: Fail\n parameters:\n - key: podIP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol without poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": false,\n "message": "msg", \n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating all pods approved or not. If it's ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", the ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," field can be used to approve partial pods."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Protocol with poll")),(0,i.kt)("p",null,"Request:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'// URL: https://1.1.1.1:8089/post-stop\n// Method: POST\n\n{ \n "traceId": "", // is generated by Operating, which can be used to track request\n "stage": "PreTrafficOff",\n "ruleName": "webhookCheck",\n "resources": [ // Information of Pods which are in this stage\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-a",\n "parameters": {\n "podIP": "1.0.0.1" // Customized information users can indicate from rule paramter\n }\n },\n {\n "apiVersion": "v1",\n "kind": "Pod",\n "name": "pod-b",\n "parameters": {\n "podIP": "1.0.0.2"\n }\n }\n ]\n}\n')),(0,i.kt)("p",null,"Response:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "poll": true, // required to indicate polling calls is necessary\n "taskId": , // required to to fetch polling result\n "message": "msg"\n}\n')),(0,i.kt)("p",null,"Response ",(0,i.kt)("inlineCode",{parentName:"p"},"success")," indicating whether the first request is success or not. If true and field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true")," (or field ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in response is ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),"), PodTransisionRule will then begin to keep calling poll URL to fetch process result.\nField ",(0,i.kt)("inlineCode",{parentName:"p"},"taskId")," is required for polling. "),(0,i.kt)("p",null,"The request for polling is GET method and in form of ",(0,i.kt)("inlineCode",{parentName:"p"},"QueryUrl=URL?task-id="),". The parameter key in this URL defaults ",(0,i.kt)("inlineCode",{parentName:"p"},"task-id"),", if using ",(0,i.kt)("inlineCode",{parentName:"p"},"poll")," in above response. It would be ",(0,i.kt)("inlineCode",{parentName:"p"},"trace-id")," if using ",(0,i.kt)("inlineCode",{parentName:"p"},"async")," in above response.\nUsers can also indicate the key by field ",(0,i.kt)("inlineCode",{parentName:"p"},"poll.rawQueryKey"),"."),(0,i.kt)("p",null,"The response from polling call is expected like following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "success": true,\n "message": "msg",\n "finished": false,\n "finishedNames": ["pod-a", "pod-b"]\n}\n')),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"success")," is supposed to be true, if there is no error. If all pods is approved, ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," should be ",(0,i.kt)("inlineCode",{parentName:"p"},"true"),".\nIf ",(0,i.kt)("inlineCode",{parentName:"p"},"finished")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"false"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"finishedNames")," can be used to allow partial pods to be approved."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5ec8c180.cb041950.js b/assets/js/b44b4ce2.475485ff.js similarity index 75% rename from assets/js/5ec8c180.cb041950.js rename to assets/js/b44b4ce2.475485ff.js index a11a5b8b785..eea3928ec51 100644 --- a/assets/js/5ec8c180.cb041950.js +++ b/assets/js/b44b4ce2.475485ff.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8828],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="Service",o={unversionedId:"kusion/reference/model/catalog_models/workload/doc_service",id:"version-v0.9/kusion/reference/model/catalog_models/workload/doc_service",title:"Service",description:"Schemas",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_service.md",sourceDirName:"kusion/reference/model/catalog_models/workload",slug:"/kusion/reference/model/catalog_models/workload/doc_service",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_service.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Job",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job"},next:{title:"database",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Service",id:"schema-service",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3},{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes-9",level:3},{value:"Examples",id:"examples-9",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"service"},"Service"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-service"},"Service"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-port"},"Port"))))),(0,r.kt)("h2",{id:"schema-service"},"Schema Service"),(0,r.kt)("p",null,"Service is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),'is typically used for long-running web applications that should "never" go down, and handle',(0,r.kt)("br",null),"short-lived latency-sensitive web requests, or events."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"ports"),(0,r.kt)("br",null),"The list of ports of the Service should get exposed."),(0,r.kt)("td",{parentName:"tr",align:null},"[",(0,r.kt)("a",{parentName:"td",href:"#schema-port"},"network.Port"),"]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,r.kt)("br",null),"types, including Deployment and CollaSet."),(0,r.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nsvc = wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9090\n }\n ]\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')),(0,r.kt)("h2",{id:"schema-port"},"Schema Port"),(0,r.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,r.kt)("br",null),"get accessed."),(0,r.kt)("h3",{id:"attributes-9"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"port"),(0,r.kt)("br",null),"The exposed port of the Service."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"80"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"protocol"),(0,r.kt)("br",null),"The protocol to access the port."),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"public"),(0,r.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"False"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"targetPort"),(0,r.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-9"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1073],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>k});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),k=r,c=u["".concat(p,".").concat(k)]||u[k]||m[k]||l;return a?n.createElement(c,i(i({ref:e},d),{},{components:a})):n.createElement(c,i({ref:e},d))}));function k(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="service",o={unversionedId:"kusion/reference/modules/catalog-models/workload/service",id:"version-v0.10/kusion/reference/modules/catalog-models/workload/service",title:"service",description:"Schemas",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/service",permalink:"/docs/kusion/reference/modules/catalog-models/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/kusion/reference/modules/catalog-models/workload/job"},next:{title:"mysql",permalink:"/docs/kusion/reference/modules/workspace-configs/database/mysql"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Service",id:"schema-service",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3},{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes-9",level:3},{value:"Examples",id:"examples-9",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"service"},"service"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-service"},"Service"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-port"},"Port"))))),(0,r.kt)("h2",{id:"schema-service"},"Schema Service"),(0,r.kt)("p",null,"Service is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),'is typically used for long-running web applications that should "never" go down, and handle',(0,r.kt)("br",null),"short-lived latency-sensitive web requests, or events."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"ports"),(0,r.kt)("br",null),"The list of ports of the Service should get exposed."),(0,r.kt)("td",{parentName:"tr",align:null},"[",(0,r.kt)("a",{parentName:"td",href:"#schema-port"},"network.Port"),"]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,r.kt)("br",null),"types, including Deployment and CollaSet."),(0,r.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nsvc = wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9090\n }\n ]\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')),(0,r.kt)("h2",{id:"schema-port"},"Schema Port"),(0,r.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,r.kt)("br",null),"get accessed."),(0,r.kt)("h3",{id:"attributes-9"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"port"),(0,r.kt)("br",null),"The exposed port of the Service."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"80"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"protocol"),(0,r.kt)("br",null),"The protocol to access the port."),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"public"),(0,r.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"False"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"targetPort"),(0,r.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-9"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b44b4ce2.a0de6e32.js b/assets/js/b44b4ce2.a0de6e32.js deleted file mode 100644 index 1090f79d212..00000000000 --- a/assets/js/b44b4ce2.a0de6e32.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1073],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>k});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),k=r,c=u["".concat(p,".").concat(k)]||u[k]||m[k]||l;return a?n.createElement(c,i(i({ref:e},d),{},{components:a})):n.createElement(c,i({ref:e},d))}));function k(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="service",o={unversionedId:"kusion/reference/modules/catalog-models/workload/service",id:"version-v0.10/kusion/reference/modules/catalog-models/workload/service",title:"service",description:"Schemas",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/service",permalink:"/docs/kusion/reference/modules/catalog-models/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/kusion/reference/modules/catalog-models/workload/job"},next:{title:"mysql",permalink:"/docs/kusion/reference/modules/workspace-configs/database/mysql"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Service",id:"schema-service",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3},{value:"Schema Port",id:"schema-port",level:2},{value:"Attributes",id:"attributes-9",level:3},{value:"Examples",id:"examples-9",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"service"},"service"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-service"},"Service"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-port"},"Port"))))),(0,r.kt)("h2",{id:"schema-service"},"Schema Service"),(0,r.kt)("p",null,"Service is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),'is typically used for long-running web applications that should "never" go down, and handle',(0,r.kt)("br",null),"short-lived latency-sensitive web requests, or events."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"ports"),(0,r.kt)("br",null),"The list of ports of the Service should get exposed."),(0,r.kt)("td",{parentName:"tr",align:null},"[",(0,r.kt)("a",{parentName:"td",href:"#schema-port"},"network.Port"),"]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,r.kt)("br",null),"types, including Deployment and CollaSet."),(0,r.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'# Instantiate a long-running service and its image is "nginx:v1"\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nsvc = wl.Service {\n containers: {\n "nginx": c.Container {\n image: "nginx:v1"\n }\n }\n ports: [\n n.Port {\n port: 80\n public: True\n }\n n.Port {\n port: 9090\n }\n ]\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')),(0,r.kt)("h2",{id:"schema-port"},"Schema Port"),(0,r.kt)("p",null,"Port defines the exposed port of Service, which can be used to describe how the Service",(0,r.kt)("br",null),"get accessed."),(0,r.kt)("h3",{id:"attributes-9"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"port"),(0,r.kt)("br",null),"The exposed port of the Service."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"80"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"protocol"),(0,r.kt)("br",null),"The protocol to access the port."),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP" ',"|",' "UDP"'),(0,r.kt)("td",{parentName:"tr",align:null},'"TCP"'),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"public"),(0,r.kt)("br",null),"Public defines whether the port can be accessed through Internet."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"False"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"targetPort"),(0,r.kt)("br",null),"The backend container port. If empty, set it the same as the port."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-9"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.network as n\n\nport = n.Port {\n port: 80\n targetPort: 8080\n protocol: "TCP"\n public: True\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b46813dd.364c88b4.js b/assets/js/b46813dd.364c88b4.js deleted file mode 100644 index 57ebbe28891..00000000000 --- a/assets/js/b46813dd.364c88b4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1115],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=r.createContext({}),l=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=l(e.components);return r.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=i,g=d["".concat(p,".").concat(m)]||d[m]||u[m]||a;return t?r.createElement(g,o(o({ref:n},c),{},{components:t})):r.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=d;var s={};for(var p in n)hasOwnProperty.call(n,p)&&(s[p]=n[p]);s.originalType=e,s.mdxType="string"==typeof e?e:i,o[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=t(87462),i=(t(67294),t(3905));const a={},o="Configure Resource Specification",s={unversionedId:"kusion/user-guides/working-with-k8s/resource-spec",id:"version-v0.10/kusion/user-guides/working-with-k8s/resource-spec",title:"Configure Resource Specification",description:"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/resource-spec",permalink:"/docs/kusion/user-guides/working-with-k8s/resource-spec",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{},sidebar:"kusion",previous:{title:"Upgrade Image",permalink:"/docs/kusion/user-guides/working-with-k8s/image-upgrade"},next:{title:"Set up Operational Rules",permalink:"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules"}},p={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configure-resource-specification"},"Configure Resource Specification"),(0,i.kt)("p",null,"You can manage container-level resource specification in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"resources")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema)."),(0,i.kt)("p",null,"For the full ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"Update the resources value in ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.helloworld: {\n ...\n # before:\n # resources: {\n # "cpu": "500m"\n # "memory": "512M"\n # }\n # after: \n resources: {\n "cpu": "250m"\n "memory": "256Mi"\n }\n ...\n }\n}\n')),(0,i.kt)("p",null,"Everything else in ",(0,i.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated resources attributes (cpu:250m, memory:256Mi) as defined in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n resources:\n limits:\n cpu: 250m\n memory: 256Mi\n...\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b46813dd.a11fb422.js b/assets/js/b46813dd.a11fb422.js new file mode 100644 index 00000000000..0e10b552972 --- /dev/null +++ b/assets/js/b46813dd.a11fb422.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1115],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var i=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function o(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var p=i.createContext({}),l=function(e){var n=i.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=l(e.components);return i.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},d=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=r,g=d["".concat(p,".").concat(m)]||d[m]||u[m]||a;return t?i.createElement(g,o(o({ref:n},c),{},{components:t})):i.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,o=new Array(a);o[0]=d;var s={};for(var p in n)hasOwnProperty.call(n,p)&&(s[p]=n[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,o[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var i=t(87462),r=(t(67294),t(3905));const a={},o="Configure Resource Specification",s={unversionedId:"kusion/user-guides/working-with-k8s/resource-spec",id:"version-v0.10/kusion/user-guides/working-with-k8s/resource-spec",title:"Configure Resource Specification",description:"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/resource-spec",permalink:"/docs/kusion/user-guides/working-with-k8s/resource-spec",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{},sidebar:"kusion",previous:{title:"Upgrade Image",permalink:"/docs/kusion/user-guides/working-with-k8s/image-upgrade"},next:{title:"Set up Operational Rules",permalink:"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules"}},p={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,i.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-resource-specification"},"Configure Resource Specification"),(0,r.kt)("p",null,"You can manage container-level resource specification in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,r.kt)("inlineCode",{parentName:"p"},"resources")," field (under the ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema)."),(0,r.kt)("p",null,"For the full ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,r.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,r.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,r.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,r.kt)("h2",{id:"example"},"Example"),(0,r.kt)("p",null,"Update the resources value in ",(0,r.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.helloworld: {\n ...\n # before:\n # resources: {\n # "cpu": "500m"\n # "memory": "512M"\n # }\n # after: \n resources: {\n "cpu": "250m"\n "memory": "256Mi"\n }\n ...\n }\n}\n')),(0,r.kt)("p",null,"Everything else in ",(0,r.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,r.kt)("h2",{id:"applying"},"Applying"),(0,r.kt)("p",null,"Re-run steps in ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,r.kt)("h2",{id:"validation"},"Validation"),(0,r.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated resources attributes (cpu:250m, memory:256Mi) as defined in the container configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n resources:\n limits:\n cpu: 250m\n memory: 256Mi\n...\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b509c81b.aeea8285.js b/assets/js/b509c81b.aeea8285.js deleted file mode 100644 index 376e14844ce..00000000000 --- a/assets/js/b509c81b.aeea8285.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3618],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),d=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(i,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(k,l(l({ref:t},p),{},{components:n})):a.createElement(k,l({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:r,l[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const o={},l="postgres",s={unversionedId:"kusion/reference/modules/catalog-models/database/postgres",id:"version-v0.10/kusion/reference/modules/catalog-models/database/postgres",title:"postgres",description:"Schema PostgreSQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/postgres",permalink:"/docs/kusion/reference/modules/catalog-models/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/kusion/reference/modules/catalog-models/database/mysql"},next:{title:"common",permalink:"/docs/kusion/reference/modules/catalog-models/internal/common"}},i={},d=[{value:"Schema PostgreSQL",id:"schema-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"postgres"},"postgres"),(0,r.kt)("h2",{id:"schema-postgresql"},"Schema PostgreSQL"),(0,r.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed postgresql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the postgresql database is deployed locally or provided by",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local postgresql database with image version of 14.0. \n\nimport catalog.models.schema.v1.accessories.postgres\n\npostgres: postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b509c81b.b10ec20a.js b/assets/js/b509c81b.b10ec20a.js new file mode 100644 index 00000000000..ea79a8dfc4a --- /dev/null +++ b/assets/js/b509c81b.b10ec20a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3618],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),d=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=d(n),u=r,k=m["".concat(i,".").concat(u)]||m[u]||c[u]||o;return n?a.createElement(k,l(l({ref:t},p),{},{components:n})):a.createElement(k,l({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:r,l[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var a=n(87462),r=(n(67294),n(3905));const o={},l="postgres",s={unversionedId:"kusion/reference/modules/catalog-models/database/postgres",id:"version-v0.10/kusion/reference/modules/catalog-models/database/postgres",title:"postgres",description:"Schema PostgreSQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/database",slug:"/kusion/reference/modules/catalog-models/database/postgres",permalink:"/docs/kusion/reference/modules/catalog-models/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/kusion/reference/modules/catalog-models/database/mysql"},next:{title:"common",permalink:"/docs/kusion/reference/modules/catalog-models/internal/common"}},i={},d=[{value:"Schema PostgreSQL",id:"schema-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Credentials and Connectivity",id:"credentials-and-connectivity",level:3}],p={toc:d};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"postgres"},"postgres"),(0,r.kt)("h2",{id:"schema-postgresql"},"Schema PostgreSQL"),(0,r.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider",(0,r.kt)("br",null),"managed postgresql database instance for the workload. "),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type defines whether the postgresql database is deployed locally or provided by",(0,r.kt)("br",null),"cloud vendor."),(0,r.kt)("td",{parentName:"tr",align:null},'"local" ',"|",' "cloud"'),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"version"),(0,r.kt)("br",null),"Version defines the mysql version to use."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a local postgresql database with image version of 14.0. \n\nimport catalog.models.schema.v1.accessories.postgres\n\npostgres: postgres.PostgreSQL {\n type: "local"\n version: "14.0"\n}\n')),(0,r.kt)("h3",{id:"credentials-and-connectivity"},"Credentials and Connectivity"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","HOST","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","USERNAME","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB","_","PASSWORD","_",(0,r.kt)("inlineCode",{parentName:"td"},"")),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"")," is composed of two parts, one of which is the ",(0,r.kt)("inlineCode",{parentName:"p"},"key")," of database declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," and the other is the ",(0,r.kt)("inlineCode",{parentName:"p"},"suffix")," declared in ",(0,r.kt)("inlineCode",{parentName:"p"},"workspace")," configuration. Kusion will concatenate the database key and suffix, convert them to uppercase, and replace ",(0,r.kt)("inlineCode",{parentName:"p"},"-")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"_"),". And the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," supported now includes ",(0,r.kt)("inlineCode",{parentName:"p"},"mysql")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postgres"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b57a4a2d.04ebf6ac.js b/assets/js/b57a4a2d.04ebf6ac.js deleted file mode 100644 index af39d9e9088..00000000000 --- a/assets/js/b57a4a2d.04ebf6ac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2708],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=r.createContext({}),l=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=l(e.components);return r.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=i,g=d["".concat(p,".").concat(m)]||d[m]||u[m]||a;return t?r.createElement(g,o(o({ref:n},c),{},{components:t})):r.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=d;var s={};for(var p in n)hasOwnProperty.call(n,p)&&(s[p]=n[p]);s.originalType=e,s.mdxType="string"==typeof e?e:i,o[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=t(87462),i=(t(67294),t(3905));const a={},o="Configure Resource Specification",s={unversionedId:"kusion/user-guides/working-with-k8s/resource-spec",id:"kusion/user-guides/working-with-k8s/resource-spec",title:"Configure Resource Specification",description:"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/resource-spec",permalink:"/docs/next/kusion/user-guides/working-with-k8s/resource-spec",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{},sidebar:"kusion",previous:{title:"Upgrade Image",permalink:"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade"},next:{title:"Set up Operational Rules",permalink:"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules"}},p={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configure-resource-specification"},"Configure Resource Specification"),(0,i.kt)("p",null,"You can manage container-level resource specification in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"resources")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema)."),(0,i.kt)("p",null,"For the full ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"Update the resources value in ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.helloworld: {\n ...\n # before:\n # resources: {\n # "cpu": "500m"\n # "memory": "512M"\n # }\n # after: \n resources: {\n "cpu": "250m"\n "memory": "256Mi"\n }\n ...\n }\n}\n')),(0,i.kt)("p",null,"Everything else in ",(0,i.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated resources attributes (cpu:250m, memory:256Mi) as defined in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n resources:\n limits:\n cpu: 250m\n memory: 256Mi\n...\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b57a4a2d.3b54e102.js b/assets/js/b57a4a2d.3b54e102.js new file mode 100644 index 00000000000..f195343ca4d --- /dev/null +++ b/assets/js/b57a4a2d.3b54e102.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2708],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=r.createContext({}),l=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=l(e.components);return r.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=i,g=d["".concat(p,".").concat(m)]||d[m]||u[m]||a;return t?r.createElement(g,o(o({ref:n},c),{},{components:t})):r.createElement(g,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=d;var s={};for(var p in n)hasOwnProperty.call(n,p)&&(s[p]=n[p]);s.originalType=e,s.mdxType="string"==typeof e?e:i,o[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=t(87462),i=(t(67294),t(3905));const a={},o="Configure Resource Specification",s={unversionedId:"kusion/user-guides/working-with-k8s/resource-spec",id:"kusion/user-guides/working-with-k8s/resource-spec",title:"Configure Resource Specification",description:"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/resource-spec",permalink:"/docs/next/kusion/user-guides/working-with-k8s/resource-spec",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{},sidebar:"kusion",previous:{title:"Upgrade Image",permalink:"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade"},next:{title:"Set up Operational Rules",permalink:"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules"}},p={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configure-resource-specification"},"Configure Resource Specification"),(0,i.kt)("p",null,"You can manage container-level resource specification in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"resources")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema)."),(0,i.kt)("p",null,"For the full ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"Update the resources value in ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.helloworld: {\n ...\n # before:\n # resources: {\n # "cpu": "500m"\n # "memory": "512M"\n # }\n # after: \n resources: {\n "cpu": "250m"\n "memory": "256Mi"\n }\n ...\n }\n}\n')),(0,i.kt)("p",null,"Everything else in ",(0,i.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated resources attributes (cpu:250m, memory:256Mi) as defined in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n resources:\n limits:\n cpu: 250m\n memory: 256Mi\n...\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b5d95ae4.69d9052f.js b/assets/js/b5d95ae4.69d9052f.js deleted file mode 100644 index c7fb5c9cb2f..00000000000 --- a/assets/js/b5d95ae4.69d9052f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[413],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(t),m=i,k=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(k,o(o({ref:n},c),{},{components:t})):a.createElement(k,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=t(87462),i=(t(67294),t(3905));const r={},o="Configure Containers",l={unversionedId:"kusion/user-guides/working-with-k8s/container",id:"version-v0.10/kusion/user-guides/working-with-k8s/container",title:"Configure Containers",description:"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/2-container.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/container",permalink:"/docs/kusion/user-guides/working-with-k8s/container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/2-container.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application",permalink:"/docs/kusion/user-guides/working-with-k8s/deploy-application"},next:{title:"Expose Service",permalink:"/docs/kusion/user-guides/working-with-k8s/service"}},s={},p=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Apply",id:"apply",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function d(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configure-containers"},"Configure Containers"),(0,i.kt)("p",null,"You can manage container-level configurations in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). By default, everything defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field will be treated as application containers. Sidecar containers will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the full ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,i.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the last guide, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/service"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,i.kt)("h2",{id:"apply"},"Apply"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new container configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the container (in the deployment template) now has the updated attributes as defined in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n - name: env1\n value: VALUE\n - name: env2\n value: VALUE2\n image: gcr.io/google-samples/gb-frontend:v4\n imagePullPolicy: IfNotPresent\n name: helloworld\n readinessProbe:\n failureThreshold: 3\n httpGet:\n host: localhost\n path: /\n port: 80\n scheme: HTTP\n initialDelaySeconds: 10\n periodSeconds: 10\n successThreshold: 1\n timeoutSeconds: 1\n resources:\n limits:\n cpu: 500m\n memory: 512M\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b5d95ae4.abfc5821.js b/assets/js/b5d95ae4.abfc5821.js new file mode 100644 index 00000000000..646f3412573 --- /dev/null +++ b/assets/js/b5d95ae4.abfc5821.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[413],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(t),m=i,k=u["".concat(s,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(k,o(o({ref:n},c),{},{components:t})):a.createElement(k,o({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,o=new Array(r);o[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=t(87462),i=(t(67294),t(3905));const r={},o="Configure Containers",l={unversionedId:"kusion/user-guides/working-with-k8s/container",id:"version-v0.10/kusion/user-guides/working-with-k8s/container",title:"Configure Containers",description:"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/2-container.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/container",permalink:"/docs/kusion/user-guides/working-with-k8s/container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/2-container.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application",permalink:"/docs/kusion/user-guides/working-with-k8s/deploy-application"},next:{title:"Expose Service",permalink:"/docs/kusion/user-guides/working-with-k8s/service"}},s={},p=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Apply",id:"apply",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function d(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"configure-containers"},"Configure Containers"),(0,i.kt)("p",null,"You can manage container-level configurations in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). By default, everything defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"containers")," field will be treated as application containers. Sidecar containers will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the full ",(0,i.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-container"},"here")," for more details."),(0,i.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the last guide, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/service"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,i.kt)("h2",{id:"apply"},"Apply"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new container configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the container (in the deployment template) now has the updated attributes as defined in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kubectl get deployment -n simple-service -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n - name: env1\n value: VALUE\n - name: env2\n value: VALUE2\n image: gcr.io/google-samples/gb-frontend:v4\n imagePullPolicy: IfNotPresent\n name: helloworld\n readinessProbe:\n failureThreshold: 3\n httpGet:\n host: localhost\n path: /\n port: 80\n scheme: HTTP\n initialDelaySeconds: 10\n periodSeconds: 10\n successThreshold: 1\n timeoutSeconds: 1\n resources:\n limits:\n cpu: 500m\n memory: 512M\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b6cf2faa.37ca3985.js b/assets/js/b6cf2faa.183608ed.js similarity index 82% rename from assets/js/b6cf2faa.37ca3985.js rename to assets/js/b6cf2faa.183608ed.js index ea4c5126897..823ab5638dd 100644 --- a/assets/js/b6cf2faa.37ca3985.js +++ b/assets/js/b6cf2faa.183608ed.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1725],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),f=l(r),d=o,m=f["".concat(c,".").concat(d)]||f[d]||u[d]||i;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:2},a="KCL",s={unversionedId:"kusion/faq/kcl",id:"version-v0.10/kusion/faq/kcl",title:"KCL",description:"Visit the KCL website for more documents.",source:"@site/versioned_docs/version-v0.10/kusion/7-faq/2-kcl.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/kcl",permalink:"/docs/kusion/faq/kcl",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/7-faq/2-kcl.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Installation",permalink:"/docs/kusion/faq/install-error"}},c={},l=[],p={toc:l};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kcl"},"KCL"),(0,o.kt)("p",null,"Visit the ",(0,o.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website")," for more documents."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1725],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),f=l(r),d=o,m=f["".concat(c,".").concat(d)]||f[d]||u[d]||i;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:2},a="KCL",s={unversionedId:"kusion/faq/kcl",id:"version-v0.10/kusion/faq/kcl",title:"KCL",description:"Visit the KCL website for more documents.",source:"@site/versioned_docs/version-v0.10/kusion/7-faq/2-kcl.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/kcl",permalink:"/docs/kusion/faq/kcl",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/7-faq/2-kcl.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Installation",permalink:"/docs/kusion/faq/install-error"}},c={},l=[],p={toc:l};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kcl"},"KCL"),(0,o.kt)("p",null,"Visit the ",(0,o.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website")," for more documents."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b6dea0ad.5d55a0d7.js b/assets/js/b6dea0ad.5d55a0d7.js new file mode 100644 index 00000000000..6e9377186c9 --- /dev/null +++ b/assets/js/b6dea0ad.5d55a0d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8535],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=a,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?i.createElement(m,r(r({ref:t},c),{},{components:n})):i.createElement(m,r({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Expose Application Service Deployed on CSP Kubernetes",s={unversionedId:"kusion/user-guides/cloud-resources/expose-service",id:"version-v0.10/kusion/user-guides/cloud-resources/expose-service",title:"Expose Application Service Deployed on CSP Kubernetes",description:"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/expose-service",permalink:"/docs/kusion/user-guides/cloud-resources/expose-service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/kusion/user-guides/cloud-resources/database"},next:{title:"Deploy Application",permalink:"/docs/kusion/user-guides/working-with-k8s/deploy-application"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Expose Service Publicly",id:"expose-service-publicly",level:2},{value:"Set up Workspace",id:"set-up-workspace",level:3},{value:"Write Configuration Code",id:"write-configuration-code",level:3},{value:"Preview and Apply",id:"preview-and-apply",level:3},{value:"Verify Accessibility",id:"verify-accessibility",level:3},{value:"Expose Service Inside Cluster",id:"expose-service-inside-cluster",level:2},{value:"Summary",id:"summary",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"expose-application-service-deployed-on-csp-kubernetes"},"Expose Application Service Deployed on CSP Kubernetes"),(0,a.kt)("p",null,"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way. "),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on CSP Kubernetes. And the responsibilities of platform engineers and application developers are also clearly defined. In this article, ",(0,a.kt)("em",{parentName:"p"},(0,a.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/blob/main/example/nginx/dev/main.k"},"exposing the service of nginx"),' (referred to "the example" in the below)')," is given as an example."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Create a Kubernetes cluster, the following CSP Kubernetes services are supported."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/kubernetes"},"Alibaba Cloud Container Service for Kubernetes (ACK)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://aws.amazon.com/eks"},"Amazon Elastic Kubernetes Service (EKS)"),".")),(0,a.kt)("p",null,"Get the example from the official example repository."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/KusionStack/konfig.git && cd konfig/example/nginx\n")),(0,a.kt)("h2",{id:"expose-service-publicly"},"Expose Service Publicly"),(0,a.kt)("p",null,"If you want the application can be accessed from outside the cluster, you should expose the service publicly. Follow the steps below, you will simply hit the goal."),(0,a.kt)("h3",{id:"set-up-workspace"},"Set up Workspace"),(0,a.kt)("p",null,"Create the workspace as the target where the application will be deployed to. The workspace is usually set up by platform engineers, which contains platform-standard and application-agnostic configurations. The workspace configurations are organized through a YAML file."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n\nruntimes:\n kubernetes:\n kubeconfig: ""\n')),(0,a.kt)("p",null,"The YAML shown above gives an example of the workspace configuration to expose service on ACK. The file contains two top-level blocks ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),", and the block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),". "),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," contains the workspace configuration of module port, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"type: the CSP providing Kubernetes service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"alicloud")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"aws")),(0,a.kt)("li",{parentName:"ul"},"annotations: annotations attached to the service, should be a map"),(0,a.kt)("li",{parentName:"ul"},"labels: labels attached to the service, should be a map")),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," contains the kubernetes related configuration, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"kubeconfig: the kube-config file path, which is got after creating the cluster.")),(0,a.kt)("p",null,"You can also configure kube-config by environment variables, which has higher priority."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export KUBE_CONFIG=""\n')),(0,a.kt)("p",null,"Then, create the workspace with the configuration file. Be attention, the workspace name must be the same as the stack name. The following command creates a workspace named ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," with configuration file ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace create prod workspace.yaml\n")),(0,a.kt)("h3",{id:"write-configuration-code"},"Write Configuration Code"),(0,a.kt)("p",null,"After creating workspace, you should write application configuration code, which only contains simple and application-centric configurations. This step is usually accomplished by application developers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n nginx: c.Container {\n image = "nginx:1.25.2"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n protocol: "TCP"\n public: True\n }\n ]\n }\n}\n')),(0,a.kt)("p",null,"The code shown above describes how to expose service publicly on ACK. Kusion use schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port")," to describe the network configuration, the primary fields of Port are as follows:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"port: port number to expose service"),(0,a.kt)("li",{parentName:"ul"},"protocol: protocol to expose service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"TCP")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"UDP")),(0,a.kt)("li",{parentName:"ul"},"public: whether to public the service")),(0,a.kt)("p",null,"To public the service, you should set ",(0,a.kt)("inlineCode",{parentName:"p"},"public")," as True. Besides, schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," should be used to describe the workload configuration."),(0,a.kt)("p",null,"That's all what an application developer need to configure! Next, preview and apply the configuration, the application will get deployed and exposed publicly."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Kusion uses Load Balancer (LB) provided by the CSP to expose service publicly. For more detailed network configuration, please refer to ",(0,a.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/kusion/configuration-walkthrough/networking"},"Application Networking"))),(0,a.kt)("h3",{id:"preview-and-apply"},"Preview and Apply"),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion preview")," under the stack path, you will get what will be created in the real infrastructure. The picture below gives the preview result of the example. A Namespace, Service and Deployment will be created, which meets the expectation. The service name has a suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"public"),", which shows it can be accessed publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"preview-public",src:n(85091).Z,width:"1540",height:"262"})),(0,a.kt)("p",null,"Then, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes")," to do the real deploying job. Just a command and a few minutes, you have accomplished deploying application and expose it publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-public",src:n(97932).Z,width:"1558",height:"480"})),(0,a.kt)("h3",{id:"verify-accessibility"},"Verify Accessibility"),(0,a.kt)("p",null,"In the example, the kubernetes Namespace whose name is nginx, and a Service and Deployment under the Namespace should be created. Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl get")," to check, the Service whose type is ",(0,a.kt)("inlineCode",{parentName:"p"},"LoadBalancer")," and Deployment are created indeed. And the Service has ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," 106.5.190.109, which means it can be accessed from outside the cluster."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-public",src:n(68162).Z,width:"1662",height:"216"})),(0,a.kt)("p",null,"Visit the ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," via browser, the correct result is returned, which illustrates the servie get publicly exposed successfully."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"result-public",src:n(65377).Z,width:"1494",height:"682"})),(0,a.kt)("h2",{id:"expose-service-inside-cluster"},"Expose Service Inside Cluster"),(0,a.kt)("p",null,"If you only need the application can be accessed inside the cluster, just configure ",(0,a.kt)("inlineCode",{parentName:"p"},"Public")," as False in schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port"),". There is no need to change the workspace, which means an application developer can easily change a service exposure range, without the involvement of platform engineers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n ...\n ports: [\n n.Port {\n ...\n public: False\n }\n ]\n }\n}\n")),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes"),", the generated Service has suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"private"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-private",src:n(96057).Z,width:"1612",height:"494"})),(0,a.kt)("p",null,"And the Service type is ",(0,a.kt)("inlineCode",{parentName:"p"},"ClusterIP"),", only has ",(0,a.kt)("inlineCode",{parentName:"p"},"CLUSTER_IP")," and no ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL_IP"),", which means it cannot get accessed from outside the cluster. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-private",src:n(64600).Z,width:"1542",height:"210"})),(0,a.kt)("h2",{id:"summary"},"Summary"),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on the CSP Kubernetes. By platform engineers' setup of workspace, and application developers' configuration of schema Port, Kusion enables you expose service simply and efficiently."))}u.isMDXComponent=!0},96057:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-private-a1d1f3a1b5afac81cea19f189d08222d.png"},97932:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-public-d89cdb3ba9d96904e1820bfbcf4671d8.png"},64600:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-private-62ab14b1de35205866b64a0d63180450.png"},68162:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-public-66ffcb206b33c5fc6f1a779bc10b3e93.png"},85091:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/preview-public-eea90eec123cd2fc13536be2b645e900.png"},65377:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/result-public-4bf3f757b0a43c78464ec9bcd75a4b2f.png"}}]); \ No newline at end of file diff --git a/assets/js/b6dea0ad.cd24d5b1.js b/assets/js/b6dea0ad.cd24d5b1.js deleted file mode 100644 index 30081189cf8..00000000000 --- a/assets/js/b6dea0ad.cd24d5b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8535],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=a,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?i.createElement(m,r(r({ref:t},c),{},{components:n})):i.createElement(m,r({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Expose Application Service Deployed on CSP Kubernetes",s={unversionedId:"kusion/user-guides/cloud-resources/expose-service",id:"version-v0.10/kusion/user-guides/cloud-resources/expose-service",title:"Expose Application Service Deployed on CSP Kubernetes",description:"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/expose-service",permalink:"/docs/kusion/user-guides/cloud-resources/expose-service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/kusion/user-guides/cloud-resources/database"},next:{title:"Deploy Application",permalink:"/docs/kusion/user-guides/working-with-k8s/deploy-application"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Expose Service Publicly",id:"expose-service-publicly",level:2},{value:"Set up Workspace",id:"set-up-workspace",level:3},{value:"Write Configuration Code",id:"write-configuration-code",level:3},{value:"Preview and Apply",id:"preview-and-apply",level:3},{value:"Verify Accessibility",id:"verify-accessibility",level:3},{value:"Expose Service Inside Cluster",id:"expose-service-inside-cluster",level:2},{value:"Summary",id:"summary",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"expose-application-service-deployed-on-csp-kubernetes"},"Expose Application Service Deployed on CSP Kubernetes"),(0,a.kt)("p",null,"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way. "),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on CSP Kubernetes. And the responsibilities of platform engineers and application developers are also clearly defined. In this article, ",(0,a.kt)("em",{parentName:"p"},(0,a.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/blob/main/example/nginx/dev/main.k"},"exposing the service of nginx"),' (referred to "the example" in the below)')," is given as an example."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Create a Kubernetes cluster, the following CSP Kubernetes services are supported."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/kubernetes"},"Alibaba Cloud Container Service for Kubernetes (ACK)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://aws.amazon.com/eks"},"Amazon Elastic Kubernetes Service (EKS)"),".")),(0,a.kt)("p",null,"Get the example from the official example repository."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/KusionStack/konfig.git && cd konfig/example/nginx\n")),(0,a.kt)("h2",{id:"expose-service-publicly"},"Expose Service Publicly"),(0,a.kt)("p",null,"If you want the application can be accessed from outside the cluster, you should expose the service publicly. Follow the steps below, you will simply hit the goal."),(0,a.kt)("h3",{id:"set-up-workspace"},"Set up Workspace"),(0,a.kt)("p",null,"Create the workspace as the target where the application will be deployed to. The workspace is usually set up by platform engineers, which contains platform-standard and application-agnostic configurations. The workspace configurations are organized through a YAML file."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n\nruntimes:\n kubernetes:\n kubeconfig: ""\n')),(0,a.kt)("p",null,"The YAML shown above gives an example of the workspace configuration to expose service on ACK. The file contains two top-level blocks ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),", and the block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),". "),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," contains the workspace configuration of module port, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"type: the CSP providing Kubernetes service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"alicloud")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"aws")),(0,a.kt)("li",{parentName:"ul"},"annotations: annotations attached to the service, should be a map"),(0,a.kt)("li",{parentName:"ul"},"labels: labels attached to the service, should be a map")),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," contains the kubernetes related configuration, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"kubeconfig: the kube-config file path, which is got after creating the cluster.")),(0,a.kt)("p",null,"You can also configure kube-config by environment variables, which has higher priority."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export KUBE_CONFIG=""\n')),(0,a.kt)("p",null,"Then, create the workspace with the configuration file. Be attention, the workspace name must be the same as the stack name. The following command creates a workspace named ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," with configuration file ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace create prod workspace.yaml\n")),(0,a.kt)("h3",{id:"write-configuration-code"},"Write Configuration Code"),(0,a.kt)("p",null,"After creating workspace, you should write application configuration code, which only contains simple and application-centric configurations. This step is usually accomplished by application developers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n nginx: c.Container {\n image = "nginx:1.25.2"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n protocol: "TCP"\n public: True\n }\n ]\n }\n}\n')),(0,a.kt)("p",null,"The code shown above describes how to expose service publicly on ACK. Kusion use schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port")," to describe the network configuration, the primary fields of Port are as follows:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"port: port number to expose service"),(0,a.kt)("li",{parentName:"ul"},"protocol: protocol to expose service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"TCP")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"UDP")),(0,a.kt)("li",{parentName:"ul"},"public: whether to public the service")),(0,a.kt)("p",null,"To public the service, you should set ",(0,a.kt)("inlineCode",{parentName:"p"},"public")," as True. Besides, schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," should be used to describe the workload configuration."),(0,a.kt)("p",null,"That's all what an application developer need to configure! Next, preview and apply the configuration, the application will get deployed and exposed publicly."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Kusion uses Load Balancer (LB) provided by the CSP to expose service publicly. For more detailed network configuration, please refer to ",(0,a.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/kusion/configuration-walkthrough/networking"},"Application Networking"))),(0,a.kt)("h3",{id:"preview-and-apply"},"Preview and Apply"),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion preview")," under the stack path, you will get what will be created in the real infrastructure. The picture below gives the preview result of the example. A Namespace, Service and Deployment will be created, which meets the expectation. The service name has a suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"public"),", which shows it can be accessed publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"preview-public",src:n(85091).Z,width:"1540",height:"262"})),(0,a.kt)("p",null,"Then, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes")," to do the real deploying job. Just a command and a few minutes, you have accomplished deploying application and expose it publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-public",src:n(97932).Z,width:"1558",height:"480"})),(0,a.kt)("h3",{id:"verify-accessibility"},"Verify Accessibility"),(0,a.kt)("p",null,"In the example, the kubernetes Namespace whose name is nginx, and a Service and Deployment under the Namespace should be created. Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl get")," to check, the Service whose type is ",(0,a.kt)("inlineCode",{parentName:"p"},"LoadBalancer")," and Deployment are created indeed. And the Service has ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," 106.5.190.109, which means it can be accessed from outside the cluster."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-public",src:n(68162).Z,width:"1662",height:"216"})),(0,a.kt)("p",null,"Visit the ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," via browser, the correct result is returned, which illustrates the servie get publicly exposed successfully."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"result-public",src:n(65377).Z,width:"1494",height:"682"})),(0,a.kt)("h2",{id:"expose-service-inside-cluster"},"Expose Service Inside Cluster"),(0,a.kt)("p",null,"If you only need the application can be accessed inside the cluster, just configure ",(0,a.kt)("inlineCode",{parentName:"p"},"Public")," as False in schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port"),". There is no need to change the workspace, which means an application developer can easily change a service exposure range, without the involvement of platform engineers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n ...\n ports: [\n n.Port {\n ...\n public: False\n }\n ]\n }\n}\n")),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes"),", the generated Service has suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"private"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-private",src:n(96057).Z,width:"1612",height:"494"})),(0,a.kt)("p",null,"And the Service type is ",(0,a.kt)("inlineCode",{parentName:"p"},"ClusterIP"),", only has ",(0,a.kt)("inlineCode",{parentName:"p"},"CLUSTER_IP")," and no ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL_IP"),", which means it cannot get accessed from outside the cluster. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-private",src:n(64600).Z,width:"1542",height:"210"})),(0,a.kt)("h2",{id:"summary"},"Summary"),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on the CSP Kubernetes. By platform engineers' setup of workspace, and application developers' configuration of schema Port, Kusion enables you expose service simply and efficiently."))}u.isMDXComponent=!0},96057:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-private-a1d1f3a1b5afac81cea19f189d08222d.png"},97932:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-public-d89cdb3ba9d96904e1820bfbcf4671d8.png"},64600:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-private-62ab14b1de35205866b64a0d63180450.png"},68162:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-public-66ffcb206b33c5fc6f1a779bc10b3e93.png"},85091:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/preview-public-eea90eec123cd2fc13536be2b645e900.png"},65377:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/result-public-4bf3f757b0a43c78464ec9bcd75a4b2f.png"}}]); \ No newline at end of file diff --git a/assets/js/b70fdfcb.fb1bde34.js b/assets/js/b70fdfcb.079b5d16.js similarity index 85% rename from assets/js/b70fdfcb.fb1bde34.js rename to assets/js/b70fdfcb.079b5d16.js index 380c09e8e35..a8ac2141dd2 100644 --- a/assets/js/b70fdfcb.fb1bde34.js +++ b/assets/js/b70fdfcb.079b5d16.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5081],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(r),m=o,d=u["".concat(s,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,c(c({ref:t},p),{},{components:r})):n.createElement(d,c({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,c[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>f,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:1},c="FAQ",i={unversionedId:"ctrlmesh/faq/faq",id:"ctrlmesh/faq/faq",title:"FAQ",description:"",source:"@site/docs/ctrlmesh/faq/faq.md",sourceDirName:"ctrlmesh/faq",slug:"/ctrlmesh/faq/",permalink:"/docs/next/ctrlmesh/faq/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/faq/faq.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Try a Sample",permalink:"/docs/next/ctrlmesh/started/try"}},s={},l=[],p={toc:l};function f(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5081],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(r),m=o,d=u["".concat(s,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,c(c({ref:t},p),{},{components:r})):n.createElement(d,c({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,c[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>f,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:1},c="FAQ",i={unversionedId:"ctrlmesh/faq/faq",id:"ctrlmesh/faq/faq",title:"FAQ",description:"",source:"@site/docs/ctrlmesh/faq/faq.md",sourceDirName:"ctrlmesh/faq",slug:"/ctrlmesh/faq/",permalink:"/docs/next/ctrlmesh/faq/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/ctrlmesh/faq/faq.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Try a Sample",permalink:"/docs/next/ctrlmesh/started/try"}},s={},l=[],p={toc:l};function f(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b72e870b.04febfb1.js b/assets/js/b72e870b.32e861fd.js similarity index 56% rename from assets/js/b72e870b.04febfb1.js rename to assets/js/b72e870b.32e861fd.js index 5769b3985d5..50d0e215830 100644 --- a/assets/js/b72e870b.04febfb1.js +++ b/assets/js/b72e870b.32e861fd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[799],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>k});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var c=o.createContext({}),p=function(e){var n=o.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},l=function(e){var n=p(e.components);return o.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(t),k=r,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return t?o.createElement(m,s(s({ref:n},l),{},{components:t})):o.createElement(m,s({ref:n},l))}));function k(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,s=new Array(a);s[0]=d;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var p=2;p{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var o=t(87462),r=(t(67294),t(3905));const a={},s="kusion workspace show",i={unversionedId:"kusion/reference/commands/kusion-workspace-show",id:"kusion/reference/commands/kusion-workspace-show",title:"kusion workspace show",description:"Show a workspace configuration",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-show.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-show",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-show",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-show.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace list",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-list"},next:{title:"kusion workspace update",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-update"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-workspace-show"},"kusion workspace show"),(0,r.kt)("p",null,"Show a workspace configuration"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"This command gets a specified workspace configuration."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace show\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Show a workspace configuration\n kusion workspace show dev\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -h, --help help for show\n")),(0,r.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[799],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>k});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var c=o.createContext({}),p=function(e){var n=o.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},l=function(e){var n=p(e.components);return o.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(t),k=r,m=d["".concat(c,".").concat(k)]||d[k]||u[k]||a;return t?o.createElement(m,s(s({ref:n},l),{},{components:t})):o.createElement(m,s({ref:n},l))}));function k(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,s=new Array(a);s[0]=d;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var p=2;p{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var o=t(87462),r=(t(67294),t(3905));const a={},s="kusion workspace show",i={unversionedId:"kusion/reference/commands/kusion-workspace-show",id:"kusion/reference/commands/kusion-workspace-show",title:"kusion workspace show",description:"Show a workspace configuration",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-show.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-show",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-show",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-show.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace list",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-list"},next:{title:"kusion workspace update",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-update"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-workspace-show"},"kusion workspace show"),(0,r.kt)("p",null,"Show a workspace configuration"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"This command gets a specified workspace configuration."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion workspace show\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Show a workspace configuration\n kusion workspace show dev\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -h, --help help for show\n")),(0,r.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b7847a20.c0ab7bba.js b/assets/js/b7847a20.c0ab7bba.js new file mode 100644 index 00000000000..563c7476bdd --- /dev/null +++ b/assets/js/b7847a20.c0ab7bba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1659],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),s=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=s(n),m=a,f=d["".concat(i,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(f,l(l({ref:t},p),{},{components:n})):r.createElement(f,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="lifecycle",c={unversionedId:"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",title:"lifecycle",description:"Schema Lifecycle",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle",slug:"/kusion/reference/modules/catalog-models/internal/container/lifecycle/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"container",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/"},next:{title:"probe",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/"}},i={},s=[{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"lifecycle"},"lifecycle"),(0,a.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,a.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,a.kt)("br",null),"to container lifecycle events."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"preStop"),(0,a.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,a.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"postStart"),(0,a.kt)("br",null),"The action to be taken after a container is created.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b7847a20.d3e7f5b2.js b/assets/js/b7847a20.d3e7f5b2.js deleted file mode 100644 index 845d4ba61b0..00000000000 --- a/assets/js/b7847a20.d3e7f5b2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1659],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),s=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=s(n),m=a,f=d["".concat(i,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(f,l(l({ref:t},p),{},{components:n})):r.createElement(f,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const o={},l="lifecycle",c={unversionedId:"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",id:"version-v0.10/kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle",title:"lifecycle",description:"Schema Lifecycle",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle",slug:"/kusion/reference/modules/catalog-models/internal/container/lifecycle/",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"container",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/"},next:{title:"probe",permalink:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/"}},i={},s=[{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:s};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"lifecycle"},"lifecycle"),(0,a.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,a.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,a.kt)("br",null),"to container lifecycle events."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"preStop"),(0,a.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,a.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"postStart"),(0,a.kt)("br",null),"The action to be taken after a container is created.",(0,a.kt)("br",null),"More info: ",(0,a.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-exec"},"probe.Exec")," ","|"," ",(0,a.kt)("a",{parentName:"td",href:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/#schema-http"},"probe.Http")),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b8caf01f.0df1e7b0.js b/assets/js/b8caf01f.de8cdbb9.js similarity index 58% rename from assets/js/b8caf01f.0df1e7b0.js rename to assets/js/b8caf01f.de8cdbb9.js index 1cecf0a3274..128ece137fe 100644 --- a/assets/js/b8caf01f.0df1e7b0.js +++ b/assets/js/b8caf01f.de8cdbb9.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5297],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||s;return n?o.createElement(f,i(i({ref:t},u),{},{components:n})):o.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,i=new Array(s);i[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:r,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const s={},i="Kusion Module",a={unversionedId:"kusion/concepts/kusion-module",id:"version-v0.10/kusion/concepts/kusion-module",title:"Kusion Module",description:"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/3-kusion-module.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/kusion-module",permalink:"/docs/kusion/concepts/kusion-module",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/3-kusion-module.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Stack Configuration",permalink:"/docs/kusion/concepts/stack/configuration"},next:{title:"Workspace",permalink:"/docs/kusion/concepts/workspace"}},c={},l=[],u={toc:l};function p(e){let{components:t,...s}=e;return(0,r.kt)("wrapper",(0,o.Z)({},u,s,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-module"},"Kusion Module"),(0,r.kt)("p",null,"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"App developer-oriented schema: It is a ",(0,r.kt)("a",{parentName:"li",href:"https://kcl-lang.io/docs/user_docs/guides/schema-definition/"},"KCL schema"),". Fields in this schema are recommended to be understandable to application developers and workspace-agnostic. For example, a database Kusion module schema only contains fields like database engine type and database version."),(0,r.kt)("li",{parentName:"ul"},"Kusion module generator: It is a piece of logic that generates the Intent with an instantiated schema mentioned above, along with platform configurations (",(0,r.kt)("a",{parentName:"li",href:"workspace"},"workspace"),"). As a building block, Kusion module hides the complexity of infrastructures. A database Kusion module not only represents a cloud RDS, but it also contains logic to configure other resources such as security groups and IAM policies. Additionally, it seamlessly injects the database host address, username, and password into the workload's environment variables. The generator logic can be very complex in some situations so we recommend implementing it in a GPL like ",(0,r.kt)("a",{parentName:"li",href:"https://go.dev/"},"go"),".")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion-module",src:n(63623).Z,width:"707",height:"215"})))}p.isMDXComponent=!0},63623:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/kusion-module-1b5dfa0856e8c5416468be9719b8e216.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5297],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||s;return n?o.createElement(f,i(i({ref:t},u),{},{components:n})):o.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,i=new Array(s);i[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:r,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const s={},i="Kusion Module",a={unversionedId:"kusion/concepts/kusion-module",id:"version-v0.10/kusion/concepts/kusion-module",title:"Kusion Module",description:"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/3-kusion-module.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/kusion-module",permalink:"/docs/kusion/concepts/kusion-module",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/3-kusion-module.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Stack Configuration",permalink:"/docs/kusion/concepts/stack/configuration"},next:{title:"Workspace",permalink:"/docs/kusion/concepts/workspace"}},c={},l=[],u={toc:l};function p(e){let{components:t,...s}=e;return(0,r.kt)("wrapper",(0,o.Z)({},u,s,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-module"},"Kusion Module"),(0,r.kt)("p",null,"A Kusion module is a reusable building block designed by platform engineers to standardize application deployments and enable app developers to self-service. It consists of two parts:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"App developer-oriented schema: It is a ",(0,r.kt)("a",{parentName:"li",href:"https://kcl-lang.io/docs/user_docs/guides/schema-definition/"},"KCL schema"),". Fields in this schema are recommended to be understandable to application developers and workspace-agnostic. For example, a database Kusion module schema only contains fields like database engine type and database version."),(0,r.kt)("li",{parentName:"ul"},"Kusion module generator: It is a piece of logic that generates the Intent with an instantiated schema mentioned above, along with platform configurations (",(0,r.kt)("a",{parentName:"li",href:"workspace"},"workspace"),"). As a building block, Kusion module hides the complexity of infrastructures. A database Kusion module not only represents a cloud RDS, but it also contains logic to configure other resources such as security groups and IAM policies. Additionally, it seamlessly injects the database host address, username, and password into the workload's environment variables. The generator logic can be very complex in some situations so we recommend implementing it in a GPL like ",(0,r.kt)("a",{parentName:"li",href:"https://go.dev/"},"go"),".")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"kusion-module",src:n(63623).Z,width:"707",height:"215"})))}p.isMDXComponent=!0},63623:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/kusion-module-1b5dfa0856e8c5416468be9719b8e216.png"}}]); \ No newline at end of file diff --git a/assets/js/b9b61d04.15460c78.js b/assets/js/b9b61d04.15460c78.js deleted file mode 100644 index a49adf4a564..00000000000 --- a/assets/js/b9b61d04.15460c78.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4491],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(t),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||i;return t?r.createElement(m,a(a({ref:n},p),{},{components:t})):r.createElement(m,a({ref:n},p))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=d;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const i={},a="Kusion Modules",s={unversionedId:"kusion/reference/modules/index",id:"kusion/reference/modules/index",title:"Kusion Modules",description:"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.",source:"@site/docs/kusion/6-reference/2-modules/index.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/",permalink:"/docs/next/kusion/reference/modules/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/index.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace",permalink:"/docs/next/kusion/reference/commands/kusion-workspace"},next:{title:"appconfiguration",permalink:"/docs/next/kusion/reference/modules/catalog-models/app-configuration"}},c={},l=[],p={toc:l};function u(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-modules"},"Kusion Modules"),(0,o.kt)("p",null,"KusionStack presets application configuration models described by KCL, where the model is called ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model"),". The GitHub repository ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," is used to store these models, which is known as ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model Library"),"."),(0,o.kt)("p",null,"The original intention of designing Kusion Model is to enhance the efficiency and improve the experience of YAML users. Through the unified application model defined by code, abstract and encapsulate complex configuration items, omit repetitive and derivable configurations, and supplement with necessary verification logic. Only the necessary attributes get exposed, users get an out-of-the-box, easy-to-understand configuration interface, which reduces the difficulty and improves the reliability of the configuration work."),(0,o.kt)("p",null,"Kusion Model Library currently provides the Kusion Model ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". The design of ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is developer-centric, based on Ant Group's decades of practice in building and managing hyperscale IDP (Internal Developer Platform), and the best practice of community. ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," describes the full lifecycle of an application."),(0,o.kt)("p",null,"A simple example of using ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to describe an application is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "wordpress": c.Container {\n image: "wordpress:latest"\n env: {\n "WORDPRESS_DB_HOST": "secret://wordpress-db/hostAddress"\n "WORDPRESS_DB_PASSWORD": "secret://wordpress-db/password"\n }\n resources: {\n "cpu": "1"\n "memory": "2Gi"\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n \n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n category: "serverless_basic"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b9b61d04.e07f242c.js b/assets/js/b9b61d04.e07f242c.js new file mode 100644 index 00000000000..2ff54d69ffc --- /dev/null +++ b/assets/js/b9b61d04.e07f242c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4491],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(t),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||i;return t?r.createElement(m,a(a({ref:n},p),{},{components:t})):r.createElement(m,a({ref:n},p))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=d;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const i={},a="Kusion Modules",s={unversionedId:"kusion/reference/modules/index",id:"kusion/reference/modules/index",title:"Kusion Modules",description:"KusionStack presets application configuration models described by KCL, where the model is called Kusion Model. The GitHub repository KusionStack/catalog is used to store these models, which is known as Kusion Model Library.",source:"@site/docs/kusion/6-reference/2-modules/index.md",sourceDirName:"kusion/6-reference/2-modules",slug:"/kusion/reference/modules/",permalink:"/docs/next/kusion/reference/modules/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/index.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace",permalink:"/docs/next/kusion/reference/commands/kusion-workspace"},next:{title:"appconfiguration",permalink:"/docs/next/kusion/reference/modules/catalog-models/app-configuration"}},c={},l=[],p={toc:l};function u(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-modules"},"Kusion Modules"),(0,o.kt)("p",null,"KusionStack presets application configuration models described by KCL, where the model is called ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model"),". The GitHub repository ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"KusionStack/catalog")," is used to store these models, which is known as ",(0,o.kt)("strong",{parentName:"p"},"Kusion Model Library"),"."),(0,o.kt)("p",null,"The original intention of designing Kusion Model is to enhance the efficiency and improve the experience of YAML users. Through the unified application model defined by code, abstract and encapsulate complex configuration items, omit repetitive and derivable configurations, and supplement with necessary verification logic. Only the necessary attributes get exposed, users get an out-of-the-box, easy-to-understand configuration interface, which reduces the difficulty and improves the reliability of the configuration work."),(0,o.kt)("p",null,"Kusion Model Library currently provides the Kusion Model ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration"),". The design of ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," is developer-centric, based on Ant Group's decades of practice in building and managing hyperscale IDP (Internal Developer Platform), and the best practice of community. ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," describes the full lifecycle of an application."),(0,o.kt)("p",null,"A simple example of using ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," to describe an application is as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'wordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "wordpress": c.Container {\n image: "wordpress:latest"\n env: {\n "WORDPRESS_DB_HOST": "secret://wordpress-db/hostAddress"\n "WORDPRESS_DB_PASSWORD": "secret://wordpress-db/password"\n }\n resources: {\n "cpu": "1"\n "memory": "2Gi"\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n \n database: db.Database {\n type: "alicloud"\n engine: "MySQL"\n version: "5.7"\n size: 20\n instanceType: "mysql.n2.serverless.1c"\n category: "serverless_basic"\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/baa12f70.132881b4.js b/assets/js/baa12f70.132881b4.js new file mode 100644 index 00000000000..a1e6ebfaf32 --- /dev/null +++ b/assets/js/baa12f70.132881b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5641],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),u=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},p=function(e){var r=u(e.components);return n.createElement(l.Provider,{value:r},e.children)},c={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=o,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||a;return t?n.createElement(f,s(s({ref:r},p),{},{components:t})):n.createElement(f,s({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,s=new Array(a);s[0]=d;var i={};for(var l in r)hasOwnProperty.call(r,l)&&(i[l]=r[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var u=2;u{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var n=t(87462),o=(t(67294),t(3905));const a={},s="Roadmap",i={unversionedId:"kusion/reference/roadmap",id:"kusion/reference/roadmap",title:"Roadmap",description:"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker",source:"@site/docs/kusion/6-reference/3-roadmap.md",sourceDirName:"kusion/6-reference",slug:"/kusion/reference/roadmap",permalink:"/docs/next/kusion/reference/roadmap",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/3-roadmap.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Resource Naming Conventions",permalink:"/docs/next/kusion/reference/modules/naming-conventions"},next:{title:"Installation",permalink:"/docs/next/kusion/faq/install-error"}},l={},u=[{value:"Resource Ecosystem",id:"resource-ecosystem",level:2},{value:"App Progressive Rollout",id:"app-progressive-rollout",level:2},{value:"Custom Pipelines",id:"custom-pipelines",level:2},{value:"Runtime Plugin",id:"runtime-plugin",level:2}],p={toc:u};function c(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"roadmap"},"Roadmap"),(0,o.kt)("p",null,"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"GitHub Issue Tracker")),(0,o.kt)("h2",{id:"resource-ecosystem"},"Resource Ecosystem"),(0,o.kt)("p",null,"We plan to expand the range of resource types that our platform can handle. This includes not only traditional cloud IaaS resources, but also popular cloud-native products such as Prometheus, istio and Argo. By supporting a wider variety of resources, we aim to address the heterogeneous needs of modern applications and allow users to harness the full power of the cloud-native technologies."),(0,o.kt)("h2",{id:"app-progressive-rollout"},"App Progressive Rollout"),(0,o.kt)("p",null,"One of the key challenges in delivering applications at scale is to balance the need for speed with the need for reliability. To help our users achieve this balance, we will introduce progressive rollout strategies, such as canary release, rolling release, and percentage release. These techniques enable users to test new features or versions on a small subset of their users or infrastructure before rolling them out to the entire system. By doing so, users can minimize the risk of downtime or errors caused by untested changes."),(0,o.kt)("h2",{id:"custom-pipelines"},"Custom Pipelines"),(0,o.kt)("p",null,"Thie current workflow of KusionStack is ",(0,o.kt)("inlineCode",{parentName:"p"},"write"),",",(0,o.kt)("inlineCode",{parentName:"p"},"preview")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"apply"),", but to handle more complex deployments we need to empower users to customize the deployment pipelines to fit their specific workflows and requirements. This includes the ability to define custom stages, add or remove steps, and integrate with third-party tools. With customizable pipelines, users can streamline their deployment process, automate repetitive tasks, and satisfy their own needs by themselves."),(0,o.kt)("h2",{id:"runtime-plugin"},"Runtime Plugin"),(0,o.kt)("p",null,"We have already supported IaaS cloud resources and Kubernetes resources, but we need a more flexible mechanism to support a broader range of on-premise infrastructure. By supporting a diverse set of infrastructures, we can help users avoid vendor lock-in, optimize their resource usage, and scale their applications across different regions and geographies."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/baa12f70.733a15a2.js b/assets/js/baa12f70.733a15a2.js deleted file mode 100644 index 0c7c944660f..00000000000 --- a/assets/js/baa12f70.733a15a2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5641],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),u=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},p=function(e){var r=u(e.components);return n.createElement(l.Provider,{value:r},e.children)},c={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=o,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||a;return t?n.createElement(f,s(s({ref:r},p),{},{components:t})):n.createElement(f,s({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,s=new Array(a);s[0]=d;var i={};for(var l in r)hasOwnProperty.call(r,l)&&(i[l]=r[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var u=2;u{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var n=t(87462),o=(t(67294),t(3905));const a={},s="Roadmap",i={unversionedId:"kusion/reference/roadmap",id:"kusion/reference/roadmap",title:"Roadmap",description:"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the GitHub Issue Tracker",source:"@site/docs/kusion/6-reference/3-roadmap.md",sourceDirName:"kusion/6-reference",slug:"/kusion/reference/roadmap",permalink:"/docs/next/kusion/reference/roadmap",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/3-roadmap.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Resource Naming Conventions",permalink:"/docs/next/kusion/reference/modules/naming-conventions"},next:{title:"Installation",permalink:"/docs/next/kusion/faq/install-error"}},l={},u=[{value:"Resource Ecosystem",id:"resource-ecosystem",level:2},{value:"App Progressive Rollout",id:"app-progressive-rollout",level:2},{value:"Custom Pipelines",id:"custom-pipelines",level:2},{value:"Runtime Plugin",id:"runtime-plugin",level:2}],p={toc:u};function c(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"roadmap"},"Roadmap"),(0,o.kt)("p",null,"For a finer-grained view into our roadmap and what is being worked on for a release, please refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"GitHub Issue Tracker")),(0,o.kt)("h2",{id:"resource-ecosystem"},"Resource Ecosystem"),(0,o.kt)("p",null,"We plan to expand the range of resource types that our platform can handle. This includes not only traditional cloud IaaS resources, but also popular cloud-native products such as Prometheus, istio and Argo. By supporting a wider variety of resources, we aim to address the heterogeneous needs of modern applications and allow users to harness the full power of the cloud-native technologies."),(0,o.kt)("h2",{id:"app-progressive-rollout"},"App Progressive Rollout"),(0,o.kt)("p",null,"One of the key challenges in delivering applications at scale is to balance the need for speed with the need for reliability. To help our users achieve this balance, we will introduce progressive rollout strategies, such as canary release, rolling release, and percentage release. These techniques enable users to test new features or versions on a small subset of their users or infrastructure before rolling them out to the entire system. By doing so, users can minimize the risk of downtime or errors caused by untested changes."),(0,o.kt)("h2",{id:"custom-pipelines"},"Custom Pipelines"),(0,o.kt)("p",null,"Thie current workflow of KusionStack is ",(0,o.kt)("inlineCode",{parentName:"p"},"write"),",",(0,o.kt)("inlineCode",{parentName:"p"},"preview")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"apply"),", but to handle more complex deployments we need to empower users to customize the deployment pipelines to fit their specific workflows and requirements. This includes the ability to define custom stages, add or remove steps, and integrate with third-party tools. With customizable pipelines, users can streamline their deployment process, automate repetitive tasks, and satisfy their own needs by themselves."),(0,o.kt)("h2",{id:"runtime-plugin"},"Runtime Plugin"),(0,o.kt)("p",null,"We have already supported IaaS cloud resources and Kubernetes resources, but we need a more flexible mechanism to support a broader range of on-premise infrastructure. By supporting a diverse set of infrastructures, we can help users avoid vendor lock-in, optimize their resource usage, and scale their applications across different regions and geographies."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bbff1c36.41c592be.js b/assets/js/bbff1c36.e41b8a00.js similarity index 61% rename from assets/js/bbff1c36.41c592be.js rename to assets/js/bbff1c36.e41b8a00.js index fe8ebc656ab..21f213efd8f 100644 --- a/assets/js/bbff1c36.41c592be.js +++ b/assets/js/bbff1c36.e41b8a00.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7202],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),u=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||i;return n?o.createElement(f,a(a({ref:t},l),{},{components:n})):o.createElement(f,a({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:1},a="Community",s={unversionedId:"community/intro/intro",id:"version-v0.10/community/intro/intro",title:"Community",description:"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.",source:"@site/versioned_docs/version-v0.10/community/intro/intro.md",sourceDirName:"community/intro",slug:"/community/intro/",permalink:"/docs/community/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/community/intro/intro.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"community"},c={},u=[],l={toc:u};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"community"},"Community"),(0,r.kt)("p",null,"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/orgs/KusionStack/discussions"},"Open a New Discussions on GitHub")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://app.slack.com/client/T03H6QE4VL0/setup-welcome"},"Contact Us on Slack"))),(0,r.kt)("h1",{id:"contributing"},"CONTRIBUTING"),(0,r.kt)("p",null,"We appreciate contributions from the community! To submit changes, please refer to the contributing file in the corresponding KusionStack repository. The files are available at the following links:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion/blob/main/docs/contributing.md"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/operating/blob/main/docs/contributing.md"},"Operating"))),(0,r.kt)("h1",{id:"code-of-conduct"},"CODE OF CONDUCT"),(0,r.kt)("p",null,"To make KusionStack a welcoming and harassment-free experience for everyone, we follow the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/CODE_OF_CONDUCT.md"},"KusionStack Code of Conduct"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7202],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=o.createContext({}),u=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||i;return n?o.createElement(f,a(a({ref:t},l),{},{components:n})):o.createElement(f,a({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const i={sidebar_position:1},a="Community",s={unversionedId:"community/intro/intro",id:"version-v0.10/community/intro/intro",title:"Community",description:"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below.",source:"@site/versioned_docs/version-v0.10/community/intro/intro.md",sourceDirName:"community/intro",slug:"/community/intro/",permalink:"/docs/community/intro/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/community/intro/intro.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"community"},c={},u=[],l={toc:u};function p(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"community"},"Community"),(0,r.kt)("p",null,"Welcome to the KusionStack open source community! Your participation is vital for the healthy growth of our open source projects. There are several ways you can get involved. You can create issues or fix bugs, improve documentation, or contribute code by submitting pull requests (PRs). Additionally, you can initiate discussions for new features by submitting KEPs or share your experiences and evangelize Kusion with others. The KusionStack project is always looking for new contributors and feedback. To get in touch, please refer to the links below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/orgs/KusionStack/discussions"},"Open a New Discussions on GitHub")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://app.slack.com/client/T03H6QE4VL0/setup-welcome"},"Contact Us on Slack"))),(0,r.kt)("h1",{id:"contributing"},"CONTRIBUTING"),(0,r.kt)("p",null,"We appreciate contributions from the community! To submit changes, please refer to the contributing file in the corresponding KusionStack repository. The files are available at the following links:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/kusion/blob/main/docs/contributing.md"},"Kusion")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/KusionStack/operating/blob/main/docs/contributing.md"},"Operating"))),(0,r.kt)("h1",{id:"code-of-conduct"},"CODE OF CONDUCT"),(0,r.kt)("p",null,"To make KusionStack a welcoming and harassment-free experience for everyone, we follow the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/CODE_OF_CONDUCT.md"},"KusionStack Code of Conduct"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bc5f1a80.0df8560d.js b/assets/js/bc5f1a80.0df8560d.js new file mode 100644 index 00000000000..8b8d4872fb2 --- /dev/null +++ b/assets/js/bc5f1a80.0df8560d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[835],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=c(r),u=o,b=m["".concat(s,".").concat(u)]||m[u]||d[u]||i;return r?n.createElement(b,a(a({ref:t},p),{},{components:r})):n.createElement(b,a({ref:t},p))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:1},a="Installation",l={unversionedId:"kusion/faq/install-error",id:"kusion/faq/install-error",title:"Installation",description:"1. Could not find libintl.dylib",source:"@site/docs/kusion/7-faq/1-install-error.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/install-error",permalink:"/docs/next/kusion/faq/install-error",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/7-faq/1-install-error.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Roadmap",permalink:"/docs/next/kusion/reference/roadmap"},next:{title:"KCL",permalink:"/docs/next/kusion/faq/kcl"}},s={},c=[{value:"1. Could not find libintl.dylib",id:"1-could-not-find-libintldylib",level:2},{value:"2. macOS system SSL related errors",id:"2-macos-system-ssl-related-errors",level:2}],p={toc:c};function d(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installation"},"Installation"),(0,o.kt)("h2",{id:"1-could-not-find-libintldylib"},"1. Could not find ",(0,o.kt)("inlineCode",{parentName:"h2"},"libintl.dylib")),(0,o.kt)("p",null,"This problem is that some tools depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"Gettext")," library, but macOS does not have this library by default. You can try to solve it in the following ways:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"brew install gettext")),(0,o.kt)("li",{parentName:"ol"},"Make sure ",(0,o.kt)("inlineCode",{parentName:"li"},"libintl.8.dylib")," exists in ",(0,o.kt)("inlineCode",{parentName:"li"},"/usr/local/opt/gettext/lib")," directory"),(0,o.kt)("li",{parentName:"ol"},"If brew is installed in another directory, the library can be created by copying it to the corresponding directory")),(0,o.kt)("h2",{id:"2-macos-system-ssl-related-errors"},"2. macOS system SSL related errors"),(0,o.kt)("p",null,"Openssl dylib library not found or SSL module is not available problem"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Install openssl (version 1.1) via brew")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"brew install openssl@1.1\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bc5f1a80.ee7d23c2.js b/assets/js/bc5f1a80.ee7d23c2.js deleted file mode 100644 index 672207f7ee0..00000000000 --- a/assets/js/bc5f1a80.ee7d23c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[835],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=c(r),u=o,b=m["".concat(s,".").concat(u)]||m[u]||d[u]||i;return r?n.createElement(b,a(a({ref:t},p),{},{components:r})):n.createElement(b,a({ref:t},p))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:1},a="Installation",l={unversionedId:"kusion/faq/install-error",id:"kusion/faq/install-error",title:"Installation",description:"1. Could not find libintl.dylib",source:"@site/docs/kusion/7-faq/1-install-error.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/install-error",permalink:"/docs/next/kusion/faq/install-error",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/7-faq/1-install-error.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"Roadmap",permalink:"/docs/next/kusion/reference/roadmap"},next:{title:"KCL",permalink:"/docs/next/kusion/faq/kcl"}},s={},c=[{value:"1. Could not find libintl.dylib",id:"1-could-not-find-libintldylib",level:2},{value:"2. macOS system SSL related errors",id:"2-macos-system-ssl-related-errors",level:2}],p={toc:c};function d(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installation"},"Installation"),(0,o.kt)("h2",{id:"1-could-not-find-libintldylib"},"1. Could not find ",(0,o.kt)("inlineCode",{parentName:"h2"},"libintl.dylib")),(0,o.kt)("p",null,"This problem is that some tools depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"Gettext")," library, but macOS does not have this library by default. You can try to solve it in the following ways:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"brew install gettext")),(0,o.kt)("li",{parentName:"ol"},"Make sure ",(0,o.kt)("inlineCode",{parentName:"li"},"libintl.8.dylib")," exists in ",(0,o.kt)("inlineCode",{parentName:"li"},"/usr/local/opt/gettext/lib")," directory"),(0,o.kt)("li",{parentName:"ol"},"If brew is installed in another directory, the library can be created by copying it to the corresponding directory")),(0,o.kt)("h2",{id:"2-macos-system-ssl-related-errors"},"2. macOS system SSL related errors"),(0,o.kt)("p",null,"Openssl dylib library not found or SSL module is not available problem"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Install openssl (version 1.1) via brew")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"brew install openssl@1.1\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c02a675f.92d65b30.js b/assets/js/c02a675f.92d65b30.js new file mode 100644 index 00000000000..869e3bb204c --- /dev/null +++ b/assets/js/c02a675f.92d65b30.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[800],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),p=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(i.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,g=c["".concat(i,".").concat(m)]||c[m]||d[m]||o;return n?r.createElement(g,l(l({ref:t},u),{},{components:n})):r.createElement(g,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=c;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,l[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},l="postgres",s={unversionedId:"kusion/reference/modules/workspace-configs/database/postgres",id:"kusion/reference/modules/workspace-configs/database/postgres",title:"postgres",description:"Module PostgreSQL",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/postgres",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/mysql"},next:{title:"monitoring",permalink:"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus"}},i={},p=[{value:"Module PostgreSQL",id:"module-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:p};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"postgres"},"postgres"),(0,a.kt)("h2",{id:"module-postgresql"},"Module PostgreSQL"),(0,a.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider managed postgres database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the postgres database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud postgres instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the postgres instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud postgres instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# PostgreSQL workspace configs for AWS RDS\nmodules: \n postgres: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# PostgreSQL workspace configs for Alicloud RDS\nmodules: \n postgres:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c02a675f.9d8def74.js b/assets/js/c02a675f.9d8def74.js deleted file mode 100644 index 9d8eed928d8..00000000000 --- a/assets/js/c02a675f.9d8def74.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[800],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),p=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(i.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,g=c["".concat(i,".").concat(m)]||c[m]||d[m]||o;return n?r.createElement(g,l(l({ref:t},u),{},{components:n})):r.createElement(g,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=c;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,l[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},l="postgres",s={unversionedId:"kusion/reference/modules/workspace-configs/database/postgres",id:"kusion/reference/modules/workspace-configs/database/postgres",title:"postgres",description:"Module PostgreSQL",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/postgres",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/mysql"},next:{title:"monitoring",permalink:"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus"}},i={},p=[{value:"Module PostgreSQL",id:"module-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:p};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"postgres"},"postgres"),(0,a.kt)("h2",{id:"module-postgresql"},"Module PostgreSQL"),(0,a.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider managed postgres database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the postgres database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud postgres instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the postgres instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud postgres instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# PostgreSQL workspace configs for AWS RDS\nmodules: \n postgres: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# PostgreSQL workspace configs for Alicloud RDS\nmodules: \n postgres:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c09b0fe7.660076a3.js b/assets/js/c09b0fe7.660076a3.js deleted file mode 100644 index 26afe6fb0c6..00000000000 --- a/assets/js/c09b0fe7.660076a3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1813],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(r),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||a;return r?n.createElement(m,s(s({ref:t},l),{},{components:r})):n.createElement(m,s({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={},s="kusion workspace create",i={unversionedId:"kusion/reference/commands/kusion-workspace-create",id:"kusion/reference/commands/kusion-workspace-create",title:"kusion workspace create",description:"Create a new workspace",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-create.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-create",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-create",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-create.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion version",permalink:"/docs/next/kusion/reference/commands/kusion-version"},next:{title:"kusion workspace delete",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-delete"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-create"},"kusion workspace create"),(0,o.kt)("p",null,"Create a new workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command creates a workspace with specified name and configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace create\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Create a new workspace\n kusion workspace create dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for create\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c09b0fe7.a66e4b54.js b/assets/js/c09b0fe7.a66e4b54.js new file mode 100644 index 00000000000..2d3ce26b684 --- /dev/null +++ b/assets/js/c09b0fe7.a66e4b54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1813],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(r),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||a;return r?n.createElement(m,i(i({ref:t},l),{},{components:r})):n.createElement(m,i({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={},i="kusion workspace create",s={unversionedId:"kusion/reference/commands/kusion-workspace-create",id:"kusion/reference/commands/kusion-workspace-create",title:"kusion workspace create",description:"Create a new workspace",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-create.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-create",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-create",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-create.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion version",permalink:"/docs/next/kusion/reference/commands/kusion-version"},next:{title:"kusion workspace delete",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-delete"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-create"},"kusion workspace create"),(0,o.kt)("p",null,"Create a new workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command creates a workspace with specified name and configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace create\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Create a new workspace\n kusion workspace create dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for create\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c15b59ba.582524dc.js b/assets/js/c15b59ba.582524dc.js new file mode 100644 index 00000000000..8930d1d613d --- /dev/null +++ b/assets/js/c15b59ba.582524dc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5731],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=u(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var u={};for(var s in t)hasOwnProperty.call(t,s)&&(u[s]=t[s]);u.originalType=e,u.mdxType="string"==typeof e?e:r,a[1]=u;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>u,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={},a="kusion build",u={unversionedId:"kusion/reference/commands/kusion-build",id:"kusion/reference/commands/kusion-build",title:"kusion build",description:"Build Kusion modules in a Stack to the Intent",source:"@site/docs/kusion/6-reference/1-commands/kusion-build.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-build",permalink:"/docs/next/kusion/reference/commands/kusion-build",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-build.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion apply",permalink:"/docs/next/kusion/reference/commands/kusion-apply"},next:{title:"kusion compile",permalink:"/docs/next/kusion/reference/commands/kusion-compile"}},s={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-build"},"kusion build"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("p",null," The command must be executed in a Stack or by specifying a Stack directory with the -w flag. You can provide a list of arguments to replace the placeholders defined in KCL, and use the --output flag to output the built results to a file"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion build [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Build main.k with arguments\n kusion build -D name=test -D age=18\n \n # Build main.k with work directory\n kusion build -w appops/demo/dev\n \n # Build configurations and write result into an output.yaml\n kusion build -o output.yaml\n \n # Build configurations with arguments from settings.yaml\n kusion build -Y settings.yaml\n \n # Build without output style and color\n kusion build --no-style=true\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -h, --help help for build\n --no-style Disable the output style and color\n -o, --output string Specify the output file\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c15b59ba.ef28dfaa.js b/assets/js/c15b59ba.ef28dfaa.js deleted file mode 100644 index 58042074c9f..00000000000 --- a/assets/js/c15b59ba.ef28dfaa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5731],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=u(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,f=d["".concat(s,".").concat(m)]||d[m]||c[m]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var u={};for(var s in t)hasOwnProperty.call(t,s)&&(u[s]=t[s]);u.originalType=e,u.mdxType="string"==typeof e?e:r,a[1]=u;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>u,toc:()=>l});var o=n(87462),r=(n(67294),n(3905));const i={},a="kusion build",u={unversionedId:"kusion/reference/commands/kusion-build",id:"kusion/reference/commands/kusion-build",title:"kusion build",description:"Build Kusion modules in a Stack to the Intent",source:"@site/docs/kusion/6-reference/1-commands/kusion-build.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-build",permalink:"/docs/next/kusion/reference/commands/kusion-build",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-build.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion apply",permalink:"/docs/next/kusion/reference/commands/kusion-apply"},next:{title:"kusion compile",permalink:"/docs/next/kusion/reference/commands/kusion-compile"}},s={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-build"},"kusion build"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"Build Kusion modules in a Stack to the Intent"),(0,r.kt)("p",null," The command must be executed in a Stack or by specifying a Stack directory with the -w flag. You can provide a list of arguments to replace the placeholders defined in KCL, and use the --output flag to output the built results to a file"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion build [flags]\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Build main.k with arguments\n kusion build -D name=test -D age=18\n \n # Build main.k with work directory\n kusion build -w appops/demo/dev\n \n # Build configurations and write result into an output.yaml\n kusion build -o output.yaml\n \n # Build configurations with arguments from settings.yaml\n kusion build -Y settings.yaml\n \n # Build without output style and color\n kusion build --no-style=true\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -h, --help help for build\n --no-style Disable the output style and color\n -o, --output string Specify the output file\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n")),(0,r.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c1bf8f22.5cf2e82b.js b/assets/js/c1bf8f22.5cf2e82b.js new file mode 100644 index 00000000000..d98c99a3125 --- /dev/null +++ b/assets/js/c1bf8f22.5cf2e82b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2347],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=a,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?i.createElement(m,r(r({ref:t},c),{},{components:n})):i.createElement(m,r({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Expose Application Service Deployed on CSP Kubernetes",s={unversionedId:"kusion/user-guides/cloud-resources/expose-service",id:"kusion/user-guides/cloud-resources/expose-service",title:"Expose Application Service Deployed on CSP Kubernetes",description:"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.",source:"@site/docs/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/expose-service",permalink:"/docs/next/kusion/user-guides/cloud-resources/expose-service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/next/kusion/user-guides/cloud-resources/database"},next:{title:"Deploy Application",permalink:"/docs/next/kusion/user-guides/working-with-k8s/deploy-application"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Expose Service Publicly",id:"expose-service-publicly",level:2},{value:"Set up Workspace",id:"set-up-workspace",level:3},{value:"Write Configuration Code",id:"write-configuration-code",level:3},{value:"Preview and Apply",id:"preview-and-apply",level:3},{value:"Verify Accessibility",id:"verify-accessibility",level:3},{value:"Expose Service Inside Cluster",id:"expose-service-inside-cluster",level:2},{value:"Summary",id:"summary",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"expose-application-service-deployed-on-csp-kubernetes"},"Expose Application Service Deployed on CSP Kubernetes"),(0,a.kt)("p",null,"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way. "),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on CSP Kubernetes. And the responsibilities of platform engineers and application developers are also clearly defined. In this article, ",(0,a.kt)("em",{parentName:"p"},(0,a.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/blob/main/example/nginx/dev/main.k"},"exposing the service of nginx"),' (referred to "the example" in the below)')," is given as an example."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Create a Kubernetes cluster, the following CSP Kubernetes services are supported."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/kubernetes"},"Alibaba Cloud Container Service for Kubernetes (ACK)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://aws.amazon.com/eks"},"Amazon Elastic Kubernetes Service (EKS)"),".")),(0,a.kt)("p",null,"Get the example from the official example repository."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/KusionStack/konfig.git && cd konfig/example/nginx\n")),(0,a.kt)("h2",{id:"expose-service-publicly"},"Expose Service Publicly"),(0,a.kt)("p",null,"If you want the application can be accessed from outside the cluster, you should expose the service publicly. Follow the steps below, you will simply hit the goal."),(0,a.kt)("h3",{id:"set-up-workspace"},"Set up Workspace"),(0,a.kt)("p",null,"Create the workspace as the target where the application will be deployed to. The workspace is usually set up by platform engineers, which contains platform-standard and application-agnostic configurations. The workspace configurations are organized through a YAML file."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n\nruntimes:\n kubernetes:\n kubeconfig: ""\n')),(0,a.kt)("p",null,"The YAML shown above gives an example of the workspace configuration to expose service on ACK. The file contains two top-level blocks ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),", and the block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),". "),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," contains the workspace configuration of module port, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"type: the CSP providing Kubernetes service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"alicloud")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"aws")),(0,a.kt)("li",{parentName:"ul"},"annotations: annotations attached to the service, should be a map"),(0,a.kt)("li",{parentName:"ul"},"labels: labels attached to the service, should be a map")),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," contains the kubernetes related configuration, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"kubeconfig: the kube-config file path, which is got after creating the cluster.")),(0,a.kt)("p",null,"You can also configure kube-config by environment variables, which has higher priority."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export KUBE_CONFIG=""\n')),(0,a.kt)("p",null,"Then, create the workspace with the configuration file. Be attention, the workspace name must be the same as the stack name. The following command creates a workspace named ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," with configuration file ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace create prod workspace.yaml\n")),(0,a.kt)("h3",{id:"write-configuration-code"},"Write Configuration Code"),(0,a.kt)("p",null,"After creating workspace, you should write application configuration code, which only contains simple and application-centric configurations. This step is usually accomplished by application developers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n nginx: c.Container {\n image = "nginx:1.25.2"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n protocol: "TCP"\n public: True\n }\n ]\n }\n}\n')),(0,a.kt)("p",null,"The code shown above describes how to expose service publicly on ACK. Kusion use schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port")," to describe the network configuration, the primary fields of Port are as follows:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"port: port number to expose service"),(0,a.kt)("li",{parentName:"ul"},"protocol: protocol to expose service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"TCP")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"UDP")),(0,a.kt)("li",{parentName:"ul"},"public: whether to public the service")),(0,a.kt)("p",null,"To public the service, you should set ",(0,a.kt)("inlineCode",{parentName:"p"},"public")," as True. Besides, schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," should be used to describe the workload configuration."),(0,a.kt)("p",null,"That's all what an application developer need to configure! Next, preview and apply the configuration, the application will get deployed and exposed publicly."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Kusion uses Load Balancer (LB) provided by the CSP to expose service publicly. For more detailed network configuration, please refer to ",(0,a.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/kusion/configuration-walkthrough/networking"},"Application Networking"))),(0,a.kt)("h3",{id:"preview-and-apply"},"Preview and Apply"),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion preview")," under the stack path, you will get what will be created in the real infrastructure. The picture below gives the preview result of the example. A Namespace, Service and Deployment will be created, which meets the expectation. The service name has a suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"public"),", which shows it can be accessed publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"preview-public",src:n(85091).Z,width:"1540",height:"262"})),(0,a.kt)("p",null,"Then, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes")," to do the real deploying job. Just a command and a few minutes, you have accomplished deploying application and expose it publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-public",src:n(97932).Z,width:"1558",height:"480"})),(0,a.kt)("h3",{id:"verify-accessibility"},"Verify Accessibility"),(0,a.kt)("p",null,"In the example, the kubernetes Namespace whose name is nginx, and a Service and Deployment under the Namespace should be created. Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl get")," to check, the Service whose type is ",(0,a.kt)("inlineCode",{parentName:"p"},"LoadBalancer")," and Deployment are created indeed. And the Service has ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," 106.5.190.109, which means it can be accessed from outside the cluster."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-public",src:n(68162).Z,width:"1662",height:"216"})),(0,a.kt)("p",null,"Visit the ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," via browser, the correct result is returned, which illustrates the servie get publicly exposed successfully."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"result-public",src:n(65377).Z,width:"1494",height:"682"})),(0,a.kt)("h2",{id:"expose-service-inside-cluster"},"Expose Service Inside Cluster"),(0,a.kt)("p",null,"If you only need the application can be accessed inside the cluster, just configure ",(0,a.kt)("inlineCode",{parentName:"p"},"Public")," as False in schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port"),". There is no need to change the workspace, which means an application developer can easily change a service exposure range, without the involvement of platform engineers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n ...\n ports: [\n n.Port {\n ...\n public: False\n }\n ]\n }\n}\n")),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes"),", the generated Service has suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"private"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-private",src:n(96057).Z,width:"1612",height:"494"})),(0,a.kt)("p",null,"And the Service type is ",(0,a.kt)("inlineCode",{parentName:"p"},"ClusterIP"),", only has ",(0,a.kt)("inlineCode",{parentName:"p"},"CLUSTER_IP")," and no ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL_IP"),", which means it cannot get accessed from outside the cluster. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-private",src:n(64600).Z,width:"1542",height:"210"})),(0,a.kt)("h2",{id:"summary"},"Summary"),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on the CSP Kubernetes. By platform engineers' setup of workspace, and application developers' configuration of schema Port, Kusion enables you expose service simply and efficiently."))}u.isMDXComponent=!0},96057:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-private-a1d1f3a1b5afac81cea19f189d08222d.png"},97932:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-public-d89cdb3ba9d96904e1820bfbcf4671d8.png"},64600:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-private-62ab14b1de35205866b64a0d63180450.png"},68162:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-public-66ffcb206b33c5fc6f1a779bc10b3e93.png"},85091:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/preview-public-eea90eec123cd2fc13536be2b645e900.png"},65377:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/result-public-4bf3f757b0a43c78464ec9bcd75a4b2f.png"}}]); \ No newline at end of file diff --git a/assets/js/c1bf8f22.d2bba25b.js b/assets/js/c1bf8f22.d2bba25b.js deleted file mode 100644 index 3f46976b00a..00000000000 --- a/assets/js/c1bf8f22.d2bba25b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2347],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var i=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=a,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?i.createElement(m,r(r({ref:t},c),{},{components:n})):i.createElement(m,r({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),a=(n(67294),n(3905));const o={},r="Expose Application Service Deployed on CSP Kubernetes",s={unversionedId:"kusion/user-guides/cloud-resources/expose-service",id:"kusion/user-guides/cloud-resources/expose-service",title:"Expose Application Service Deployed on CSP Kubernetes",description:"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way.",source:"@site/docs/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",sourceDirName:"kusion/5-user-guides/1-cloud-resources",slug:"/kusion/user-guides/cloud-resources/expose-service",permalink:"/docs/next/kusion/user-guides/cloud-resources/expose-service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/next/kusion/user-guides/cloud-resources/database"},next:{title:"Deploy Application",permalink:"/docs/next/kusion/user-guides/working-with-k8s/deploy-application"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Expose Service Publicly",id:"expose-service-publicly",level:2},{value:"Set up Workspace",id:"set-up-workspace",level:3},{value:"Write Configuration Code",id:"write-configuration-code",level:3},{value:"Preview and Apply",id:"preview-and-apply",level:3},{value:"Verify Accessibility",id:"verify-accessibility",level:3},{value:"Expose Service Inside Cluster",id:"expose-service-inside-cluster",level:2},{value:"Summary",id:"summary",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,i.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"expose-application-service-deployed-on-csp-kubernetes"},"Expose Application Service Deployed on CSP Kubernetes"),(0,a.kt)("p",null,"Deploying application on the Kubernetes provided by CSP (Cloud Service Provider) is convenient and reliable, which is adopted by many enterprises. Kusion has a good integration with CSP Kubernetes service. You can deploy your application to the Kubernetes cluster, and expose the service in a quite easy way. "),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on CSP Kubernetes. And the responsibilities of platform engineers and application developers are also clearly defined. In this article, ",(0,a.kt)("em",{parentName:"p"},(0,a.kt)("a",{parentName:"em",href:"https://github.com/KusionStack/konfig/blob/main/example/nginx/dev/main.k"},"exposing the service of nginx"),' (referred to "the example" in the below)')," is given as an example."),(0,a.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Create a Kubernetes cluster, the following CSP Kubernetes services are supported."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.alibabacloud.com/product/kubernetes"},"Alibaba Cloud Container Service for Kubernetes (ACK)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://aws.amazon.com/eks"},"Amazon Elastic Kubernetes Service (EKS)"),".")),(0,a.kt)("p",null,"Get the example from the official example repository."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/KusionStack/konfig.git && cd konfig/example/nginx\n")),(0,a.kt)("h2",{id:"expose-service-publicly"},"Expose Service Publicly"),(0,a.kt)("p",null,"If you want the application can be accessed from outside the cluster, you should expose the service publicly. Follow the steps below, you will simply hit the goal."),(0,a.kt)("h3",{id:"set-up-workspace"},"Set up Workspace"),(0,a.kt)("p",null,"Create the workspace as the target where the application will be deployed to. The workspace is usually set up by platform engineers, which contains platform-standard and application-agnostic configurations. The workspace configurations are organized through a YAML file."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n\nruntimes:\n kubernetes:\n kubeconfig: ""\n')),(0,a.kt)("p",null,"The YAML shown above gives an example of the workspace configuration to expose service on ACK. The file contains two top-level blocks ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),", and the block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," under ",(0,a.kt)("inlineCode",{parentName:"p"},"runtimes"),". "),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"port")," contains the workspace configuration of module port, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"type: the CSP providing Kubernetes service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"alicloud")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"aws")),(0,a.kt)("li",{parentName:"ul"},"annotations: annotations attached to the service, should be a map"),(0,a.kt)("li",{parentName:"ul"},"labels: labels attached to the service, should be a map")),(0,a.kt)("p",null,"The block ",(0,a.kt)("inlineCode",{parentName:"p"},"kubernetes")," contains the kubernetes related configuration, which has the following fields:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"kubeconfig: the kube-config file path, which is got after creating the cluster.")),(0,a.kt)("p",null,"You can also configure kube-config by environment variables, which has higher priority."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'export KUBE_CONFIG=""\n')),(0,a.kt)("p",null,"Then, create the workspace with the configuration file. Be attention, the workspace name must be the same as the stack name. The following command creates a workspace named ",(0,a.kt)("inlineCode",{parentName:"p"},"dev")," with configuration file ",(0,a.kt)("inlineCode",{parentName:"p"},"workspace.yaml"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace create prod workspace.yaml\n")),(0,a.kt)("h3",{id:"write-configuration-code"},"Write Configuration Code"),(0,a.kt)("p",null,"After creating workspace, you should write application configuration code, which only contains simple and application-centric configurations. This step is usually accomplished by application developers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n nginx: c.Container {\n image = "nginx:1.25.2"\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n protocol: "TCP"\n public: True\n }\n ]\n }\n}\n')),(0,a.kt)("p",null,"The code shown above describes how to expose service publicly on ACK. Kusion use schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port")," to describe the network configuration, the primary fields of Port are as follows:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"port: port number to expose service"),(0,a.kt)("li",{parentName:"ul"},"protocol: protocol to expose service, support ",(0,a.kt)("inlineCode",{parentName:"li"},"TCP")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"UDP")),(0,a.kt)("li",{parentName:"ul"},"public: whether to public the service")),(0,a.kt)("p",null,"To public the service, you should set ",(0,a.kt)("inlineCode",{parentName:"p"},"public")," as True. Besides, schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Service")," should be used to describe the workload configuration."),(0,a.kt)("p",null,"That's all what an application developer need to configure! Next, preview and apply the configuration, the application will get deployed and exposed publicly."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Kusion uses Load Balancer (LB) provided by the CSP to expose service publicly. For more detailed network configuration, please refer to ",(0,a.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/kusion/configuration-walkthrough/networking"},"Application Networking"))),(0,a.kt)("h3",{id:"preview-and-apply"},"Preview and Apply"),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion preview")," under the stack path, you will get what will be created in the real infrastructure. The picture below gives the preview result of the example. A Namespace, Service and Deployment will be created, which meets the expectation. The service name has a suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"public"),", which shows it can be accessed publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"preview-public",src:n(85091).Z,width:"1540",height:"262"})),(0,a.kt)("p",null,"Then, execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes")," to do the real deploying job. Just a command and a few minutes, you have accomplished deploying application and expose it publicly."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-public",src:n(97932).Z,width:"1558",height:"480"})),(0,a.kt)("h3",{id:"verify-accessibility"},"Verify Accessibility"),(0,a.kt)("p",null,"In the example, the kubernetes Namespace whose name is nginx, and a Service and Deployment under the Namespace should be created. Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl get")," to check, the Service whose type is ",(0,a.kt)("inlineCode",{parentName:"p"},"LoadBalancer")," and Deployment are created indeed. And the Service has ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," 106.5.190.109, which means it can be accessed from outside the cluster."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-public",src:n(68162).Z,width:"1662",height:"216"})),(0,a.kt)("p",null,"Visit the ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL-IP")," via browser, the correct result is returned, which illustrates the servie get publicly exposed successfully."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"result-public",src:n(65377).Z,width:"1494",height:"682"})),(0,a.kt)("h2",{id:"expose-service-inside-cluster"},"Expose Service Inside Cluster"),(0,a.kt)("p",null,"If you only need the application can be accessed inside the cluster, just configure ",(0,a.kt)("inlineCode",{parentName:"p"},"Public")," as False in schema ",(0,a.kt)("inlineCode",{parentName:"p"},"Port"),". There is no need to change the workspace, which means an application developer can easily change a service exposure range, without the involvement of platform engineers."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n\nnginx: ac.AppConfiguration {\n workload: wl.Service {\n ...\n ports: [\n n.Port {\n ...\n public: False\n }\n ]\n }\n}\n")),(0,a.kt)("p",null,"Execute ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply --yes"),", the generated Service has suffix ",(0,a.kt)("inlineCode",{parentName:"p"},"private"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"apply-private",src:n(96057).Z,width:"1612",height:"494"})),(0,a.kt)("p",null,"And the Service type is ",(0,a.kt)("inlineCode",{parentName:"p"},"ClusterIP"),", only has ",(0,a.kt)("inlineCode",{parentName:"p"},"CLUSTER_IP")," and no ",(0,a.kt)("inlineCode",{parentName:"p"},"EXTERNAL_IP"),", which means it cannot get accessed from outside the cluster. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"k8s-resource-private",src:n(64600).Z,width:"1542",height:"210"})),(0,a.kt)("h2",{id:"summary"},"Summary"),(0,a.kt)("p",null,"This tutorial demonstrates how to expose service of the application deployed on the CSP Kubernetes. By platform engineers' setup of workspace, and application developers' configuration of schema Port, Kusion enables you expose service simply and efficiently."))}u.isMDXComponent=!0},96057:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-private-a1d1f3a1b5afac81cea19f189d08222d.png"},97932:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/apply-public-d89cdb3ba9d96904e1820bfbcf4671d8.png"},64600:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-private-62ab14b1de35205866b64a0d63180450.png"},68162:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/k8s-resource-public-66ffcb206b33c5fc6f1a779bc10b3e93.png"},85091:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/preview-public-eea90eec123cd2fc13536be2b645e900.png"},65377:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/result-public-4bf3f757b0a43c78464ec9bcd75a4b2f.png"}}]); \ No newline at end of file diff --git a/assets/js/c2884f74.27697d2b.js b/assets/js/c2884f74.27697d2b.js deleted file mode 100644 index 1523ef0f71c..00000000000 --- a/assets/js/c2884f74.27697d2b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9216],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,i=new Array(s);i[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const s={},i="kusion destroy",a={unversionedId:"kusion/reference/commands/kusion-destroy",id:"version-v0.10/kusion/reference/commands/kusion-destroy",title:"kusion destroy",description:"Destroy resources within the stack.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-destroy.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-destroy",permalink:"/docs/kusion/reference/commands/kusion-destroy",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-destroy.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion compile",permalink:"/docs/kusion/reference/commands/kusion-compile"},next:{title:"kusion init",permalink:"/docs/kusion/reference/commands/kusion-init"}},c={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-destroy"},"kusion destroy"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("p",null," Please note that the destroy command does NOT perform resource version checks. Therefore, if someone submits an update to a resource at the same time you execute a destroy command, their update will be lost along with the rest of the resource."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion destroy [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete resources of current stack\n kusion destroy\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details after previewing it\n -h, --help help for destroy\n --operator string Specify the operator\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c2884f74.d0b0ad50.js b/assets/js/c2884f74.d0b0ad50.js new file mode 100644 index 00000000000..c8c54bf4606 --- /dev/null +++ b/assets/js/c2884f74.d0b0ad50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9216],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||s;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,i=new Array(s);i[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const s={},i="kusion destroy",a={unversionedId:"kusion/reference/commands/kusion-destroy",id:"version-v0.10/kusion/reference/commands/kusion-destroy",title:"kusion destroy",description:"Destroy resources within the stack.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-destroy.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-destroy",permalink:"/docs/kusion/reference/commands/kusion-destroy",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-destroy.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion compile",permalink:"/docs/kusion/reference/commands/kusion-compile"},next:{title:"kusion init",permalink:"/docs/kusion/reference/commands/kusion-init"}},c={},l=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-destroy"},"kusion destroy"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Destroy resources within the stack."),(0,o.kt)("p",null," Please note that the destroy command does NOT perform resource version checks. Therefore, if someone submits an update to a resource at the same time you execute a destroy command, their update will be lost along with the rest of the resource."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion destroy [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Delete resources of current stack\n kusion destroy\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -D, --argument stringToString Specify the top-level argument (default [])\n -C, --backend-config strings backend-config config state storage backend\n --backend-type string backend-type specify state storage backend\n -d, --detail Automatically show plan details after previewing it\n -h, --help help for destroy\n --operator string Specify the operator\n -Y, --setting strings Specify the command line setting files\n -w, --workdir string Specify the work directory\n -y, --yes Automatically approve and perform the update after previewing it\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c311d7f4.401ed809.js b/assets/js/c311d7f4.401ed809.js deleted file mode 100644 index 1bdf11fffd0..00000000000 --- a/assets/js/c311d7f4.401ed809.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4446],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,f=m["".concat(i,".").concat(u)]||m[u]||c[u]||a;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},l="ResourceConsist",s={unversionedId:"operating/manuals/resourceconsist",id:"operating/manuals/resourceconsist",title:"ResourceConsist",description:"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following",source:"@site/docs/operating/manuals/resourceconsist.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/resourceconsist",permalink:"/docs/next/operating/manuals/resourceconsist",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/resourceconsist.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"CollaSet",permalink:"/docs/next/operating/manuals/collaset"},next:{title:"PodTransitionRule",permalink:"/docs/next/operating/manuals/podtransitionrule"}},i={},p=[{value:"Tutorials",id:"tutorials",level:2},{value:"adapters",id:"adapters",level:3},{value:"alibabacloudslb adapter",id:"alibabacloudslb-adapter",level:4},{value:"experimental/adapters",id:"experimentaladapters",level:3},{value:"demo adapter",id:"demo-adapter",level:3}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resourceconsist"},"ResourceConsist"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist/blob/main/README.md"},(0,o.kt)("strong",{parentName:"a"},"ResourceConsist"))," aims to make a customized controller can be realized easily, and offering the ability of following\n",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," for controllers."),(0,o.kt)("h2",{id:"tutorials"},"Tutorials"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"kusionstack.io/resourceconsit")," mainly consists of frame, experimental/adapters and adapters."),(0,o.kt)("p",null,"The frame, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame"),", is used for adapters starting a controller, which handles\nReconcile and Employer/Employees' spec&status. If you wrote an adapter in your own repo, you can import\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/webhook"),",\n]and call AddToMgr to start a controller."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"webhookAdapter is only necessary to be implemented for controllers following PodOpsLifecycle.")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n controllerframe "kusionstack.io/resourceconsist/pkg/frame/controller"\n webhookframe "kusionstack.io/resourceconsist/pkg/frame/webhook"\n)\n\nfunc main() {\n controllerframe.AddToMgr(manager, yourOwnControllerAdapter)\n webhookframe.AddToMgr(manager, yourOwnWebhookAdapter)\n}\n')),(0,o.kt)("h3",{id:"adapters"},"adapters"),(0,o.kt)("p",null,"The adapters, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters"),", consists of built-in adapters. You can start a\ncontroller with built-in adapters just calling AddBuiltinControllerAdaptersToMgr and AddBuiltinWebhookAdaptersToMgr,\npassing built-in adapters' names. Currently, an aliababacloudslb adapter has released. You can use it as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "kusionstack.io/resourceconsist/pkg/adapters"\n)\n\nfunc main() {\n adapters.AddBuiltinControllerAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n adapters.AddBuiltinWebhookAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n}\n')),(0,o.kt)("p",null,"Built-in adapters can also be used like how frame used. You can call NewAdapter from a certain built-in adapter pkg\nand the call frame.AddToMgr to start a controller/webhook"),(0,o.kt)("p",null,"More built-in adapters will be implemented in the future. To make this repo stable, all new built-in adapters will\nbe added to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/experimental/adapters")," first, and then moved to\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters")," until ready to be released."),(0,o.kt)("h4",{id:"alibabacloudslb-adapter"},"alibabacloudslb adapter"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb")," is an adapter that implements ReconcileAdapter. It follows ",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," to\nhandle various scenarios during pod operations, such as creating a new pod, deleting an existing pod, or handling\nchanges to pod configurations. This adapter ensures minimal traffic loss and provides a seamless experience for users\naccessing services load balanced by Alibaba Cloud SLB."),(0,o.kt)("p",null,"In ",(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb"),", the real server is removed from SLB before pod operation in ACK. The LB\nmanagement and real server management are handled by CCM in ACK. Since alibabacloudslb adapter follows PodOpsLifecycle\nand real servers are managed by CCM, ReconcileLifecycleOptions should be implemented. If the cluster is not in ACK or\nCCM is not working in the cluster, the alibabacloudslb controller should implement additional methods of ReconcileAdapter."),(0,o.kt)("h3",{id:"experimentaladapters"},"experimental/adapters"),(0,o.kt)("p",null,"The experimental/adapters is more like a pre-release pkg for built-in adapters. Usage of experimental/adapters is same\nwith built-in adapters, and be aware that ",(0,o.kt)("strong",{parentName:"p"},"DO NOT USE EXPERIMENTAL/ADAPTERS IN PRODUCTION")),(0,o.kt)("h3",{id:"demo-adapter"},"demo adapter"),(0,o.kt)("p",null,"A demo is implemented in ",(0,o.kt)("inlineCode",{parentName:"p"},"resource_controller_suite_test.go"),". In the demo controller, the employer is represented\nas a service and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoServiceStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n }\n}\n')),(0,o.kt)("p",null,"The employee is represented as a pod and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoPodStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n EmployeeStatuses: PodEmployeeStatuses{\n Ip: string,\n Ipv6: string,\n LifecycleReady: bool,\n ExtraStatus: PodExtraStatus{\n TrafficOn: bool,\n TrafficWeight: int,\n },\n }\n}\n")),(0,o.kt)("p",null,"The DemoResourceProviderClient is a fake client that handles backend provider resources related to the employer/employee\n(service/pods). In the Demo Controller, ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"\nare mocked as resources in the backend provider."),(0,o.kt)("p",null,"How the demo controller adapter realized will be introduced in detail as follows,\n",(0,o.kt)("inlineCode",{parentName:"p"},"DemoControllerAdapter")," was defined, including a kubernetes client and a resourceProviderClient. What included in\nthe Adapter struct can be defined as needed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type DemoControllerAdapter struct {\n client.Client\n resourceProviderClient *DemoResourceProviderClient\n}\n")),(0,o.kt)("p",null,"Declaring that the DemoControllerAdapter implemented ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileAdapter")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),".\nImplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"RconcileAdapter")," is a must action, while ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," isn't, check the remarks\nfor ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller/types.go")," to find why."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"var _ ReconcileAdapter = &DemoControllerAdapter{}\nvar _ ReconcileLifecycleOptions = &DemoControllerAdapter{}\n")),(0,o.kt)("p",null,"Following two methods for DemoControllerAdapter inplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),", defines whether\nDemoControllerAdapter following PodOpsLifecycle and need record employees."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"func (r *DemoControllerAdapter) FollowPodOpsLifeCycle() bool {\n return true\n}\n\nfunc (r *DemoControllerAdapter) NeedRecordEmployees() bool {\n return needRecordEmployees\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"IEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"IEmployee")," are interfaces that includes several methods indicating the status employer and\nemployee."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type IEmployer interface {\n GetEmployerId() string\n GetEmployerStatuses() interface{}\n EmployerEqual(employer IEmployer) (bool, error)\n}\n\ntype IEmployee interface {\n GetEmployeeId() string\n GetEmployeeName() string\n GetEmployeeStatuses() interface{}\n EmployeeEqual(employee IEmployee) (bool, error)\n}\n\ntype DemoServiceStatus struct {\n EmployerId string\n EmployerStatuses DemoServiceDetails\n}\n\ntype DemoServiceDetails struct {\n RemoteVIP string\n RemoteVIPQPS int\n}\n\ntype DemoPodStatus struct {\n EmployeeId string\n EmployeeName string\n EmployeeStatuses PodEmployeeStatuses\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," returns all employees' names selected by employer, here is pods' names selected by\nservice. ",(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," is used for ensuring LifecycleFinalizer and ExpectedFinalizer, so you can give\nit an empty return if your adapter doesn't follow PodOpsLifecycle."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) {\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n selected := make([]string, len(podList.Items))\n for idx, pod := range podList.Items {\n selected[idx] = pod.Name\n }\n\n return selected, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployer")," defines what is expected under the spec of employer and what is\ncurrent status, like the load balancer from a cloud provider. Here in the demo adapter, expected is defined by hardcode\nand current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return nil, nil\n }\n var expect []IEmployer\n expect = append(expect, DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n },\n })\n return expect, nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n var current []IEmployer\n\n req := &DemoResourceVipOps{}\n resp, err := r.resourceProviderClient.QueryVip(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource vip query resp is nil")\n }\n\n for _, employerStatus := range resp.VipStatuses {\n current = append(current, employerStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles creation/update/deletion of resources related to employer on\nrelated backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles\n",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n\n toCreateDemoServiceStatus := make([]DemoServiceStatus, len(toCreates))\n for idx, create := range toCreates {\n createDemoServiceStatus, ok := create.(DemoServiceStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreates employer is not DemoServiceStatus")\n }\n toCreateDemoServiceStatus[idx] = createDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.CreateVip(&DemoResourceVipOps{\n VipStatuses: toCreateDemoServiceStatus,\n })\n if err != nil {\n return nil, toCreates, err\n }\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoServiceStatus := make([]DemoServiceStatus, len(toUpdates))\n for idx, update := range toUpdates {\n updateDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdates employer is not DemoServiceStatus")\n }\n toUpdateDemoServiceStatus[idx] = updateDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.UpdateVip(&DemoResourceVipOps{\n VipStatuses: toUpdateDemoServiceStatus,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoServiceStatus := make([]DemoServiceStatus, len(toDeletes))\n for idx, update := range toDeletes {\n deleteDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDeletes employer is not DemoServiceStatus")\n }\n toDeleteDemoServiceStatus[idx] = deleteDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.DeleteVip(&DemoResourceVipOps{\n VipStatuses: toDeleteDemoServiceStatus,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n return toDeletes, nil, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployee"),"and",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployee")," defines what is expected under the spec of employer and employees\nand what is current status, like real servers under the load balancer from a cloud provider. Here in the demo adapter,\nexpected is calculated from pods and current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'// GetExpectEmployeeStatus return expect employee status\nfunc (r *DemoControllerAdapter) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return []IEmployee{}, nil\n }\n\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n expected := make([]IEmployee, len(podList.Items))\n expectIdx := 0\n for _, pod := range podList.Items {\n if !pod.DeletionTimestamp.IsZero() {\n continue\n }\n status := DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n }\n employeeStatuses, err := GetCommonPodEmployeeStatus(&pod)\n if err != nil {\n return nil, err\n }\n extraStatus := PodExtraStatus{}\n if employeeStatuses.LifecycleReady {\n extraStatus.TrafficOn = true\n extraStatus.TrafficWeight = 100\n } else {\n extraStatus.TrafficOn = false\n extraStatus.TrafficWeight = 0\n }\n employeeStatuses.ExtraStatus = extraStatus\n status.EmployeeStatuses = employeeStatuses\n expected[expectIdx] = status\n expectIdx++\n }\n\n return expected[:expectIdx], nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n var current []IEmployee\n req := &DemoResourceRsOps{}\n resp, err := r.resourceProviderClient.QueryRealServer(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource rs query resp is nil")\n }\n\n for _, rsStatus := range resp.RsStatuses {\n current = append(current, rsStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees")," handles creation/update/deletion of resources related to employee\non related backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees"),"\nhandles ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n toCreateDemoPodStatuses := make([]DemoPodStatus, len(toCreates))\n\n for idx, toCreate := range toCreates {\n podStatus, ok := toCreate.(DemoPodStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreate is not DemoPodStatus")\n }\n toCreateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.CreateRealServer(&DemoResourceRsOps{\n RsStatuses: toCreateDemoPodStatuses,\n })\n if err != nil {\n return nil, toCreates, err\n }\n\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoPodStatuses := make([]DemoPodStatus, len(toUpdates))\n\n for idx, toUpdate := range toUpdates {\n podStatus, ok := toUpdate.(DemoPodStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdate is not DemoPodStatus")\n }\n toUpdateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.UpdateRealServer(&DemoResourceRsOps{\n RsStatuses: toUpdateDemoPodStatuses,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoPodStatuses := make([]DemoPodStatus, len(toDeletes))\n\n for idx, toDelete := range toDeletes {\n podStatus, ok := toDelete.(DemoPodStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDelete is not DemoPodStatus")\n }\n toDeleteDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.DeleteRealServer(&DemoResourceRsOps{\n RsStatuses: toDeleteDemoPodStatuses,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n\n return toDeletes, nil, nil\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c311d7f4.d147804d.js b/assets/js/c311d7f4.d147804d.js new file mode 100644 index 00000000000..afbf48a0d82 --- /dev/null +++ b/assets/js/c311d7f4.d147804d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4446],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,f=m["".concat(i,".").concat(u)]||m[u]||c[u]||a;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},l="ResourceConsist",s={unversionedId:"operating/manuals/resourceconsist",id:"operating/manuals/resourceconsist",title:"ResourceConsist",description:"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following",source:"@site/docs/operating/manuals/resourceconsist.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/resourceconsist",permalink:"/docs/next/operating/manuals/resourceconsist",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/operating/manuals/resourceconsist.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"CollaSet",permalink:"/docs/next/operating/manuals/collaset"},next:{title:"PodTransitionRule",permalink:"/docs/next/operating/manuals/podtransitionrule"}},i={},p=[{value:"Tutorials",id:"tutorials",level:2},{value:"adapters",id:"adapters",level:3},{value:"alibabacloudslb adapter",id:"alibabacloudslb-adapter",level:4},{value:"experimental/adapters",id:"experimentaladapters",level:3},{value:"demo adapter",id:"demo-adapter",level:3}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resourceconsist"},"ResourceConsist"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist/blob/main/README.md"},(0,o.kt)("strong",{parentName:"a"},"ResourceConsist"))," aims to make a customized controller can be realized easily, and offering the ability of following\n",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," for controllers."),(0,o.kt)("h2",{id:"tutorials"},"Tutorials"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"kusionstack.io/resourceconsit")," mainly consists of frame, experimental/adapters and adapters."),(0,o.kt)("p",null,"The frame, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame"),", is used for adapters starting a controller, which handles\nReconcile and Employer/Employees' spec&status. If you wrote an adapter in your own repo, you can import\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/webhook"),",\n]and call AddToMgr to start a controller."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"webhookAdapter is only necessary to be implemented for controllers following PodOpsLifecycle.")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n controllerframe "kusionstack.io/resourceconsist/pkg/frame/controller"\n webhookframe "kusionstack.io/resourceconsist/pkg/frame/webhook"\n)\n\nfunc main() {\n controllerframe.AddToMgr(manager, yourOwnControllerAdapter)\n webhookframe.AddToMgr(manager, yourOwnWebhookAdapter)\n}\n')),(0,o.kt)("h3",{id:"adapters"},"adapters"),(0,o.kt)("p",null,"The adapters, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters"),", consists of built-in adapters. You can start a\ncontroller with built-in adapters just calling AddBuiltinControllerAdaptersToMgr and AddBuiltinWebhookAdaptersToMgr,\npassing built-in adapters' names. Currently, an aliababacloudslb adapter has released. You can use it as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "kusionstack.io/resourceconsist/pkg/adapters"\n)\n\nfunc main() {\n adapters.AddBuiltinControllerAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n adapters.AddBuiltinWebhookAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n}\n')),(0,o.kt)("p",null,"Built-in adapters can also be used like how frame used. You can call NewAdapter from a certain built-in adapter pkg\nand the call frame.AddToMgr to start a controller/webhook"),(0,o.kt)("p",null,"More built-in adapters will be implemented in the future. To make this repo stable, all new built-in adapters will\nbe added to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/experimental/adapters")," first, and then moved to\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters")," until ready to be released."),(0,o.kt)("h4",{id:"alibabacloudslb-adapter"},"alibabacloudslb adapter"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb")," is an adapter that implements ReconcileAdapter. It follows ",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," to\nhandle various scenarios during pod operations, such as creating a new pod, deleting an existing pod, or handling\nchanges to pod configurations. This adapter ensures minimal traffic loss and provides a seamless experience for users\naccessing services load balanced by Alibaba Cloud SLB."),(0,o.kt)("p",null,"In ",(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb"),", the real server is removed from SLB before pod operation in ACK. The LB\nmanagement and real server management are handled by CCM in ACK. Since alibabacloudslb adapter follows PodOpsLifecycle\nand real servers are managed by CCM, ReconcileLifecycleOptions should be implemented. If the cluster is not in ACK or\nCCM is not working in the cluster, the alibabacloudslb controller should implement additional methods of ReconcileAdapter."),(0,o.kt)("h3",{id:"experimentaladapters"},"experimental/adapters"),(0,o.kt)("p",null,"The experimental/adapters is more like a pre-release pkg for built-in adapters. Usage of experimental/adapters is same\nwith built-in adapters, and be aware that ",(0,o.kt)("strong",{parentName:"p"},"DO NOT USE EXPERIMENTAL/ADAPTERS IN PRODUCTION")),(0,o.kt)("h3",{id:"demo-adapter"},"demo adapter"),(0,o.kt)("p",null,"A demo is implemented in ",(0,o.kt)("inlineCode",{parentName:"p"},"resource_controller_suite_test.go"),". In the demo controller, the employer is represented\nas a service and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoServiceStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n }\n}\n')),(0,o.kt)("p",null,"The employee is represented as a pod and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoPodStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n EmployeeStatuses: PodEmployeeStatuses{\n Ip: string,\n Ipv6: string,\n LifecycleReady: bool,\n ExtraStatus: PodExtraStatus{\n TrafficOn: bool,\n TrafficWeight: int,\n },\n }\n}\n")),(0,o.kt)("p",null,"The DemoResourceProviderClient is a fake client that handles backend provider resources related to the employer/employee\n(service/pods). In the Demo Controller, ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"\nare mocked as resources in the backend provider."),(0,o.kt)("p",null,"How the demo controller adapter realized will be introduced in detail as follows,\n",(0,o.kt)("inlineCode",{parentName:"p"},"DemoControllerAdapter")," was defined, including a kubernetes client and a resourceProviderClient. What included in\nthe Adapter struct can be defined as needed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type DemoControllerAdapter struct {\n client.Client\n resourceProviderClient *DemoResourceProviderClient\n}\n")),(0,o.kt)("p",null,"Declaring that the DemoControllerAdapter implemented ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileAdapter")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),".\nImplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"RconcileAdapter")," is a must action, while ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," isn't, check the remarks\nfor ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller/types.go")," to find why."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"var _ ReconcileAdapter = &DemoControllerAdapter{}\nvar _ ReconcileLifecycleOptions = &DemoControllerAdapter{}\n")),(0,o.kt)("p",null,"Following two methods for DemoControllerAdapter inplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),", defines whether\nDemoControllerAdapter following PodOpsLifecycle and need record employees."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"func (r *DemoControllerAdapter) FollowPodOpsLifeCycle() bool {\n return true\n}\n\nfunc (r *DemoControllerAdapter) NeedRecordEmployees() bool {\n return needRecordEmployees\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"IEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"IEmployee")," are interfaces that includes several methods indicating the status employer and\nemployee."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type IEmployer interface {\n GetEmployerId() string\n GetEmployerStatuses() interface{}\n EmployerEqual(employer IEmployer) (bool, error)\n}\n\ntype IEmployee interface {\n GetEmployeeId() string\n GetEmployeeName() string\n GetEmployeeStatuses() interface{}\n EmployeeEqual(employee IEmployee) (bool, error)\n}\n\ntype DemoServiceStatus struct {\n EmployerId string\n EmployerStatuses DemoServiceDetails\n}\n\ntype DemoServiceDetails struct {\n RemoteVIP string\n RemoteVIPQPS int\n}\n\ntype DemoPodStatus struct {\n EmployeeId string\n EmployeeName string\n EmployeeStatuses PodEmployeeStatuses\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," returns all employees' names selected by employer, here is pods' names selected by\nservice. ",(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," is used for ensuring LifecycleFinalizer and ExpectedFinalizer, so you can give\nit an empty return if your adapter doesn't follow PodOpsLifecycle."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) {\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n selected := make([]string, len(podList.Items))\n for idx, pod := range podList.Items {\n selected[idx] = pod.Name\n }\n\n return selected, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployer")," defines what is expected under the spec of employer and what is\ncurrent status, like the load balancer from a cloud provider. Here in the demo adapter, expected is defined by hardcode\nand current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return nil, nil\n }\n var expect []IEmployer\n expect = append(expect, DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n },\n })\n return expect, nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n var current []IEmployer\n\n req := &DemoResourceVipOps{}\n resp, err := r.resourceProviderClient.QueryVip(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource vip query resp is nil")\n }\n\n for _, employerStatus := range resp.VipStatuses {\n current = append(current, employerStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles creation/update/deletion of resources related to employer on\nrelated backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles\n",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n\n toCreateDemoServiceStatus := make([]DemoServiceStatus, len(toCreates))\n for idx, create := range toCreates {\n createDemoServiceStatus, ok := create.(DemoServiceStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreates employer is not DemoServiceStatus")\n }\n toCreateDemoServiceStatus[idx] = createDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.CreateVip(&DemoResourceVipOps{\n VipStatuses: toCreateDemoServiceStatus,\n })\n if err != nil {\n return nil, toCreates, err\n }\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoServiceStatus := make([]DemoServiceStatus, len(toUpdates))\n for idx, update := range toUpdates {\n updateDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdates employer is not DemoServiceStatus")\n }\n toUpdateDemoServiceStatus[idx] = updateDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.UpdateVip(&DemoResourceVipOps{\n VipStatuses: toUpdateDemoServiceStatus,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoServiceStatus := make([]DemoServiceStatus, len(toDeletes))\n for idx, update := range toDeletes {\n deleteDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDeletes employer is not DemoServiceStatus")\n }\n toDeleteDemoServiceStatus[idx] = deleteDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.DeleteVip(&DemoResourceVipOps{\n VipStatuses: toDeleteDemoServiceStatus,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n return toDeletes, nil, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployee"),"and",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployee")," defines what is expected under the spec of employer and employees\nand what is current status, like real servers under the load balancer from a cloud provider. Here in the demo adapter,\nexpected is calculated from pods and current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'// GetExpectEmployeeStatus return expect employee status\nfunc (r *DemoControllerAdapter) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return []IEmployee{}, nil\n }\n\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n expected := make([]IEmployee, len(podList.Items))\n expectIdx := 0\n for _, pod := range podList.Items {\n if !pod.DeletionTimestamp.IsZero() {\n continue\n }\n status := DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n }\n employeeStatuses, err := GetCommonPodEmployeeStatus(&pod)\n if err != nil {\n return nil, err\n }\n extraStatus := PodExtraStatus{}\n if employeeStatuses.LifecycleReady {\n extraStatus.TrafficOn = true\n extraStatus.TrafficWeight = 100\n } else {\n extraStatus.TrafficOn = false\n extraStatus.TrafficWeight = 0\n }\n employeeStatuses.ExtraStatus = extraStatus\n status.EmployeeStatuses = employeeStatuses\n expected[expectIdx] = status\n expectIdx++\n }\n\n return expected[:expectIdx], nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n var current []IEmployee\n req := &DemoResourceRsOps{}\n resp, err := r.resourceProviderClient.QueryRealServer(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource rs query resp is nil")\n }\n\n for _, rsStatus := range resp.RsStatuses {\n current = append(current, rsStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees")," handles creation/update/deletion of resources related to employee\non related backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees"),"\nhandles ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n toCreateDemoPodStatuses := make([]DemoPodStatus, len(toCreates))\n\n for idx, toCreate := range toCreates {\n podStatus, ok := toCreate.(DemoPodStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreate is not DemoPodStatus")\n }\n toCreateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.CreateRealServer(&DemoResourceRsOps{\n RsStatuses: toCreateDemoPodStatuses,\n })\n if err != nil {\n return nil, toCreates, err\n }\n\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoPodStatuses := make([]DemoPodStatus, len(toUpdates))\n\n for idx, toUpdate := range toUpdates {\n podStatus, ok := toUpdate.(DemoPodStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdate is not DemoPodStatus")\n }\n toUpdateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.UpdateRealServer(&DemoResourceRsOps{\n RsStatuses: toUpdateDemoPodStatuses,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoPodStatuses := make([]DemoPodStatus, len(toDeletes))\n\n for idx, toDelete := range toDeletes {\n podStatus, ok := toDelete.(DemoPodStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDelete is not DemoPodStatus")\n }\n toDeleteDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.DeleteRealServer(&DemoResourceRsOps{\n RsStatuses: toDeleteDemoPodStatuses,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n\n return toDeletes, nil, nil\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c31a6c64.8ec97530.js b/assets/js/c31a6c64.8ec97530.js new file mode 100644 index 00000000000..1c66e274e14 --- /dev/null +++ b/assets/js/c31a6c64.8ec97530.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6721],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(t),m=r,h=u["".concat(p,".").concat(m)]||u[m]||d[m]||i;return t?o.createElement(h,a(a({ref:n},c),{},{components:t})):o.createElement(h,a({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=u;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),r=(t(67294),t(3905));const i={},a="Configure Containers",l={unversionedId:"kusion/guides/working-with-k8s/container",id:"version-v0.9/kusion/guides/working-with-k8s/container",title:"Configure Containers",description:"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/2-container.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/container",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/2-container.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application"},next:{title:"Expose Service",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/service"}},p={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Example",id:"example",level:2},{value:"Apply",id:"apply",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-containers"},"Configure Containers"),(0,r.kt)("p",null,"You can manage container-level configurations in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,r.kt)("inlineCode",{parentName:"p"},"containers")," field (under the ",(0,r.kt)("inlineCode",{parentName:"p"},"workload")," schemas). By default, everything defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"containers")," field will be treated as application containers. Sidecar containers will be supported in a future version of kusion."),(0,r.kt)("p",null,"For the full ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,r.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-container"},"here")," for more details."),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,r.kt)("h2",{id:"example"},"Example"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,r.kt)("h2",{id:"apply"},"Apply"),(0,r.kt)("p",null,"Re-run steps in ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new container configuration can be applied."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS UnChanged v1:Service:helloworld:helloworld-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nUpdate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,r.kt)("h2",{id:"validation"},"Validation"),(0,r.kt)("p",null,"We can verify the container (in the deployment template) now has the updated attributes as defined in the container configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kubectl get deployment -n helloworld -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n - name: env1\n value: VALUE\n - name: env2\n value: VALUE2\n image: gcr.io/google-samples/gb-frontend:v4\n imagePullPolicy: IfNotPresent\n name: helloworld\n readinessProbe:\n failureThreshold: 3\n httpGet:\n host: localhost\n path: /\n port: 80\n scheme: HTTP\n initialDelaySeconds: 10\n periodSeconds: 10\n successThreshold: 1\n timeoutSeconds: 1\n resources:\n limits:\n cpu: 500m\n memory: 512M\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c31a6c64.dbba3d47.js b/assets/js/c31a6c64.dbba3d47.js deleted file mode 100644 index 1d0752eb87c..00000000000 --- a/assets/js/c31a6c64.dbba3d47.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6721],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var p=o.createContext({}),s=function(e){var n=o.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(p.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(t),m=r,h=u["".concat(p,".").concat(m)]||u[m]||d[m]||i;return t?o.createElement(h,a(a({ref:n},c),{},{components:t})):o.createElement(h,a({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=u;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=t(87462),r=(t(67294),t(3905));const i={},a="Configure Containers",l={unversionedId:"kusion/guides/working-with-k8s/container",id:"version-v0.9/kusion/guides/working-with-k8s/container",title:"Configure Containers",description:"You can manage container-level configurations in the AppConfiguration model via the containers field (under the workload schemas). By default, everything defined in the containers field will be treated as application containers. Sidecar containers will be supported in a future version of kusion.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/2-container.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/container",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/2-container.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{},sidebar:"kusion",previous:{title:"Deploy Application",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application"},next:{title:"Expose Service",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/service"}},p={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Example",id:"example",level:2},{value:"Apply",id:"apply",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function d(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configure-containers"},"Configure Containers"),(0,r.kt)("p",null,"You can manage container-level configurations in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,r.kt)("inlineCode",{parentName:"p"},"containers")," field (under the ",(0,r.kt)("inlineCode",{parentName:"p"},"workload")," schemas). By default, everything defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"containers")," field will be treated as application containers. Sidecar containers will be supported in a future version of kusion."),(0,r.kt)("p",null,"For the full ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,r.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-container"},"here")," for more details."),(0,r.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,r.kt)("p",null,"Please refer to the ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,r.kt)("p",null,"The example below also requires you to have ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,r.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,r.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,r.kt)("h2",{id:"example"},"Example"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"helloworld/dev/main.k"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,r.kt)("h2",{id:"apply"},"Apply"),(0,r.kt)("p",null,"Re-run steps in ",(0,r.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new container configuration can be applied."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS UnChanged v1:Service:helloworld:helloworld-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nUpdate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,r.kt)("h2",{id:"validation"},"Validation"),(0,r.kt)("p",null,"We can verify the container (in the deployment template) now has the updated attributes as defined in the container configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ kubectl get deployment -n helloworld -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n - name: env1\n value: VALUE\n - name: env2\n value: VALUE2\n image: gcr.io/google-samples/gb-frontend:v4\n imagePullPolicy: IfNotPresent\n name: helloworld\n readinessProbe:\n failureThreshold: 3\n httpGet:\n host: localhost\n path: /\n port: 80\n scheme: HTTP\n initialDelaySeconds: 10\n periodSeconds: 10\n successThreshold: 1\n timeoutSeconds: 1\n resources:\n limits:\n cpu: 500m\n memory: 512M\n...\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c3728e1b.46469b73.js b/assets/js/c3728e1b.21bf3d2b.js similarity index 51% rename from assets/js/c3728e1b.46469b73.js rename to assets/js/c3728e1b.21bf3d2b.js index 978346a72f4..f72675ca2cd 100644 --- a/assets/js/c3728e1b.46469b73.js +++ b/assets/js/c3728e1b.21bf3d2b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2290],{3905:(e,n,t)=>{t.d(n,{Zo:()=>d,kt:()=>m});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=r.createContext({}),s=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},d=function(e){var n=s(e.components);return r.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=s(t),m=a,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return t?r.createElement(g,o(o({ref:n},d),{},{components:t})):r.createElement(g,o({ref:n},d))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,o=new Array(i);o[0]=u;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=t(87462),a=(t(67294),t(3905));const i={},o="Upgrade Image",l={unversionedId:"kusion/guides/working-with-k8s/image-upgrade",id:"version-v0.9/kusion/guides/working-with-k8s/image-upgrade",title:"Upgrade Image",description:"You can declare the application's container image via image field of the Container schema.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/4-image-upgrade.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/image-upgrade",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/4-image-upgrade.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Service",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/service"},next:{title:"Configure Resource Specification",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec"}},p={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],d={toc:s};function c(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"upgrade-image"},"Upgrade Image"),(0,a.kt)("p",null,"You can declare the application's container image via ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," field of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"For the full ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,a.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-container"},"here")," for more details."),(0,a.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,a.kt)("h2",{id:"example"},"Example"),(0,a.kt)("p",null,"Update the image value in ",(0,a.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.nginx: {\n # dev stack has different image\n # set image to your want\n # before: \n # image = "gcr.io/google-samples/gb-frontend:v4"\n # after: \n image = "gcr.io/google-samples/gb-frontend:v5"\n }\n}\n')),(0,a.kt)("p",null,"Everything else in ",(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Re-run steps in ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", update image is completed."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS UnChanged v1:Service:helloworld:helloworld-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nUpdate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,a.kt)("h2",{id:"validation"},"Validation"),(0,a.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated image (v5) as defined in the container configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get deployment -n helloworld -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n...\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2290],{3905:(e,n,t)=>{t.d(n,{Zo:()=>d,kt:()=>m});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=r.createContext({}),s=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},d=function(e){var n=s(e.components);return r.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=s(t),m=a,g=u["".concat(p,".").concat(m)]||u[m]||c[m]||i;return t?r.createElement(g,o(o({ref:n},d),{},{components:t})):r.createElement(g,o({ref:n},d))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,o=new Array(i);o[0]=u;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=t(87462),a=(t(67294),t(3905));const i={},o="Upgrade Image",l={unversionedId:"kusion/guides/working-with-k8s/image-upgrade",id:"version-v0.9/kusion/guides/working-with-k8s/image-upgrade",title:"Upgrade Image",description:"You can declare the application's container image via image field of the Container schema.",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/4-image-upgrade.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/image-upgrade",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/4-image-upgrade.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Expose Service",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/service"},next:{title:"Configure Resource Specification",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec"}},p={},s=[{value:"Pre-requisite",id:"pre-requisite",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],d={toc:s};function c(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"upgrade-image"},"Upgrade Image"),(0,a.kt)("p",null,"You can declare the application's container image via ",(0,a.kt)("inlineCode",{parentName:"p"},"image")," field of the ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema."),(0,a.kt)("p",null,"For the full ",(0,a.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,a.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-container"},"here")," for more details."),(0,a.kt)("h2",{id:"pre-requisite"},"Pre-requisite"),(0,a.kt)("p",null,"Please refer to the ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,a.kt)("p",null,"The example below also requires you to have ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,a.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,a.kt)("h2",{id:"example"},"Example"),(0,a.kt)("p",null,"Update the image value in ",(0,a.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.nginx: {\n # dev stack has different image\n # set image to your want\n # before: \n # image = "gcr.io/google-samples/gb-frontend:v4"\n # after: \n image = "gcr.io/google-samples/gb-frontend:v5"\n }\n}\n')),(0,a.kt)("p",null,"Everything else in ",(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,a.kt)("h2",{id:"applying"},"Applying"),(0,a.kt)("p",null,"Re-run steps in ",(0,a.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", update image is completed."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS UnChanged v1:Service:helloworld:helloworld-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nUpdate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,a.kt)("h2",{id:"validation"},"Validation"),(0,a.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated image (v5) as defined in the container configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"kubectl get deployment -n helloworld -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v5\n ...\n...\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c4ba81c3.2dbc3af6.js b/assets/js/c4ba81c3.2dbc3af6.js new file mode 100644 index 00000000000..19ea60d1a86 --- /dev/null +++ b/assets/js/c4ba81c3.2dbc3af6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6489],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),p=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(i.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,g=c["".concat(i,".").concat(m)]||c[m]||d[m]||o;return n?r.createElement(g,s(s({ref:t},u),{},{components:n})):r.createElement(g,s({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=c;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,s[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},s="postgres",l={unversionedId:"kusion/reference/modules/workspace-configs/database/postgres",id:"version-v0.10/kusion/reference/modules/workspace-configs/database/postgres",title:"postgres",description:"Module PostgreSQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/postgres",permalink:"/docs/kusion/reference/modules/workspace-configs/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/kusion/reference/modules/workspace-configs/database/mysql"},next:{title:"monitoring",permalink:"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus"}},i={},p=[{value:"Module PostgreSQL",id:"module-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:p};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"postgres"},"postgres"),(0,a.kt)("h2",{id:"module-postgresql"},"Module PostgreSQL"),(0,a.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider managed postgres database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the postgres database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud postgres instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the postgres instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud postgres instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# PostgreSQL workspace configs for AWS RDS\nmodules: \n postgres: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# PostgreSQL workspace configs for Alicloud RDS\nmodules: \n postgres:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c4ba81c3.cb955b2d.js b/assets/js/c4ba81c3.cb955b2d.js deleted file mode 100644 index 8bfa8e67f6b..00000000000 --- a/assets/js/c4ba81c3.cb955b2d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6489],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),p=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(i.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,g=c["".concat(i,".").concat(m)]||c[m]||d[m]||o;return n?r.createElement(g,s(s({ref:t},u),{},{components:n})):r.createElement(g,s({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=c;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,s[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},s="postgres",l={unversionedId:"kusion/reference/modules/workspace-configs/database/postgres",id:"version-v0.10/kusion/reference/modules/workspace-configs/database/postgres",title:"postgres",description:"Module PostgreSQL",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/database",slug:"/kusion/reference/modules/workspace-configs/database/postgres",permalink:"/docs/kusion/reference/modules/workspace-configs/database/postgres",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"mysql",permalink:"/docs/kusion/reference/modules/workspace-configs/database/mysql"},next:{title:"monitoring",permalink:"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus"}},i={},p=[{value:"Module PostgreSQL",id:"module-postgresql",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:p};function d(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"postgres"},"postgres"),(0,a.kt)("h2",{id:"module-postgresql"},"Module PostgreSQL"),(0,a.kt)("p",null,"PostgreSQL describes the attributes to locally deploy or create a cloud provider managed postgres database instance for the workload. "),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"cloud"),(0,a.kt)("br",null),"Cloud specifies the type of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},'"aws" ',"|",' "alicloud"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"username"),(0,a.kt)("br",null),"Username specifies the operation account for the postgres database."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"root"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"category"),(0,a.kt)("br",null),"Category specifies the edition of the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},'"Basic"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"securityIPs"),(0,a.kt)("br",null),"SecurityIPs specifies the list of IP addresses allowed to access the postgres instance provided by the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"[str]"),(0,a.kt)("td",{parentName:"tr",align:null},'["0.0.0.0/0"]'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"privateRouting"),(0,a.kt)("br",null),"PrivateRouting specifies whether the host address of the cloud postgres instance for the workload to connect with is via public network or private network of the cloud vendor."),(0,a.kt)("td",{parentName:"tr",align:null},"bool"),(0,a.kt)("td",{parentName:"tr",align:null},"true"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"size"),(0,a.kt)("br",null),"Size specifies the allocated storage size of the postgres instance."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"10"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"subnetID"),(0,a.kt)("br",null),"SubnetID specifies the virtual subnet ID associated with the VPC that the cloud postgres instance will be created in."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"suffix"),(0,a.kt)("br",null),"Suffix specifies the suffix of the database name."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\n# PostgreSQL workspace configs for AWS RDS\nmodules: \n postgres: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n alicloud:\n version: 1.209.1\n source: aliyun/alicloud\n region: cn-beijing\n\n# PostgreSQL workspace configs for Alicloud RDS\nmodules: \n postgres:\n default:\n cloud: alicloud\n size: 20\n instanceType: pg.n2.serverless.1c\n category: serverless_basic\n privateRouting: false\n subnetID: [your-subnet-id]\n securityIPs: \n - 0.0.0.0/0\n suffix: "-postgres"\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c5353c60.3e26b543.js b/assets/js/c5353c60.3e26b543.js new file mode 100644 index 00000000000..324db521fe3 --- /dev/null +++ b/assets/js/c5353c60.3e26b543.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4855],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(f,i(i({ref:t},c),{},{components:n})):a.createElement(f,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(87462),o=(n(67294),n(3905));const r={id:"kusion-vs-x"},i="Kusion vs Other Software",s={unversionedId:"kusion/what-is-kusion/kusion-vs-x",id:"kusion/what-is-kusion/kusion-vs-x",title:"Kusion vs Other Software",description:"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.",source:"@site/docs/kusion/1-what-is-kusion/2-kusion-vs-x.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/kusion/what-is-kusion/kusion-vs-x",permalink:"/docs/next/kusion/what-is-kusion/kusion-vs-x",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/1-what-is-kusion/2-kusion-vs-x.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kusion-vs-x"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/next/"},next:{title:"Install Kusion",permalink:"/docs/next/kusion/getting-started/install-kusion"}},p={},l=[],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-vs-other-software"},"Kusion vs Other Software"),(0,o.kt)("p",null,"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. GitOps (ArgoCD, FluxCD, etc.)")),(0,o.kt)("p",null,"According to the ",(0,o.kt)("a",{parentName:"p",href:"https://opengitops.dev/"},"open GitOps principles"),", GitOps systems typically have its desired state expressed declaratively, continuously observe actual system state and attempt to apply the desired state. In the design of Kusion toolchain, we refer to those principles but have no intention to reinvent any GitOps systems wheel. "),(0,o.kt)("p",null,"Kusion adopts your GitOps process and improves it with richness of features. The declarative ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," model can be used to express desired intent, once intent is declared ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands"},"Kusion CLI")," takes the role to make production match intent as safely as possible. "),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. PaaS (Heroku, Vercel, etc.)")),(0,o.kt)("p",null,"Kusion shares the same goal with traditional PaaS platforms to provide application delivery and management capabilities. The intuitive difference from the full functionality PaaS platforms is that Kusion is a client-side toolchain, not a complete PaaS platform. "),(0,o.kt)("p",null,"Also traditional PaaS platforms typically constrain the type of applications they can run but there is no such constrain for Kusion which means Kusion provides greater flexibility."),(0,o.kt)("p",null,"Kusion allows you to have platform-like features without the constraints of a traditional PaaS. However, Kusion is not attempting to replace any PaaS platforms, instead Kusion can be used to deploy to a platform such as Heroku."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. KubeVela")),(0,o.kt)("p",null,"KubeVela is a modern software delivery and management control plane. KubeVela makes it easier to deploy and operate applications on top of Kubernetes."),(0,o.kt)("p",null,"Kusion is not a control plane. Kusion is a client-side tool for describing application intent in a declarative way and providing consistent workflow to apply that desired state."),(0,o.kt)("p",null,"With proper Generator implementation, the target Spec of ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," can be ",(0,o.kt)("a",{parentName:"p",href:"https://kubevela.io/docs/getting-started/core-concept/"},"KubeVela Application"),' and Kusion can use KubeVela to satisfy the "apply" step.'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Helm")),(0,o.kt)("p",null,"The concept of Helm originates from the ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Package_manager"},"package management")," mechanism of the operating system. It is a package management tool based on templated YAML files and supports the execution and management of resources in the package. "),(0,o.kt)("p",null,"Kusion is not a package manager. Kusion naturally provides a superset of Helm capabilities with the modeled key-value pairs, so that developers can use Kusion directly as a programable alternative to avoid the pain of writing text templates. For users who have adopted Helm, the stack compilation results in Kusion can be packaged and used in Helm format."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Kubernetes")),(0,o.kt)("p",null,'Kubernetes(K8s) is a container scheduling and management runtime widely used around the world, an "operating system" core for containers, and a platform for building platforms. Above the Kubernetes API layer, Kusion aims to provide app-centric ',(0,o.kt)("strong",{parentName:"p"},"abstraction")," and unified ",(0,o.kt)("strong",{parentName:"p"},"workspace"),", better ",(0,o.kt)("strong",{parentName:"p"},"user experience")," and automation ",(0,o.kt)("strong",{parentName:"p"},"workflow"),", and helps developers build the app delivery model easily and collaboratively."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c5353c60.9b747761.js b/assets/js/c5353c60.9b747761.js deleted file mode 100644 index f7581eb843d..00000000000 --- a/assets/js/c5353c60.9b747761.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4855],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),l=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(f,i(i({ref:t},c),{},{components:n})):a.createElement(f,i({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(87462),o=(n(67294),n(3905));const r={id:"kusion-vs-x"},i="Kusion vs Other Software",s={unversionedId:"kusion/what-is-kusion/kusion-vs-x",id:"kusion/what-is-kusion/kusion-vs-x",title:"Kusion vs Other Software",description:"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software.",source:"@site/docs/kusion/1-what-is-kusion/2-kusion-vs-x.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/kusion/what-is-kusion/kusion-vs-x",permalink:"/docs/next/kusion/what-is-kusion/kusion-vs-x",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/1-what-is-kusion/2-kusion-vs-x.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kusion-vs-x"},sidebar:"kusion",previous:{title:"Overview",permalink:"/docs/next/"},next:{title:"Install Kusion",permalink:"/docs/next/kusion/getting-started/install-kusion"}},p={},l=[],c={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-vs-other-software"},"Kusion vs Other Software"),(0,o.kt)("p",null,"It can be difficult to understand how different software compare to each other. Is one a replacement for the other? Are they complementary? etc. In this section, we compare Kusion to other software."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. GitOps (ArgoCD, FluxCD, etc.)")),(0,o.kt)("p",null,"According to the ",(0,o.kt)("a",{parentName:"p",href:"https://opengitops.dev/"},"open GitOps principles"),", GitOps systems typically have its desired state expressed declaratively, continuously observe actual system state and attempt to apply the desired state. In the design of Kusion toolchain, we refer to those principles but have no intention to reinvent any GitOps systems wheel. "),(0,o.kt)("p",null,"Kusion adopts your GitOps process and improves it with richness of features. The declarative ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," model can be used to express desired intent, once intent is declared ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands"},"Kusion CLI")," takes the role to make production match intent as safely as possible. "),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. PaaS (Heroku, Vercel, etc.)")),(0,o.kt)("p",null,"Kusion shares the same goal with traditional PaaS platforms to provide application delivery and management capabilities. The intuitive difference from the full functionality PaaS platforms is that Kusion is a client-side toolchain, not a complete PaaS platform. "),(0,o.kt)("p",null,"Also traditional PaaS platforms typically constrain the type of applications they can run but there is no such constrain for Kusion which means Kusion provides greater flexibility."),(0,o.kt)("p",null,"Kusion allows you to have platform-like features without the constraints of a traditional PaaS. However, Kusion is not attempting to replace any PaaS platforms, instead Kusion can be used to deploy to a platform such as Heroku."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. KubeVela")),(0,o.kt)("p",null,"KubeVela is a modern software delivery and management control plane. KubeVela makes it easier to deploy and operate applications on top of Kubernetes."),(0,o.kt)("p",null,"Kusion is not a control plane. Kusion is a client-side tool for describing application intent in a declarative way and providing consistent workflow to apply that desired state."),(0,o.kt)("p",null,"With proper Generator implementation, the target Spec of ",(0,o.kt)("a",{parentName:"p",href:"../concepts/app-configuration"},"AppConfiguration")," can be ",(0,o.kt)("a",{parentName:"p",href:"https://kubevela.io/docs/getting-started/core-concept/"},"KubeVela Application"),' and Kusion can use KubeVela to satisfy the "apply" step.'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Helm")),(0,o.kt)("p",null,"The concept of Helm originates from the ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Package_manager"},"package management")," mechanism of the operating system. It is a package management tool based on templated YAML files and supports the execution and management of resources in the package. "),(0,o.kt)("p",null,"Kusion is not a package manager. Kusion naturally provides a superset of Helm capabilities with the modeled key-value pairs, so that developers can use Kusion directly as a programable alternative to avoid the pain of writing text templates. For users who have adopted Helm, the stack compilation results in Kusion can be packaged and used in Helm format."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"vs. Kubernetes")),(0,o.kt)("p",null,'Kubernetes(K8s) is a container scheduling and management runtime widely used around the world, an "operating system" core for containers, and a platform for building platforms. Above the Kubernetes API layer, Kusion aims to provide app-centric ',(0,o.kt)("strong",{parentName:"p"},"abstraction")," and unified ",(0,o.kt)("strong",{parentName:"p"},"workspace"),", better ",(0,o.kt)("strong",{parentName:"p"},"user experience")," and automation ",(0,o.kt)("strong",{parentName:"p"},"workflow"),", and helps developers build the app delivery model easily and collaboratively."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c5a89df7.1948f9a2.js b/assets/js/c5a89df7.1948f9a2.js deleted file mode 100644 index b92b9263fe9..00000000000 --- a/assets/js/c5a89df7.1948f9a2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1550],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=o.createContext({}),p=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=p(e.components);return o.createElement(l.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=p(t),m=a,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||r;return t?o.createElement(f,i(i({ref:n},u),{},{components:t})):o.createElement(f,i({ref:n},u))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,i=new Array(r);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var o=t(87462),a=(t(67294),t(3905));const r={id:"how-kusion-works",sidebar_label:"How Kusion Works?"},i="How Kusion Works?",s={unversionedId:"kusion/concepts/how-kusion-works",id:"version-v0.10/kusion/concepts/how-kusion-works",title:"How Kusion Works?",description:"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Modules defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/8-how-kusion-works.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/how-kusion-works",permalink:"/docs/kusion/concepts/how-kusion-works",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/8-how-kusion-works.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{id:"how-kusion-works",sidebar_label:"How Kusion Works?"},sidebar:"kusion",previous:{title:"Backend Configuration",permalink:"/docs/kusion/concepts/backend-configuration"},next:{title:"Configuration File Overview",permalink:"/docs/kusion/configuration-walkthrough/overview"}},l={},p=[{value:"Overview",id:"overview",level:2},{value:"Platform Developer\u2019s Workflow",id:"platform-developers-workflow",level:2},{value:"Design Kusion Modules",id:"design-kusion-modules",level:3},{value:"Instantiate and Set Up Workspaces",id:"instantiate-and-set-up-workspaces",level:3},{value:"Application Developer\u2019s Workflow",id:"application-developers-workflow",level:2},{value:"Instantiate AppConfiguration and Apply",id:"instantiate-appconfiguration-and-apply",level:3}],u={toc:p};function c(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"how-kusion-works"},"How Kusion Works?"),(0,a.kt)("p",null,"Kusion is the platform engineering engine of ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack"},"KusionStack"),". It delivers intentions described with Kusion Modules defined in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," to Kubernetes, Clouds and On-Prem infrastructures."),(0,a.kt)("p",null,(0,a.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,a.kt)("h2",{id:"overview"},"Overview"),(0,a.kt)("p",null,"The workflow of KusionStack is illustrated in the diagram above, and it consists of three steps. The first step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Write"),", where platform engineers provide Kusion Modules and application developers write AppConfigurations based on the Kusion Modules to describe their operational intent."),(0,a.kt)("p",null,"The second step is the ",(0,a.kt)("inlineCode",{parentName:"p"},"Build")," process, which results in the creation of the SSoT (Single Source of Truth), also known as the ",(0,a.kt)("a",{parentName:"p",href:"intent"},"Intent")," of the current operational task. If you need version management of the SSoT, we recommend you manage the Intent with a VCS (Version Control System) tool like git."),(0,a.kt)("p",null,"The third step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Apply")," which makes the Intent effective. Kusion parses the operational intent based on the Intent produced in the previous step. Before applying the intent, Kusion will execute the Preview command (you can also execute this command manually) which will use a three-way diff algorithm to preview changes and prompt users to make sure all changes meet expectations; the Apply command will then actualize the operational intent onto various infrastructure platforms. Currently, it supports three runtimes: Terraform, Kubernetes, and on-prem infrastructures."),(0,a.kt)("p",null,"As a user of Kusion, if you prefer not to be conscious of so many steps, you can simply use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),", and Kusion will automatically execute all the aforementioned steps for you."),(0,a.kt)("h2",{id:"platform-developers-workflow"},"Platform Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"design-kusion-modules"},"Design Kusion Modules"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"kusion-module"},"Kusion Module")," is a reusable building block designed by platform engineers and contains two components: an application developer-oriented schema and a Kusion module generator. When platform engineers have developed a Kusion module, they can push it to a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," repository to make it into a KCL package."),(0,a.kt)("p",null,"Given a database Kusion module as an example, the schema definition is shown below and the generator logic can be found ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/pkg/modules/generators/accessories/database_generator.go"},"here"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'schema MySQL: \n """ MySQL describes the attributes to locally deploy or create a cloud provider\n managed mysql database instance for the workload. \n\n Attributes\n ----------\n type: "local" | "cloud", defaults to Undefined, required. \n Type defines whether the mysql database is deployed locally or provided by \n cloud vendor. \n version: str, defaults to Undefined, required. \n Version defines the mysql version to use. \n\n Examples\n --------\n Instantiate a local mysql database with version of 5.7. \n\n import models.schema.v1.accessories.mysql\n\n mysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n }\n """\n\n # The deployment mode of the mysql database. \n type: "local" | "cloud"\n\n # The mysql database version to use. \n version: str\n')),(0,a.kt)("h3",{id:"instantiate-and-set-up-workspaces"},"Instantiate and Set Up Workspaces"),(0,a.kt)("p",null,"Each ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," includes a corresponding Platform config file maintained by platform engineers.\nPlatform engineers should instantiate all workspaces and fulfill all fields with platform default values. Kusion will merge the workspace configuration with AppConfiguration in the Stack of the same name. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n # your kubeconfig file path\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n # metadat of used terraform providers\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\nmodules: \n # platform configuration of AWS RDS MySQL\n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," block represents a Kusion module. The fields inside are parts of the inputs for the Kusion module generator. For more details about the workspace, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," section."),(0,a.kt)("h2",{id:"application-developers-workflow"},"Application Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"instantiate-appconfiguration-and-apply"},"Instantiate AppConfiguration and Apply"),(0,a.kt)("p",null,"Application developers choose Kusion modules they need and instantiate them in the AppConfiguration to describe their operation intentions. We have built some built-in Kusion modules in the repository ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," and we warmly welcome you to join us in building this ecosystem together."),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," is the ",(0,a.kt)("strong",{parentName:"p"},"only")," configuration maintained by application developers and schemas in this file are defined from the application developer's perspective to reduce their cognitive load. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-pthyon"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n ......\n }\n }\n ......\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"workload")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"database")," are both Kusion modules provided by platform engineers and Kusion will convert them into actual infrastructure API calls eventually."),(0,a.kt)("p",null,"Finally, application developers can deliver their operational intent to infrastructures with one command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c5a89df7.f48ef27c.js b/assets/js/c5a89df7.f48ef27c.js new file mode 100644 index 00000000000..b0b52d185da --- /dev/null +++ b/assets/js/c5a89df7.f48ef27c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1550],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=o.createContext({}),p=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=p(e.components);return o.createElement(l.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=p(t),m=a,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||r;return t?o.createElement(f,i(i({ref:n},u),{},{components:t})):o.createElement(f,i({ref:n},u))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,i=new Array(r);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var o=t(87462),a=(t(67294),t(3905));const r={id:"how-kusion-works",sidebar_label:"How Kusion Works?"},i="How Kusion Works?",s={unversionedId:"kusion/concepts/how-kusion-works",id:"version-v0.10/kusion/concepts/how-kusion-works",title:"How Kusion Works?",description:"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Modules defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.",source:"@site/versioned_docs/version-v0.10/kusion/3-concepts/8-how-kusion-works.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/how-kusion-works",permalink:"/docs/kusion/concepts/how-kusion-works",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/3-concepts/8-how-kusion-works.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{id:"how-kusion-works",sidebar_label:"How Kusion Works?"},sidebar:"kusion",previous:{title:"Backend Configuration",permalink:"/docs/kusion/concepts/backend-configuration"},next:{title:"Configuration File Overview",permalink:"/docs/kusion/configuration-walkthrough/overview"}},l={},p=[{value:"Overview",id:"overview",level:2},{value:"Platform Developer\u2019s Workflow",id:"platform-developers-workflow",level:2},{value:"Design Kusion Modules",id:"design-kusion-modules",level:3},{value:"Instantiate and Set Up Workspaces",id:"instantiate-and-set-up-workspaces",level:3},{value:"Application Developer\u2019s Workflow",id:"application-developers-workflow",level:2},{value:"Instantiate AppConfiguration and Apply",id:"instantiate-appconfiguration-and-apply",level:3}],u={toc:p};function c(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"how-kusion-works"},"How Kusion Works?"),(0,a.kt)("p",null,"Kusion is the platform engineering engine of ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack"},"KusionStack"),". It delivers intentions described with Kusion Modules defined in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," to Kubernetes, Clouds and On-Prem infrastructures."),(0,a.kt)("p",null,(0,a.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,a.kt)("h2",{id:"overview"},"Overview"),(0,a.kt)("p",null,"The workflow of KusionStack is illustrated in the diagram above, and it consists of three steps. The first step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Write"),", where platform engineers provide Kusion Modules and application developers write AppConfigurations based on the Kusion Modules to describe their operational intent."),(0,a.kt)("p",null,"The second step is the ",(0,a.kt)("inlineCode",{parentName:"p"},"Build")," process, which results in the creation of the SSoT (Single Source of Truth), also known as the ",(0,a.kt)("a",{parentName:"p",href:"intent"},"Intent")," of the current operational task. If you need version management of the SSoT, we recommend you manage the Intent with a VCS (Version Control System) tool like git."),(0,a.kt)("p",null,"The third step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Apply")," which makes the Intent effective. Kusion parses the operational intent based on the Intent produced in the previous step. Before applying the intent, Kusion will execute the Preview command (you can also execute this command manually) which will use a three-way diff algorithm to preview changes and prompt users to make sure all changes meet expectations; the Apply command will then actualize the operational intent onto various infrastructure platforms. Currently, it supports three runtimes: Terraform, Kubernetes, and on-prem infrastructures."),(0,a.kt)("p",null,"As a user of Kusion, if you prefer not to be conscious of so many steps, you can simply use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),", and Kusion will automatically execute all the aforementioned steps for you."),(0,a.kt)("h2",{id:"platform-developers-workflow"},"Platform Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"design-kusion-modules"},"Design Kusion Modules"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"kusion-module"},"Kusion Module")," is a reusable building block designed by platform engineers and contains two components: an application developer-oriented schema and a Kusion module generator. When platform engineers have developed a Kusion module, they can push it to a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," repository to make it into a KCL package."),(0,a.kt)("p",null,"Given a database Kusion module as an example, the schema definition is shown below and the generator logic can be found ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/pkg/modules/generators/accessories/database_generator.go"},"here"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'schema MySQL: \n """ MySQL describes the attributes to locally deploy or create a cloud provider\n managed mysql database instance for the workload. \n\n Attributes\n ----------\n type: "local" | "cloud", defaults to Undefined, required. \n Type defines whether the mysql database is deployed locally or provided by \n cloud vendor. \n version: str, defaults to Undefined, required. \n Version defines the mysql version to use. \n\n Examples\n --------\n Instantiate a local mysql database with version of 5.7. \n\n import models.schema.v1.accessories.mysql\n\n mysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n }\n """\n\n # The deployment mode of the mysql database. \n type: "local" | "cloud"\n\n # The mysql database version to use. \n version: str\n')),(0,a.kt)("h3",{id:"instantiate-and-set-up-workspaces"},"Instantiate and Set Up Workspaces"),(0,a.kt)("p",null,"Each ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," includes a corresponding Platform config file maintained by platform engineers.\nPlatform engineers should instantiate all workspaces and fulfill all fields with platform default values. Kusion will merge the workspace configuration with AppConfiguration in the Stack of the same name. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n # your kubeconfig file path\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n # metadat of used terraform providers\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\nmodules: \n # platform configuration of AWS RDS MySQL\n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," block represents a Kusion module. The fields inside are parts of the inputs for the Kusion module generator. For more details about the workspace, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," section."),(0,a.kt)("h2",{id:"application-developers-workflow"},"Application Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"instantiate-appconfiguration-and-apply"},"Instantiate AppConfiguration and Apply"),(0,a.kt)("p",null,"Application developers choose Kusion modules they need and instantiate them in the AppConfiguration to describe their operation intentions. We have built some built-in Kusion modules in the repository ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," and we warmly welcome you to join us in building this ecosystem together."),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," is the ",(0,a.kt)("strong",{parentName:"p"},"only")," configuration maintained by application developers and schemas in this file are defined from the application developer's perspective to reduce their cognitive load. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-pthyon"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n ......\n }\n }\n ......\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"workload")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"database")," are both Kusion modules provided by platform engineers and Kusion will convert them into actual infrastructure API calls eventually."),(0,a.kt)("p",null,"Finally, application developers can deliver their operational intent to infrastructures with one command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c6ae2a42.5cdb0a17.js b/assets/js/c6ae2a42.5cdb0a17.js deleted file mode 100644 index 01878bad57f..00000000000 --- a/assets/js/c6ae2a42.5cdb0a17.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[922],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,r(r({ref:t},d),{},{components:n})):a.createElement(k,r({ref:t},d))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(87462),i=(n(67294),n(3905));const o={id:"kcl-basics"},r="KCL Basics",l={unversionedId:"kusion/configuration-walkthrough/kcl-basics",id:"version-v0.10/kusion/configuration-walkthrough/kcl-basics",title:"KCL Basics",description:"Table of Content",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/2-kcl-basics.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/kcl-basics",permalink:"/docs/kusion/configuration-walkthrough/kcl-basics",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/2-kcl-basics.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kcl-basics"},sidebar:"kusion",previous:{title:"Configuration File Overview",permalink:"/docs/kusion/configuration-walkthrough/overview"},next:{title:"Base and Override",permalink:"/docs/kusion/configuration-walkthrough/base-override"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Variable assignments",id:"variable-assignments",level:2},{value:"Common built-in types",id:"common-built-in-types",level:2},{value:"Lists and maps",id:"lists-and-maps",level:2},{value:"Conditional statements",id:"conditional-statements",level:2},{value:"The : and = operator",id:"the--and--operator",level:2},{value:"Advanced KCL capabilities",id:"advanced-kcl-capabilities",level:2}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kcl-basics"},"KCL Basics"),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#variable-assignments"},"Variable assignments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#common-built-in-types"},"Common built-in types")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#lists-and-maps"},"Lists and maps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#conditional-statements"},"Conditional statements")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#the--and--operator"},"The : and = operator")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#advanced-kcl-capabilities"},"Advanced KCL capabilities"))),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h2",{id:"variable-assignments"},"Variable assignments"),(0,i.kt)("p",null,"There are two ways to initialize a variable in KCL. You can either use the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," operator or the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss the difference between them in ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},"this section later"),"."),(0,i.kt)("p",null,"Here are the two ways to create a variable and initialize it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'foo = "Foo" # Declare a variable named `foo` and its value is a string literal "Foo"\nbar: "Bar" # Declare a variable named `bar` and its value is a string literal "Bar"\n')),(0,i.kt)("p",null,"You will be able to override a variable assignment via the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss this in depth in the ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},(0,i.kt)("inlineCode",{parentName:"a"},":")," and ",(0,i.kt)("inlineCode",{parentName:"a"},"=")," operator section"),"."),(0,i.kt)("h2",{id:"common-built-in-types"},"Common built-in types"),(0,i.kt)("p",null,"KCL supports ",(0,i.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"float"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"bool")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"string")," as the built-in types."),(0,i.kt)("p",null,"Other types are defined in the packages that are imported into the application configuration files. One such example would be the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object (or ",(0,i.kt)("inlineCode",{parentName:"p"},"Container"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Probe"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," object, etc) that are defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," repository."),(0,i.kt)("h2",{id:"lists-and-maps"},"Lists and maps"),(0,i.kt)("p",null,"Lists are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"[]")," notation.\nAn example of lists:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"list0 = [1, 2, 3]\nlist1 = [4, 5, 6]\njoined_list = list0 + list1 # [1, 2, 3, 4, 5, 6]\n")),(0,i.kt)("p",null,"Maps are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," notation.\nAn example of maps:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"a = {\"one\" = 1, \"two\" = 2, \"three\" = 3}\nb = {'one' = 1, 'two' = 2, 'three' = 3}\nassert a == b # True\nassert len(a) == 3 # True\n")),(0,i.kt)("h2",{id:"conditional-statements"},"Conditional statements"),(0,i.kt)("p",null,"You can also use basic control flow statements when writing the configuration file."),(0,i.kt)("p",null,"An example that sets the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," conditionally based on the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"containers.myapp.resources.cpu"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1 if containers.myapp.resources.cpu == "500m" else 2\n }\n}\n')),(0,i.kt)("p",null,"For more details on KCL's control flow statements, please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#control-flow-statements"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"the--and--operator"},"The ",(0,i.kt)("inlineCode",{parentName:"h2"},":")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"=")," operator"),(0,i.kt)("p",null,"You might have noticed there is a mixed usage of the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," in the samples above."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"TLDR: The recommendation is to use ",(0,i.kt)("inlineCode",{parentName:"strong"},":")," in the common configurations, and ",(0,i.kt)("inlineCode",{parentName:"strong"},"=")," for override in the environment-specific configurations."))),(0,i.kt)("p",null,"In KCL:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},":")," represents a union-ed value assignment. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: T E"),", the value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will be merged and union-ed into the element value."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"=")," represents a value override. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = T E"),", The value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will override the ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier")," attribute value.")),(0,i.kt)("p",null,"Let's take a look at an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is one configuration that will be merged.\nconfig: Config {\n data.d1 = 1\n}\n# This is another configuration that will be merged.\nconfig: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The above is equivalent to the snippet below since the two expressions for ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," get merged/union-ed into one:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d1 = 1\n data.d2 = 1\n}\n")),(0,i.kt)("p",null,"whereas using the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operators will result in a different outcome:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is first configuration.\nconfig = Config {\n data.d1 = 1\n}\n# This is second configuration that will override the prior one.\nconfig = Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The config above results in:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict with each other."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"data0 = {id: 1} | {id: 2} # Error\uff1aconflicting values between {'id': 2} and {'id': 1}\ndata1 = {id: 1} | {id = 2} # Ok, the value of `data` is {\"id\": 2}\n")),(0,i.kt)("p",null,"More about ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator can be found in the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#config-operations"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"advanced-kcl-capabilities"},"Advanced KCL capabilities"),(0,i.kt)("p",null,"For more advanced KCL capabilities, please visit the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c6ae2a42.8b27f6a1.js b/assets/js/c6ae2a42.8b27f6a1.js new file mode 100644 index 00000000000..86ed7475064 --- /dev/null +++ b/assets/js/c6ae2a42.8b27f6a1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[922],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),m=i,k=u["".concat(s,".").concat(m)]||u[m]||c[m]||o;return n?a.createElement(k,r(r({ref:t},d),{},{components:n})):a.createElement(k,r({ref:t},d))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(87462),i=(n(67294),n(3905));const o={id:"kcl-basics"},r="KCL Basics",l={unversionedId:"kusion/configuration-walkthrough/kcl-basics",id:"version-v0.10/kusion/configuration-walkthrough/kcl-basics",title:"KCL Basics",description:"Table of Content",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/2-kcl-basics.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/kcl-basics",permalink:"/docs/kusion/configuration-walkthrough/kcl-basics",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/2-kcl-basics.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{id:"kcl-basics"},sidebar:"kusion",previous:{title:"Configuration File Overview",permalink:"/docs/kusion/configuration-walkthrough/overview"},next:{title:"Base and Override",permalink:"/docs/kusion/configuration-walkthrough/base-override"}},s={},p=[{value:"Table of Content",id:"table-of-content",level:2},{value:"Variable assignments",id:"variable-assignments",level:2},{value:"Common built-in types",id:"common-built-in-types",level:2},{value:"Lists and maps",id:"lists-and-maps",level:2},{value:"Conditional statements",id:"conditional-statements",level:2},{value:"The : and = operator",id:"the--and--operator",level:2},{value:"Advanced KCL capabilities",id:"advanced-kcl-capabilities",level:2}],d={toc:p};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"kcl-basics"},"KCL Basics"),(0,i.kt)("h2",{id:"table-of-content"},"Table of Content"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#variable-assignments"},"Variable assignments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#common-built-in-types"},"Common built-in types")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#lists-and-maps"},"Lists and maps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#conditional-statements"},"Conditional statements")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#the--and--operator"},"The : and = operator")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#advanced-kcl-capabilities"},"Advanced KCL capabilities"))),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/"},"KCL")," is the choice of configuration language consumed by Kusion. KCL is an open source constraint-based record and functional language. KCL works well with a large number of complex configurations via modern programming language technology and practice, and is committed to provide better modularity, scalability, stability and extensibility."),(0,i.kt)("h2",{id:"variable-assignments"},"Variable assignments"),(0,i.kt)("p",null,"There are two ways to initialize a variable in KCL. You can either use the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," operator or the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss the difference between them in ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},"this section later"),"."),(0,i.kt)("p",null,"Here are the two ways to create a variable and initialize it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'foo = "Foo" # Declare a variable named `foo` and its value is a string literal "Foo"\nbar: "Bar" # Declare a variable named `bar` and its value is a string literal "Bar"\n')),(0,i.kt)("p",null,"You will be able to override a variable assignment via the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator. We will discuss this in depth in the ",(0,i.kt)("a",{parentName:"p",href:"#the--and--operator"},(0,i.kt)("inlineCode",{parentName:"a"},":")," and ",(0,i.kt)("inlineCode",{parentName:"a"},"=")," operator section"),"."),(0,i.kt)("h2",{id:"common-built-in-types"},"Common built-in types"),(0,i.kt)("p",null,"KCL supports ",(0,i.kt)("inlineCode",{parentName:"p"},"int"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"float"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"bool")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"string")," as the built-in types."),(0,i.kt)("p",null,"Other types are defined in the packages that are imported into the application configuration files. One such example would be the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object (or ",(0,i.kt)("inlineCode",{parentName:"p"},"Container"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Probe"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," object, etc) that are defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"catalog")," repository."),(0,i.kt)("h2",{id:"lists-and-maps"},"Lists and maps"),(0,i.kt)("p",null,"Lists are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"[]")," notation.\nAn example of lists:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"list0 = [1, 2, 3]\nlist1 = [4, 5, 6]\njoined_list = list0 + list1 # [1, 2, 3, 4, 5, 6]\n")),(0,i.kt)("p",null,"Maps are represented using the ",(0,i.kt)("inlineCode",{parentName:"p"},"{}")," notation.\nAn example of maps:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"a = {\"one\" = 1, \"two\" = 2, \"three\" = 3}\nb = {'one' = 1, 'two' = 2, 'three' = 3}\nassert a == b # True\nassert len(a) == 3 # True\n")),(0,i.kt)("h2",{id:"conditional-statements"},"Conditional statements"),(0,i.kt)("p",null,"You can also use basic control flow statements when writing the configuration file."),(0,i.kt)("p",null,"An example that sets the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," conditionally based on the value of ",(0,i.kt)("inlineCode",{parentName:"p"},"containers.myapp.resources.cpu"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1 if containers.myapp.resources.cpu == "500m" else 2\n }\n}\n')),(0,i.kt)("p",null,"For more details on KCL's control flow statements, please refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#control-flow-statements"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"the--and--operator"},"The ",(0,i.kt)("inlineCode",{parentName:"h2"},":")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"=")," operator"),(0,i.kt)("p",null,"You might have noticed there is a mixed usage of the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," in the samples above."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"TLDR: The recommendation is to use ",(0,i.kt)("inlineCode",{parentName:"strong"},":")," in the common configurations, and ",(0,i.kt)("inlineCode",{parentName:"strong"},"=")," for override in the environment-specific configurations."))),(0,i.kt)("p",null,"In KCL:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},":")," represents a union-ed value assignment. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier: T E"),", the value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will be merged and union-ed into the element value."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"=")," represents a value override. In the pattern ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = E")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier = T E"),", The value of the expression ",(0,i.kt)("inlineCode",{parentName:"li"},"E")," with optional type annotation ",(0,i.kt)("inlineCode",{parentName:"li"},"T")," will override the ",(0,i.kt)("inlineCode",{parentName:"li"},"identifier")," attribute value.")),(0,i.kt)("p",null,"Let's take a look at an example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is one configuration that will be merged.\nconfig: Config {\n data.d1 = 1\n}\n# This is another configuration that will be merged.\nconfig: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The above is equivalent to the snippet below since the two expressions for ",(0,i.kt)("inlineCode",{parentName:"p"},"config")," get merged/union-ed into one:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d1 = 1\n data.d2 = 1\n}\n")),(0,i.kt)("p",null,"whereas using the ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operators will result in a different outcome:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"# This is first configuration.\nconfig = Config {\n data.d1 = 1\n}\n# This is second configuration that will override the prior one.\nconfig = Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"The config above results in:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"config: Config {\n data.d2 = 2\n}\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},":")," attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict with each other."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"data0 = {id: 1} | {id: 2} # Error\uff1aconflicting values between {'id': 2} and {'id': 1}\ndata1 = {id: 1} | {id = 2} # Ok, the value of `data` is {\"id\": 2}\n")),(0,i.kt)("p",null,"More about ",(0,i.kt)("inlineCode",{parentName:"p"},":")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"=")," operator can be found in the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/reference/lang/tour#config-operations"},"KCL documentation"),"."),(0,i.kt)("h2",{id:"advanced-kcl-capabilities"},"Advanced KCL capabilities"),(0,i.kt)("p",null,"For more advanced KCL capabilities, please visit the ",(0,i.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c7fa01e5.0ccaf230.js b/assets/js/c7fa01e5.0ccaf230.js deleted file mode 100644 index bdaf7b53eac..00000000000 --- a/assets/js/c7fa01e5.0ccaf230.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5523],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=o.createContext({}),p=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=i,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||a;return t?o.createElement(m,r(r({ref:n},c),{},{components:t})):o.createElement(m,r({ref:n},c))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,r=new Array(a);r[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var o=t(87462),i=(t(67294),t(3905));const a={},r="Schedule a Job",l={unversionedId:"kusion/user-guides/working-with-k8s/job",id:"kusion/user-guides/working-with-k8s/job",title:"Schedule a Job",description:'The guides above provide examples on how to configure workloads of the type wl.Service, which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely wl.Job which corresponds to a one-off or recurring execution of tasks that run to completion and then stop.',source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/7-job.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/job",permalink:"/docs/next/kusion/user-guides/working-with-k8s/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/7-job.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{},sidebar:"kusion",previous:{title:"Set up Operational Rules",permalink:"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules"},next:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/next/kusion/user-guides/observability/prometheus"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"schedule-a-job"},"Schedule a Job"),(0,i.kt)("p",null,"The guides above provide examples on how to configure workloads of the type ",(0,i.kt)("inlineCode",{parentName:"p"},"wl.Service"),', which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely ',(0,i.kt)("inlineCode",{parentName:"p"},"wl.Job")," which corresponds to a one-off or recurring execution of tasks that run to completion and then stop."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for scheduling a job."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there. Alternatively, if you have updated your workspace config in the previous guides, no changes need to be made either."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/job"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"To schedule a job with cron expression, update ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k")," to the following:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Job {\n containers: {\n "busybox": c.Container {\n # The target image\n image: "busybox:1.28"\n # Run the following command as defined\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n # Run every minute.\n schedule: "* * * * *"\n }\n}\n')),(0,i.kt)("p",null,"The KCL snippet above schedules a job. Alternatively, if you want a one-time job without cron, simply remove the ",(0,i.kt)("inlineCode",{parentName:"p"},"schedule")," from the configuration."),(0,i.kt)("p",null,"You can find the full example in here in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/simple-job"},"konfig repo"),"."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying")," and schedule the job. Your output might look like one of the following:"),(0,i.kt)("p",null,"If you are starting from scratch, all resources are created on the spot:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u2514\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create batch/v1:CronJob:simple-service:helloworld-dev-helloworld success \nCreate batch/v1:CronJob:simple-service:simple-service-dev-helloworld success [2/2] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("p",null,"If you are starting from the last guide which configures an ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule"),", the output looks like the following which destroys the ",(0,i.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," and replace it with a ",(0,i.kt)("inlineCode",{parentName:"p"},"CronJob"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n* \u251c\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Delete\n* \u2514\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Delete\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Delete apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \n SUCCESS Create batch/v1:CronJob:simple-service:simple-service-dev-helloworld success \n SUCCESS Delete v1:Service:simple-service:simple-service-dev-helloworld-private success \nDelete v1:Service:simple-service:simple-service-dev-helloworld-private success [4/4] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 1 created, 0 updated, 2 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the job has now been scheduled:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get cronjob -n simple-service\nNAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE\nsimple-service-dev-helloworld * * * * * False 0 2m18s\n")),(0,i.kt)("p",null,"Verify the job has been triggered after the minute mark since we scheduled it to run every minute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get job -n simple-service\nNAME COMPLETIONS DURATION AGE\nsimple-service-dev-helloworld-28415748 1/1 5s 11s\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c7fa01e5.2ed2e287.js b/assets/js/c7fa01e5.2ed2e287.js new file mode 100644 index 00000000000..94d2cf91e04 --- /dev/null +++ b/assets/js/c7fa01e5.2ed2e287.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5523],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var o=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=o.createContext({}),p=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=p(e.components);return o.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=i,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||a;return t?o.createElement(m,r(r({ref:n},c),{},{components:t})):o.createElement(m,r({ref:n},c))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,r=new Array(a);r[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var o=t(87462),i=(t(67294),t(3905));const a={},r="Schedule a Job",l={unversionedId:"kusion/user-guides/working-with-k8s/job",id:"kusion/user-guides/working-with-k8s/job",title:"Schedule a Job",description:'The guides above provide examples on how to configure workloads of the type wl.Service, which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely wl.Job which corresponds to a one-off or recurring execution of tasks that run to completion and then stop.',source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/7-job.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/job",permalink:"/docs/next/kusion/user-guides/working-with-k8s/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/7-job.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:7,frontMatter:{},sidebar:"kusion",previous:{title:"Set up Operational Rules",permalink:"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules"},next:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/next/kusion/user-guides/observability/prometheus"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"schedule-a-job"},"Schedule a Job"),(0,i.kt)("p",null,"The guides above provide examples on how to configure workloads of the type ",(0,i.kt)("inlineCode",{parentName:"p"},"wl.Service"),', which is typically used for long-running web applications that should "never" go down. Alternatively, you could also schedule another kind of workload profile, namely ',(0,i.kt)("inlineCode",{parentName:"p"},"wl.Job")," which corresponds to a one-off or recurring execution of tasks that run to completion and then stop."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for scheduling a job."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there. Alternatively, if you have updated your workspace config in the previous guides, no changes need to be made either."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the workloads to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"replicas")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/workload/job"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"To schedule a job with cron expression, update ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k")," to the following:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Job {\n containers: {\n "busybox": c.Container {\n # The target image\n image: "busybox:1.28"\n # Run the following command as defined\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n # Run every minute.\n schedule: "* * * * *"\n }\n}\n')),(0,i.kt)("p",null,"The KCL snippet above schedules a job. Alternatively, if you want a one-time job without cron, simply remove the ",(0,i.kt)("inlineCode",{parentName:"p"},"schedule")," from the configuration."),(0,i.kt)("p",null,"You can find the full example in here in the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/simple-job"},"konfig repo"),"."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying")," and schedule the job. Your output might look like one of the following:"),(0,i.kt)("p",null,"If you are starting from scratch, all resources are created on the spot:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service Create\n* \u2514\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS Create v1:Namespace:simple-service success \n SUCCESS Create batch/v1:CronJob:simple-service:helloworld-dev-helloworld success \nCreate batch/v1:CronJob:simple-service:simple-service-dev-helloworld success [2/2] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("p",null,"If you are starting from the last guide which configures an ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule"),", the output looks like the following which destroys the ",(0,i.kt)("inlineCode",{parentName:"p"},"Deployment")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," and replace it with a ",(0,i.kt)("inlineCode",{parentName:"p"},"CronJob"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 batch/v1:CronJob:simple-service:simple-service-dev-helloworld Create\n* \u251c\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Delete\n* \u2514\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Delete\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Delete apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \n SUCCESS Create batch/v1:CronJob:simple-service:simple-service-dev-helloworld success \n SUCCESS Delete v1:Service:simple-service:simple-service-dev-helloworld-private success \nDelete v1:Service:simple-service:simple-service-dev-helloworld-private success [4/4] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 1 created, 0 updated, 2 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the job has now been scheduled:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get cronjob -n simple-service\nNAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE\nsimple-service-dev-helloworld * * * * * False 0 2m18s\n")),(0,i.kt)("p",null,"Verify the job has been triggered after the minute mark since we scheduled it to run every minute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get job -n simple-service\nNAME COMPLETIONS DURATION AGE\nsimple-service-dev-helloworld-28415748 1/1 5s 11s\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/cd9e621c.1e08be72.js b/assets/js/cd9e621c.6b430410.js similarity index 55% rename from assets/js/cd9e621c.1e08be72.js rename to assets/js/cd9e621c.6b430410.js index 06364b86119..5310d386780 100644 --- a/assets/js/cd9e621c.1e08be72.js +++ b/assets/js/cd9e621c.6b430410.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7744],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,k=m["".concat(l,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(k,s(s({ref:t},p),{},{components:n})):r.createElement(k,s({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace list",i={unversionedId:"kusion/reference/commands/kusion-workspace-list",id:"kusion/reference/commands/kusion-workspace-list",title:"kusion workspace list",description:"List all workspace names",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-list.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-list",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-list",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-list.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace delete",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-delete"},next:{title:"kusion workspace show",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-show"}},l={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-list"},"kusion workspace list"),(0,o.kt)("p",null,"List all workspace names"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command list the names of all workspaces."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace list\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # List all workspace names\n kusion workspace list\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for list\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7744],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,k=m["".concat(l,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(k,s(s({ref:t},p),{},{components:n})):r.createElement(k,s({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},s="kusion workspace list",i={unversionedId:"kusion/reference/commands/kusion-workspace-list",id:"kusion/reference/commands/kusion-workspace-list",title:"kusion workspace list",description:"List all workspace names",source:"@site/docs/kusion/6-reference/1-commands/kusion-workspace-list.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-list",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-list",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-workspace-list.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace delete",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-delete"},next:{title:"kusion workspace show",permalink:"/docs/next/kusion/reference/commands/kusion-workspace-show"}},l={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-list"},"kusion workspace list"),(0,o.kt)("p",null,"List all workspace names"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command list the names of all workspaces."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace list\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # List all workspace names\n kusion workspace list\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for list\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d0375dde.535a8363.js b/assets/js/d0375dde.535a8363.js new file mode 100644 index 00000000000..abb643da816 --- /dev/null +++ b/assets/js/d0375dde.535a8363.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2709],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=i,h=d["".concat(c,".").concat(f)]||d[f]||p[f]||r;return n?o.createElement(h,a(a({ref:t},u),{},{components:n})):o.createElement(h,a({ref:t},u))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=n(87462),i=(n(67294),n(3905));const r={},a="Intent",s={unversionedId:"kusion/concepts/intent",id:"version-v0.9/kusion/concepts/intent",title:"Intent",description:"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/intent.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/intent",permalink:"/docs/v0.9/kusion/concepts/intent",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/intent.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"AppConfiguration",permalink:"/docs/v0.9/kusion/concepts/appconfiguration"},next:{title:"Configuration File Overview",permalink:"/docs/v0.9/kusion/config-walkthrough/overview"}},c={},l=[{value:"Purpose",id:"purpose",level:2},{value:"Single Source of Truth",id:"single-source-of-truth",level:3},{value:"Consistency",id:"consistency",level:3},{value:"Rollback and Disaster Recovery",id:"rollback-and-disaster-recovery",level:3}],u={toc:l};function p(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"intent"},"Intent"),(0,i.kt)("p",null,"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent."),(0,i.kt)("h2",{id:"purpose"},"Purpose"),(0,i.kt)("h3",{id:"single-source-of-truth"},"Single Source of Truth"),(0,i.kt)("p",null,"In Kusion's workflow, platform engineer build Kusion modules and provide environment configurations, application developers choose Kusion modules they need and deploy operational intentions to an environment with related environment configurations. They can also input dynamic paramters like the container image when execute the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," command. So the final operational intentions includes configuratins written by application developers, environment configurations and dynamic inputs. Due to this reason, we introduce ",(0,i.kt)("strong",{parentName:"p"},"Intent")," to represent the SSoT(Single Source of Truth) of Kusion. It is the result of ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," which contains all operational intentions from different sources."),(0,i.kt)("h3",{id:"consistency"},"Consistency"),(0,i.kt)("p",null,"Delivering an application to different environments with identical configurations is a common practice, especially for applications that require scalable distribution. In such cases, an immutable configuration package is helpful. By utilizing the Intent, all configurations and changes are stored in a single file. As the Intent is the input of Kusion, it ensures consistency across different environments whenever you execute Kusion with the same Intent file."),(0,i.kt)("h3",{id:"rollback-and-disaster-recovery"},"Rollback and Disaster Recovery"),(0,i.kt)("p",null,"The ability to roll back is crucial in reducing incident duration. Rolling back the system to previously validated version is much faster compared to attempting to fix it during an outage. We regard a validated Intent as a snapshot of the system and recommend to sotre the Intent in a version control systems like Git. This enables better change management practices and makes it simpler to roll back to previous versions if needed. In case of a failure or outage, having a validated Intent simplifies the rollback process, ensuring that the system can be quickly recovered."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d0375dde.7c666183.js b/assets/js/d0375dde.7c666183.js deleted file mode 100644 index 586b3ef2576..00000000000 --- a/assets/js/d0375dde.7c666183.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2709],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=i,h=d["".concat(c,".").concat(f)]||d[f]||p[f]||r;return n?o.createElement(h,a(a({ref:t},u),{},{components:n})):o.createElement(h,a({ref:t},u))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=n(87462),i=(n(67294),n(3905));const r={},a="Intent",s={unversionedId:"kusion/concepts/intent",id:"version-v0.9/kusion/concepts/intent",title:"Intent",description:"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent.",source:"@site/versioned_docs/version-v0.9/kusion/concepts/intent.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/intent",permalink:"/docs/v0.9/kusion/concepts/intent",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/intent.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"AppConfiguration",permalink:"/docs/v0.9/kusion/concepts/appconfiguration"},next:{title:"Configuration File Overview",permalink:"/docs/v0.9/kusion/config-walkthrough/overview"}},c={},l=[{value:"Purpose",id:"purpose",level:2},{value:"Single Source of Truth",id:"single-source-of-truth",level:3},{value:"Consistency",id:"consistency",level:3},{value:"Rollback and Disaster Recovery",id:"rollback-and-disaster-recovery",level:3}],u={toc:l};function p(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"intent"},"Intent"),(0,i.kt)("p",null,"The Intent represents the operational intentions that you aim to deliver using Kusion. These intentions are expected to contain all components throughout the software development lifecycle (SDLC), including resources (workload, database, load balancer, etc.), dependencies, and policies. The Kusion module generators are responsible for converting all AppConfigurations and environment configurations into the Intent. Once the Intent is generated, the Kusion Engine takes charge of updating the actual infrastructures to match the Intent."),(0,i.kt)("h2",{id:"purpose"},"Purpose"),(0,i.kt)("h3",{id:"single-source-of-truth"},"Single Source of Truth"),(0,i.kt)("p",null,"In Kusion's workflow, platform engineer build Kusion modules and provide environment configurations, application developers choose Kusion modules they need and deploy operational intentions to an environment with related environment configurations. They can also input dynamic paramters like the container image when execute the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," command. So the final operational intentions includes configuratins written by application developers, environment configurations and dynamic inputs. Due to this reason, we introduce ",(0,i.kt)("strong",{parentName:"p"},"Intent")," to represent the SSoT(Single Source of Truth) of Kusion. It is the result of ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," which contains all operational intentions from different sources."),(0,i.kt)("h3",{id:"consistency"},"Consistency"),(0,i.kt)("p",null,"Delivering an application to different environments with identical configurations is a common practice, especially for applications that require scalable distribution. In such cases, an immutable configuration package is helpful. By utilizing the Intent, all configurations and changes are stored in a single file. As the Intent is the input of Kusion, it ensures consistency across different environments whenever you execute Kusion with the same Intent file."),(0,i.kt)("h3",{id:"rollback-and-disaster-recovery"},"Rollback and Disaster Recovery"),(0,i.kt)("p",null,"The ability to roll back is crucial in reducing incident duration. Rolling back the system to previously validated version is much faster compared to attempting to fix it during an outage. We regard a validated Intent as a snapshot of the system and recommend to sotre the Intent in a version control systems like Git. This enables better change management practices and makes it simpler to roll back to previous versions if needed. In case of a failure or outage, having a validated Intent simplifies the rollback process, ensuring that the system can be quickly recovered."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d05ef132.65b778ef.js b/assets/js/d05ef132.65b778ef.js deleted file mode 100644 index 00a296955d9..00000000000 --- a/assets/js/d05ef132.65b778ef.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5452],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(f,i(i({ref:n},p),{},{components:t})):r.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const a={sidebar_position:3},i="Base and Override",s={unversionedId:"kusion/config-walkthrough/base_override",id:"version-v0.9/kusion/config-walkthrough/base_override",title:"Base and Override",description:"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/base_override.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/base_override",permalink:"/docs/v0.9/kusion/config-walkthrough/base_override",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/base_override.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"kusion",previous:{title:"KCL Basics",permalink:"/docs/v0.9/kusion/config-walkthrough/kcl_basics"},next:{title:"Workload",permalink:"/docs/v0.9/kusion/config-walkthrough/workload"}},c={},l=[],p={toc:l};function d(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"base-and-override"},"Base and Override"),(0,o.kt)("p",null,"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons."),(0,o.kt)("p",null,"In that context, we advocate for a pattern where you can leverage some Kusion and KCL features to minimize the amount of duplicate configurations, by separating the common base application configuration and environment-specific ones."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The file names in the below examples don't matter as long as they are called out and appear in the correct order in the ",(0,o.kt)("inlineCode",{parentName:"p"},"entries")," field (the field is a list) in ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod"),". The files with common configurations should appear first in the list and stack-specific ones last. The latter one takes precedence."),(0,o.kt)("p",{parentName:"admonition"},"The configurations also don't have be placed into a single ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," file. For complex projects, they can be broken down into smaller organized ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," files for better readability. ")),(0,o.kt)("p",null,"Base configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"base/base.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,o.kt)("p",null,"Environment-specific configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n # dev stack has different app configuration from the base\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n }\n replicas = 2\n }\n}\n')),(0,o.kt)("p",null,"Alternatively, you could locate a specific property (in this case below, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," object) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object using the dot selector shorthand(such as ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.containers.myapp")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.replicas")," below):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload.replicas = 2\n workload.containers.myapp: {\n # dev stack has different app configuration\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"This is especially useful when the application configuration is complex but the override is relatively straightforward."),(0,o.kt)("p",null,"The two examples above are equivalent when overriding the base."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d05ef132.ff4dea0a.js b/assets/js/d05ef132.ff4dea0a.js new file mode 100644 index 00000000000..cf285d7320b --- /dev/null +++ b/assets/js/d05ef132.ff4dea0a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5452],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(f,i(i({ref:n},p),{},{components:t})):r.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const a={sidebar_position:3},i="Base and Override",s={unversionedId:"kusion/config-walkthrough/base_override",id:"version-v0.9/kusion/config-walkthrough/base_override",title:"Base and Override",description:"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/base_override.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/base_override",permalink:"/docs/v0.9/kusion/config-walkthrough/base_override",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/base_override.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"kusion",previous:{title:"KCL Basics",permalink:"/docs/v0.9/kusion/config-walkthrough/kcl_basics"},next:{title:"Workload",permalink:"/docs/v0.9/kusion/config-walkthrough/workload"}},c={},l=[],p={toc:l};function d(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"base-and-override"},"Base and Override"),(0,o.kt)("p",null,"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons."),(0,o.kt)("p",null,"In that context, we advocate for a pattern where you can leverage some Kusion and KCL features to minimize the amount of duplicate configurations, by separating the common base application configuration and environment-specific ones."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The file names in the below examples don't matter as long as they are called out and appear in the correct order in the ",(0,o.kt)("inlineCode",{parentName:"p"},"entries")," field (the field is a list) in ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod"),". The files with common configurations should appear first in the list and stack-specific ones last. The latter one takes precedence."),(0,o.kt)("p",{parentName:"admonition"},"The configurations also don't have be placed into a single ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," file. For complex projects, they can be broken down into smaller organized ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," files for better readability. ")),(0,o.kt)("p",null,"Base configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"base/base.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.workload.container as c\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n')),(0,o.kt)("p",null,"Environment-specific configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n # dev stack has different app configuration from the base\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n }\n replicas = 2\n }\n}\n')),(0,o.kt)("p",null,"Alternatively, you could locate a specific property (in this case below, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," object) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object using the dot selector shorthand(such as ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.containers.myapp")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.replicas")," below):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import catalog.models.schema.v1 as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload.replicas = 2\n workload.containers.myapp: {\n # dev stack has different app configuration\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"This is especially useful when the application configuration is complex but the override is relatively straightforward."),(0,o.kt)("p",null,"The two examples above are equivalent when overriding the base."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d08bdbd3.29405804.js b/assets/js/d08bdbd3.29405804.js deleted file mode 100644 index d98bb683c41..00000000000 --- a/assets/js/d08bdbd3.29405804.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5665],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=o,g=c["".concat(s,".").concat(d)]||c[d]||m[d]||a;return n?r.createElement(g,i(i({ref:t},u),{},{components:n})):r.createElement(g,i({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},i="monitoring",l={unversionedId:"kusion/reference/modules/workspace-configs/monitoring/prometheus",id:"kusion/reference/modules/workspace-configs/monitoring/prometheus",title:"monitoring",description:"monitoring can be used to define workspace-level monitoring configurations.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/monitoring",slug:"/kusion/reference/modules/workspace-configs/monitoring/prometheus",permalink:"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/postgres"},next:{title:"port",permalink:"/docs/next/kusion/reference/modules/workspace-configs/networking/port"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],u={toc:p};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"monitoring"},"monitoring"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"monitoring")," can be used to define workspace-level monitoring configurations."),(0,o.kt)("h2",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"operatorMode"),(0,o.kt)("br",null),"Whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,o.kt)("td",{parentName:"tr",align:null},"true ","|"," false"),(0,o.kt)("td",{parentName:"tr",align:null},"false"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"monitorType"),(0,o.kt)("br",null),"The kind of monitor to create. It only applies when operatorMode is set to True."),(0,o.kt)("td",{parentName:"tr",align:null},'"Service" ',"|",' "Pod"'),(0,o.kt)("td",{parentName:"tr",align:null},'"Service"'),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"interval"),(0,o.kt)("br",null),"The time interval which Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping interval can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"30s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"timeout"),(0,o.kt)("br",null),"The timeout when Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping timeout can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"15s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"scheme"),(0,o.kt)("br",null),"The scheme to scrape metrics from. Possible values are http and https."),(0,o.kt)("td",{parentName:"tr",align:null},'"http" ',"|",' "https"'),(0,o.kt)("td",{parentName:"tr",align:null},"http"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n timeout: 1m\n projectSelector:\n - foo\n - bar\n high_frequency:\n monitorType: Service\n interval: 10s\n timeout: 5s\n projectSelector:\n - helloworld\n - wordpress\n - prometheus-sample-app\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d08bdbd3.c2a6f40d.js b/assets/js/d08bdbd3.c2a6f40d.js new file mode 100644 index 00000000000..203e4fd848e --- /dev/null +++ b/assets/js/d08bdbd3.c2a6f40d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5665],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=o,g=c["".concat(s,".").concat(d)]||c[d]||m[d]||a;return n?r.createElement(g,i(i({ref:t},u),{},{components:n})):r.createElement(g,i({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},i="monitoring",l={unversionedId:"kusion/reference/modules/workspace-configs/monitoring/prometheus",id:"kusion/reference/modules/workspace-configs/monitoring/prometheus",title:"monitoring",description:"monitoring can be used to define workspace-level monitoring configurations.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/monitoring",slug:"/kusion/reference/modules/workspace-configs/monitoring/prometheus",permalink:"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/next/kusion/reference/modules/workspace-configs/database/postgres"},next:{title:"port",permalink:"/docs/next/kusion/reference/modules/workspace-configs/networking/port"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],u={toc:p};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"monitoring"},"monitoring"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"monitoring")," can be used to define workspace-level monitoring configurations."),(0,o.kt)("h2",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"operatorMode"),(0,o.kt)("br",null),"Whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,o.kt)("td",{parentName:"tr",align:null},"true ","|"," false"),(0,o.kt)("td",{parentName:"tr",align:null},"false"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"monitorType"),(0,o.kt)("br",null),"The kind of monitor to create. It only applies when operatorMode is set to True."),(0,o.kt)("td",{parentName:"tr",align:null},'"Service" ',"|",' "Pod"'),(0,o.kt)("td",{parentName:"tr",align:null},'"Service"'),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"interval"),(0,o.kt)("br",null),"The time interval which Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping interval can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"30s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"timeout"),(0,o.kt)("br",null),"The timeout when Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping timeout can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"15s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"scheme"),(0,o.kt)("br",null),"The scheme to scrape metrics from. Possible values are http and https."),(0,o.kt)("td",{parentName:"tr",align:null},'"http" ',"|",' "https"'),(0,o.kt)("td",{parentName:"tr",align:null},"http"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n timeout: 1m\n projectSelector:\n - foo\n - bar\n high_frequency:\n monitorType: Service\n interval: 10s\n timeout: 5s\n projectSelector:\n - helloworld\n - wordpress\n - prometheus-sample-app\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d107a415.b51c0c01.js b/assets/js/d107a415.66e33494.js similarity index 55% rename from assets/js/d107a415.b51c0c01.js rename to assets/js/d107a415.66e33494.js index 800d0420f6f..df23d4d6abd 100644 --- a/assets/js/d107a415.b51c0c01.js +++ b/assets/js/d107a415.66e33494.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6945],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||l[f]||a;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},i="kusion workspace update",s={unversionedId:"kusion/reference/commands/kusion-workspace-update",id:"version-v0.10/kusion/reference/commands/kusion-workspace-update",title:"kusion workspace update",description:"Update a workspace configuration",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-update.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-update",permalink:"/docs/kusion/reference/commands/kusion-workspace-update",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-update.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace show",permalink:"/docs/kusion/reference/commands/kusion-workspace-show"},next:{title:"kusion workspace",permalink:"/docs/kusion/reference/commands/kusion-workspace"}},p={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],u={toc:c};function l(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-update"},"kusion workspace update"),(0,o.kt)("p",null,"Update a workspace configuration"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command updates a workspace configuration with specified configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace update\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Update a workspace configuration\n kusion workspace update dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for update\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6945],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,m=d["".concat(p,".").concat(f)]||d[f]||l[f]||a;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={},i="kusion workspace update",s={unversionedId:"kusion/reference/commands/kusion-workspace-update",id:"version-v0.10/kusion/reference/commands/kusion-workspace-update",title:"kusion workspace update",description:"Update a workspace configuration",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-update.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-update",permalink:"/docs/kusion/reference/commands/kusion-workspace-update",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-update.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion workspace show",permalink:"/docs/kusion/reference/commands/kusion-workspace-show"},next:{title:"kusion workspace",permalink:"/docs/kusion/reference/commands/kusion-workspace"}},p={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],u={toc:c};function l(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-update"},"kusion workspace update"),(0,o.kt)("p",null,"Update a workspace configuration"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command updates a workspace configuration with specified configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace update\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Update a workspace configuration\n kusion workspace update dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for update\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d33f5cb2.22228d8c.js b/assets/js/d33f5cb2.22228d8c.js new file mode 100644 index 00000000000..eeb705aead8 --- /dev/null +++ b/assets/js/d33f5cb2.22228d8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1137],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),u=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var r=n(87462),o=(n(67294),n(3905));const a={},i="Kusion Commands",s={unversionedId:"kusion/reference/commands/index",id:"kusion/reference/commands/index",title:"Kusion Commands",description:"Kusion is the Platform Orchestrator of KusionStack",source:"@site/docs/kusion/6-reference/1-commands/index.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/",permalink:"/docs/next/kusion/reference/commands/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/index.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Using Cloud Secrets Manager",permalink:"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets"},next:{title:"kusion apply",permalink:"/docs/next/kusion/reference/commands/kusion-apply"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:u};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-commands"},"Kusion Commands"),(0,o.kt)("p",null,"Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"As a Platform Orchestrator, Kusion delivers user intentions to Kubernetes, Clouds and On-Premise resources. Also enables asynchronous cooperation between the development and the platform team and drives the separation of concerns."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' -h, --help help for kusion\n --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-apply"},"kusion apply"),"\t - Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-build"},"kusion build"),"\t - Build Kusion modules in a Stack to the Intent"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-compile"},"kusion compile"),"\t - Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-destroy"},"kusion destroy"),"\t - Destroy resources within the stack."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-init"},"kusion init"),"\t - Initialize the scaffolding for a project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-preview"},"kusion preview"),"\t - Preview a series of resource changes within the stack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-version"},"kusion version"),"\t - Print the Kusion version information for the current context"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d33f5cb2.8fdce34e.js b/assets/js/d33f5cb2.8fdce34e.js deleted file mode 100644 index 883b61274dc..00000000000 --- a/assets/js/d33f5cb2.8fdce34e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1137],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),u=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var r=n(87462),o=(n(67294),n(3905));const a={},i="Kusion Commands",s={unversionedId:"kusion/reference/commands/index",id:"kusion/reference/commands/index",title:"Kusion Commands",description:"Kusion is the Platform Orchestrator of KusionStack",source:"@site/docs/kusion/6-reference/1-commands/index.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/",permalink:"/docs/next/kusion/reference/commands/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/index.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Using Cloud Secrets Manager",permalink:"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets"},next:{title:"kusion apply",permalink:"/docs/next/kusion/reference/commands/kusion-apply"}},c={},u=[{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:u};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-commands"},"Kusion Commands"),(0,o.kt)("p",null,"Kusion is the Platform Orchestrator of KusionStack"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"As a Platform Orchestrator, Kusion delivers user intentions to Kubernetes, Clouds and On-Premise resources. Also enables asynchronous cooperation between the development and the platform team and drives the separation of concerns."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion [flags]\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' -h, --help help for kusion\n --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-apply"},"kusion apply"),"\t - Apply the operational intent of various resources to multiple runtimes"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-build"},"kusion build"),"\t - Build Kusion modules in a Stack to the Intent"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-compile"},"kusion compile"),"\t - Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-destroy"},"kusion destroy"),"\t - Destroy resources within the stack."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-init"},"kusion init"),"\t - Initialize the scaffolding for a project"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-preview"},"kusion preview"),"\t - Preview a series of resource changes within the stack"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-version"},"kusion version"),"\t - Print the Kusion version information for the current context"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d398f178.15ecdd0f.js b/assets/js/d398f178.15ecdd0f.js deleted file mode 100644 index 8ba821a6060..00000000000 --- a/assets/js/d398f178.15ecdd0f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[654],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=o.createContext({}),u=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,f=m["".concat(p,".").concat(d)]||m[d]||c[d]||a;return n?o.createElement(f,i(i({ref:t},l),{},{components:n})):o.createElement(f,i({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const a={},i="Application Monitoring",s={unversionedId:"kusion/configuration-walkthrough/monitoring",id:"version-v0.10/kusion/configuration-walkthrough/monitoring",title:"Application Monitoring",description:"The monitoring attribute in the AppConfiguration instance is used to describe the specification for the collection of monitoring requirements for the application.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/8-monitoring.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/monitoring",permalink:"/docs/kusion/configuration-walkthrough/monitoring",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/8-monitoring.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{},sidebar:"kusion",previous:{title:"Secrets",permalink:"/docs/kusion/configuration-walkthrough/secret"},next:{title:"Operational Rules",permalink:"/docs/kusion/configuration-walkthrough/operational-rules"}},p={},u=[{value:"Import",id:"import",level:2},{value:"Workspace configurations",id:"workspace-configurations",level:2},{value:"Managing Scraping Configuration",id:"managing-scraping-configuration",level:2},{value:"Default values",id:"default-values",level:2}],l={toc:u};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-monitoring"},"Application Monitoring"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of monitoring requirements for the application."),(0,r.kt)("p",null,"As of version 0.10.0, Kusion supports integration with Prometheus by managing scraping behaviors in the configuration file."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute requires the target cluster to have installed Prometheus correctly, either as a Kubernetes operator or a server/agent."),(0,r.kt)("p",{parentName:"admonition"},"More about how to set up Prometheus can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus"},"Prometheus User Guide for Kusion"))),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.monitoring as m\n")),(0,r.kt)("h2",{id:"workspace-configurations"},"Workspace configurations"),(0,r.kt)("p",null,"In addition to the KCL configuration file, there are also workspace-level configurations that should be set first. In an ideal scenario, this step is done by the platform engineers. "),(0,r.kt)("p",null,"In the event that they do not exist for you or your organization, e.g. if you are an individual developer, you can either do it yourself or use the ",(0,r.kt)("a",{parentName:"p",href:"#default-values"},"default values")," provided by the KusionStack team. The steps to do this yourself can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"Prometheus User Guide for Kusion"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For more details on how workspaces work, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/workspace"},"workspace concept"))),(0,r.kt)("p",null,"By separating configurations that the developers are interested in and those that platform owners are interested in, we can reduce the cognitive complexity of the application configuration and achieve separation of concern."),(0,r.kt)("h2",{id:"managing-scraping-configuration"},"Managing Scraping Configuration"),(0,r.kt)("p",null,"To manage scrape configuration for the application:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n path: "/metrics"\n port: "web"\n }\n}\n')),(0,r.kt)("p",null,"The example above will instruct the Prometheus job to scrape metrics from the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint of the application on the port named ",(0,r.kt)("inlineCode",{parentName:"p"},"web"),"."),(0,r.kt)("p",null,"To instruct Prometheus to scrape from ",(0,r.kt)("inlineCode",{parentName:"p"},"/actuator/metrics")," on port ",(0,r.kt)("inlineCode",{parentName:"p"},"9099")," instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n path: "/actuator/metrics"\n port: "9099"\n }\n}\n')),(0,r.kt)("p",null,"Note that numbered ports only work when your Prometheus is not running as an operator. "),(0,r.kt)("p",null,"Neither ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," are required fields if Prometheus runs as an operator. If omitted, ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," defaults to the container port or service port, depending on which resource is being monitored. If Prometheus does not run as an operator, both fields are required."),(0,r.kt)("p",null,"Scraping scheme, interval and timeout are considered platform-managed configurations and are therefore managed as part of the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"workspace configurations"),"."),(0,r.kt)("p",null,"More details about how the Prometheus integration works can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md"},"design documentation"),"."),(0,r.kt)("h2",{id:"default-values"},"Default values"),(0,r.kt)("p",null,"If no workspace configurations are found, the default values provided by the KusionStack team are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Scraping interval defaults to 30 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping timeout defaults to 15 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping scheme defaults to http"),(0,r.kt)("li",{parentName:"ul"},"Defaults to NOT running as an operator")),(0,r.kt)("p",null,"If any of the default values does not meet your need, you can change them by ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"setting up the workspace configuration"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d398f178.b537c3ee.js b/assets/js/d398f178.b537c3ee.js new file mode 100644 index 00000000000..0215709298c --- /dev/null +++ b/assets/js/d398f178.b537c3ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[654],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var o=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=o.createContext({}),u=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=u(n),d=r,f=m["".concat(p,".").concat(d)]||m[d]||c[d]||a;return n?o.createElement(f,i(i({ref:t},l),{},{components:n})):o.createElement(f,i({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var o=n(87462),r=(n(67294),n(3905));const a={},i="Application Monitoring",s={unversionedId:"kusion/configuration-walkthrough/monitoring",id:"version-v0.10/kusion/configuration-walkthrough/monitoring",title:"Application Monitoring",description:"The monitoring attribute in the AppConfiguration instance is used to describe the specification for the collection of monitoring requirements for the application.",source:"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/8-monitoring.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/monitoring",permalink:"/docs/kusion/configuration-walkthrough/monitoring",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/8-monitoring.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:8,frontMatter:{},sidebar:"kusion",previous:{title:"Secrets",permalink:"/docs/kusion/configuration-walkthrough/secret"},next:{title:"Operational Rules",permalink:"/docs/kusion/configuration-walkthrough/operational-rules"}},p={},u=[{value:"Import",id:"import",level:2},{value:"Workspace configurations",id:"workspace-configurations",level:2},{value:"Managing Scraping Configuration",id:"managing-scraping-configuration",level:2},{value:"Default values",id:"default-values",level:2}],l={toc:u};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-monitoring"},"Application Monitoring"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of monitoring requirements for the application."),(0,r.kt)("p",null,"As of version 0.10.0, Kusion supports integration with Prometheus by managing scraping behaviors in the configuration file."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"monitoring")," attribute requires the target cluster to have installed Prometheus correctly, either as a Kubernetes operator or a server/agent."),(0,r.kt)("p",{parentName:"admonition"},"More about how to set up Prometheus can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus"},"Prometheus User Guide for Kusion"))),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.monitoring as m\n")),(0,r.kt)("h2",{id:"workspace-configurations"},"Workspace configurations"),(0,r.kt)("p",null,"In addition to the KCL configuration file, there are also workspace-level configurations that should be set first. In an ideal scenario, this step is done by the platform engineers. "),(0,r.kt)("p",null,"In the event that they do not exist for you or your organization, e.g. if you are an individual developer, you can either do it yourself or use the ",(0,r.kt)("a",{parentName:"p",href:"#default-values"},"default values")," provided by the KusionStack team. The steps to do this yourself can be found in the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"Prometheus User Guide for Kusion"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"For more details on how workspaces work, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/kusion/concepts/workspace"},"workspace concept"))),(0,r.kt)("p",null,"By separating configurations that the developers are interested in and those that platform owners are interested in, we can reduce the cognitive complexity of the application configuration and achieve separation of concern."),(0,r.kt)("h2",{id:"managing-scraping-configuration"},"Managing Scraping Configuration"),(0,r.kt)("p",null,"To manage scrape configuration for the application:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n path: "/metrics"\n port: "web"\n }\n}\n')),(0,r.kt)("p",null,"The example above will instruct the Prometheus job to scrape metrics from the ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics")," endpoint of the application on the port named ",(0,r.kt)("inlineCode",{parentName:"p"},"web"),"."),(0,r.kt)("p",null,"To instruct Prometheus to scrape from ",(0,r.kt)("inlineCode",{parentName:"p"},"/actuator/metrics")," on port ",(0,r.kt)("inlineCode",{parentName:"p"},"9099")," instead:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n monitoring: m.Prometheus{\n path: "/actuator/metrics"\n port: "9099"\n }\n}\n')),(0,r.kt)("p",null,"Note that numbered ports only work when your Prometheus is not running as an operator. "),(0,r.kt)("p",null,"Neither ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," are required fields if Prometheus runs as an operator. If omitted, ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"/metrics"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," defaults to the container port or service port, depending on which resource is being monitored. If Prometheus does not run as an operator, both fields are required."),(0,r.kt)("p",null,"Scraping scheme, interval and timeout are considered platform-managed configurations and are therefore managed as part of the ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"workspace configurations"),"."),(0,r.kt)("p",null,"More details about how the Prometheus integration works can be found in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/docs/prometheus.md"},"design documentation"),"."),(0,r.kt)("h2",{id:"default-values"},"Default values"),(0,r.kt)("p",null,"If no workspace configurations are found, the default values provided by the KusionStack team are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Scraping interval defaults to 30 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping timeout defaults to 15 seconds"),(0,r.kt)("li",{parentName:"ul"},"Scraping scheme defaults to http"),(0,r.kt)("li",{parentName:"ul"},"Defaults to NOT running as an operator")),(0,r.kt)("p",null,"If any of the default values does not meet your need, you can change them by ",(0,r.kt)("a",{parentName:"p",href:"../user-guides/observability/prometheus#setting-up-workspace-configs"},"setting up the workspace configuration"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d5b05897.a399b999.js b/assets/js/d5b05897.a399b999.js new file mode 100644 index 00000000000..1e2762c1568 --- /dev/null +++ b/assets/js/d5b05897.a399b999.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7736],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>f});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),p=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},l=function(e){var n=p(e.components);return r.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(t),f=o,m=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return t?r.createElement(m,i(i({ref:n},l),{},{components:t})):r.createElement(m,i({ref:n},l))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=t(87462),o=(t(67294),t(3905));const a={id:"base-override"},i="Base and Override",s={unversionedId:"kusion/configuration-walkthrough/base-override",id:"kusion/configuration-walkthrough/base-override",title:"Base and Override",description:"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.",source:"@site/docs/kusion/4-configuration-walkthrough/3-base-override.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/base-override",permalink:"/docs/next/kusion/configuration-walkthrough/base-override",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/3-base-override.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"base-override"},sidebar:"kusion",previous:{title:"KCL Basics",permalink:"/docs/next/kusion/configuration-walkthrough/kcl-basics"},next:{title:"Workload",permalink:"/docs/next/kusion/configuration-walkthrough/workload"}},c={},p=[],l={toc:p};function d(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"base-and-override"},"Base and Override"),(0,o.kt)("p",null,"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons."),(0,o.kt)("p",null,"In that context, we advocate for a pattern where you can leverage some Kusion and KCL features to minimize the amount of duplicate configurations, by separating the common base application configuration and environment-specific ones."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The file names in the below examples don't matter as long as they are called out and appear in the correct order in the ",(0,o.kt)("inlineCode",{parentName:"p"},"entries")," field (the field is a list) in ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod"),". The files with common configurations should appear first in the list and stack-specific ones last. The latter one takes precedence."),(0,o.kt)("p",{parentName:"admonition"},"The configurations also don't have be placed into a single ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," file. For complex projects, they can be broken down into smaller organized ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," files for better readability. ")),(0,o.kt)("p",null,"Base configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"base/base.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport network.network as n\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n }\n}\n')),(0,o.kt)("p",null,"Environment-specific configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n # dev stack has different app configuration from the base\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n }\n replicas = 2\n }\n}\n')),(0,o.kt)("p",null,"Alternatively, you could locate a specific property (in this case below, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," object) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object using the dot selector shorthand(such as ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.containers.myapp")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.replicas")," below):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload.replicas = 2\n workload.containers.myapp: {\n # dev stack has different app configuration\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"This is especially useful when the application configuration is complex but the override is relatively straightforward."),(0,o.kt)("p",null,"The two examples above are equivalent when overriding the base."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d5b05897.c920e343.js b/assets/js/d5b05897.c920e343.js deleted file mode 100644 index a851cb13aa1..00000000000 --- a/assets/js/d5b05897.c920e343.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7736],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>f});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),p=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},l=function(e){var n=p(e.components);return r.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(t),f=o,m=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return t?r.createElement(m,i(i({ref:n},l),{},{components:t})):r.createElement(m,i({ref:n},l))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=u;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=t(87462),o=(t(67294),t(3905));const a={id:"base-override"},i="Base and Override",s={unversionedId:"kusion/configuration-walkthrough/base-override",id:"kusion/configuration-walkthrough/base-override",title:"Base and Override",description:"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons.",source:"@site/docs/kusion/4-configuration-walkthrough/3-base-override.md",sourceDirName:"kusion/4-configuration-walkthrough",slug:"/kusion/configuration-walkthrough/base-override",permalink:"/docs/next/kusion/configuration-walkthrough/base-override",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/4-configuration-walkthrough/3-base-override.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{id:"base-override"},sidebar:"kusion",previous:{title:"KCL Basics",permalink:"/docs/next/kusion/configuration-walkthrough/kcl-basics"},next:{title:"Workload",permalink:"/docs/next/kusion/configuration-walkthrough/workload"}},c={},p=[],l={toc:p};function d(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"base-and-override"},"Base and Override"),(0,o.kt)("p",null,"In practice, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets, be it different environments in the SDLC, or different clouds, regions or runtimes for cost/regulation/performance or disaster recovery related reasons."),(0,o.kt)("p",null,"In that context, we advocate for a pattern where you can leverage some Kusion and KCL features to minimize the amount of duplicate configurations, by separating the common base application configuration and environment-specific ones."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"The file names in the below examples don't matter as long as they are called out and appear in the correct order in the ",(0,o.kt)("inlineCode",{parentName:"p"},"entries")," field (the field is a list) in ",(0,o.kt)("inlineCode",{parentName:"p"},"kcl.mod"),". The files with common configurations should appear first in the list and stack-specific ones last. The latter one takes precedence."),(0,o.kt)("p",{parentName:"admonition"},"The configurations also don't have be placed into a single ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," file. For complex projects, they can be broken down into smaller organized ",(0,o.kt)("inlineCode",{parentName:"p"},".k")," files for better readability. ")),(0,o.kt)("p",null,"Base configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"base/base.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\nimport kam.v1.workload as wl\nimport kam.v1.workload.container as c\nimport network.network as n\n\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n image: ""\n resources: {\n "cpu": "500m"\n "memory": "512Mi"\n }\n }\n }\n replicas: 1\n }\n accessories: {\n "network": n.Network {\n ports: [\n n.Port {\n port: 80\n public: True\n }\n ]\n }\n }\n}\n')),(0,o.kt)("p",null,"Environment-specific configuration defined in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "myapp": c.Container {\n # dev stack has different app configuration from the base\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n }\n replicas = 2\n }\n}\n')),(0,o.kt)("p",null,"Alternatively, you could locate a specific property (in this case below, the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," object) in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," object using the dot selector shorthand(such as ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.containers.myapp")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"workload.replicas")," below):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'import kam.v1.app_configuration as ac\n\n# main.k declares customized configurations for dev stack.\nmyapp: ac.AppConfiguration {\n workload.replicas = 2\n workload.containers.myapp: {\n # dev stack has different app configuration\n image = "gcr.io/google-samples/gb-frontend:v5"\n resources = {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"This is especially useful when the application configuration is complex but the override is relatively straightforward."),(0,o.kt)("p",null,"The two examples above are equivalent when overriding the base."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d5d68d14.1c4e0780.js b/assets/js/d5d68d14.c5270262.js similarity index 83% rename from assets/js/d5d68d14.1c4e0780.js rename to assets/js/d5d68d14.c5270262.js index 33124fe7da9..362ba0499f9 100644 --- a/assets/js/d5d68d14.1c4e0780.js +++ b/assets/js/d5d68d14.c5270262.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9093],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),d=c(r),f=o,m=d["".concat(u,".").concat(f)]||d[f]||p[f]||i;return r?n.createElement(m,s(s({ref:t},l),{},{components:r})):n.createElement(m,s({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var u in t)hasOwnProperty.call(t,u)&&(a[u]=t[u]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const i={},s="User Guide",a={unversionedId:"kusion/guides/guides",id:"version-v0.9/kusion/guides/guides",title:"User Guide",description:"",source:"@site/versioned_docs/version-v0.9/kusion/guides/guides.md",sourceDirName:"kusion/guides",slug:"/kusion/guides/",permalink:"/docs/v0.9/kusion/guides/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/guides.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Operational Rules",permalink:"/docs/v0.9/kusion/config-walkthrough/operational_rules"},next:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/v0.9/kusion/guides/cloud-resources/database"}},u={},c=[],l={toc:c};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"user-guide"},"User Guide"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9093],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),d=c(r),f=o,m=d["".concat(u,".").concat(f)]||d[f]||p[f]||i;return r?n.createElement(m,s(s({ref:t},l),{},{components:r})):n.createElement(m,s({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var u in t)hasOwnProperty.call(t,u)&&(a[u]=t[u]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const i={},s="User Guide",a={unversionedId:"kusion/guides/guides",id:"version-v0.9/kusion/guides/guides",title:"User Guide",description:"",source:"@site/versioned_docs/version-v0.9/kusion/guides/guides.md",sourceDirName:"kusion/guides",slug:"/kusion/guides/",permalink:"/docs/v0.9/kusion/guides/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/guides.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Operational Rules",permalink:"/docs/v0.9/kusion/config-walkthrough/operational_rules"},next:{title:"Deliver the WordPress Application with Cloud RDS",permalink:"/docs/v0.9/kusion/guides/cloud-resources/database"}},u={},c=[],l={toc:c};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"user-guide"},"User Guide"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d65cad0c.d29f91ad.js b/assets/js/d65cad0c.5f482958.js similarity index 85% rename from assets/js/d65cad0c.d29f91ad.js rename to assets/js/d65cad0c.5f482958.js index 3493ef38db8..d5bb64494d6 100644 --- a/assets/js/d65cad0c.d29f91ad.js +++ b/assets/js/d65cad0c.5f482958.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2713],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=o,d=u["".concat(s,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,i(i({ref:t},p),{},{components:r})):n.createElement(d,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:1},i="FAQ",c={unversionedId:"ctrlmesh/faq/faq",id:"version-v0.10/ctrlmesh/faq/faq",title:"FAQ",description:"",source:"@site/versioned_docs/version-v0.10/ctrlmesh/faq/faq.md",sourceDirName:"ctrlmesh/faq",slug:"/ctrlmesh/faq/",permalink:"/docs/ctrlmesh/faq/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/faq/faq.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Try a Sample",permalink:"/docs/ctrlmesh/started/try"}},s={},l=[],p={toc:l};function f(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2713],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=o,d=u["".concat(s,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,i(i({ref:t},p),{},{components:r})):n.createElement(d,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:1},i="FAQ",c={unversionedId:"ctrlmesh/faq/faq",id:"version-v0.10/ctrlmesh/faq/faq",title:"FAQ",description:"",source:"@site/versioned_docs/version-v0.10/ctrlmesh/faq/faq.md",sourceDirName:"ctrlmesh/faq",slug:"/ctrlmesh/faq/",permalink:"/docs/ctrlmesh/faq/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/faq/faq.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Try a Sample",permalink:"/docs/ctrlmesh/started/try"}},s={},l=[],p={toc:l};function f(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d7b729b6.827935fd.js b/assets/js/d7b729b6.96f32350.js similarity index 50% rename from assets/js/d7b729b6.827935fd.js rename to assets/js/d7b729b6.96f32350.js index e4d112bff0c..742c2de6af7 100644 --- a/assets/js/d7b729b6.827935fd.js +++ b/assets/js/d7b729b6.96f32350.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9756],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),d=p(r),m=o,b=d["".concat(s,".").concat(m)]||d[m]||u[m]||i;return r?n.createElement(b,l(l({ref:t},c),{},{components:r})):n.createElement(b,l({ref:t},c))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,l=new Array(i);l[0]=d;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a.mdxType="string"==typeof e?e:o,l[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:1},l="Installation",a={unversionedId:"kusion/support/install-error",id:"version-v0.9/kusion/support/install-error",title:"Installation",description:"1. Could not find libintl.dylib",source:"@site/versioned_docs/version-v0.9/kusion/support/install-error.md",sourceDirName:"kusion/support",slug:"/kusion/support/install-error",permalink:"/docs/v0.9/kusion/support/install-error",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/support/install-error.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"FAQ",permalink:"/docs/v0.9/kusion/support/"},next:{title:"KCL",permalink:"/docs/v0.9/kusion/support/kcl"}},s={},p=[{value:"1. Could not find libintl.dylib",id:"1-could-not-find-libintldylib",level:2},{value:"2. macOS system SSL related errors",id:"2-macos-system-ssl-related-errors",level:2}],c={toc:p};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installation"},"Installation"),(0,o.kt)("h2",{id:"1-could-not-find-libintldylib"},"1. Could not find ",(0,o.kt)("inlineCode",{parentName:"h2"},"libintl.dylib")),(0,o.kt)("p",null,"This problem is that some tools depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"Gettext")," library, but macOS does not have this library by default. You can try to solve it in the following ways:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"brew install gettext")),(0,o.kt)("li",{parentName:"ol"},"Make sure ",(0,o.kt)("inlineCode",{parentName:"li"},"libintl.8.dylib")," exists in ",(0,o.kt)("inlineCode",{parentName:"li"},"/usr/local/opt/gettext/lib")," directory"),(0,o.kt)("li",{parentName:"ol"},"If brew is installed in another directory, the library can be created by copying it to the corresponding directory")),(0,o.kt)("h2",{id:"2-macos-system-ssl-related-errors"},"2. macOS system SSL related errors"),(0,o.kt)("p",null,"Openssl dylib library not found or SSL module is not available problem"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Install openssl (version 1.1) via brew")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"brew install openssl@1.1\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9756],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),d=p(r),m=o,b=d["".concat(s,".").concat(m)]||d[m]||u[m]||i;return r?n.createElement(b,l(l({ref:t},c),{},{components:r})):n.createElement(b,l({ref:t},c))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,l=new Array(i);l[0]=d;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a.mdxType="string"==typeof e?e:o,l[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const i={sidebar_position:1},l="Installation",a={unversionedId:"kusion/support/install-error",id:"version-v0.9/kusion/support/install-error",title:"Installation",description:"1. Could not find libintl.dylib",source:"@site/versioned_docs/version-v0.9/kusion/support/install-error.md",sourceDirName:"kusion/support",slug:"/kusion/support/install-error",permalink:"/docs/v0.9/kusion/support/install-error",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/support/install-error.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"kusion",previous:{title:"FAQ",permalink:"/docs/v0.9/kusion/support/"},next:{title:"KCL",permalink:"/docs/v0.9/kusion/support/kcl"}},s={},p=[{value:"1. Could not find libintl.dylib",id:"1-could-not-find-libintldylib",level:2},{value:"2. macOS system SSL related errors",id:"2-macos-system-ssl-related-errors",level:2}],c={toc:p};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installation"},"Installation"),(0,o.kt)("h2",{id:"1-could-not-find-libintldylib"},"1. Could not find ",(0,o.kt)("inlineCode",{parentName:"h2"},"libintl.dylib")),(0,o.kt)("p",null,"This problem is that some tools depends on the ",(0,o.kt)("inlineCode",{parentName:"p"},"Gettext")," library, but macOS does not have this library by default. You can try to solve it in the following ways:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("inlineCode",{parentName:"li"},"brew install gettext")),(0,o.kt)("li",{parentName:"ol"},"Make sure ",(0,o.kt)("inlineCode",{parentName:"li"},"libintl.8.dylib")," exists in ",(0,o.kt)("inlineCode",{parentName:"li"},"/usr/local/opt/gettext/lib")," directory"),(0,o.kt)("li",{parentName:"ol"},"If brew is installed in another directory, the library can be created by copying it to the corresponding directory")),(0,o.kt)("h2",{id:"2-macos-system-ssl-related-errors"},"2. macOS system SSL related errors"),(0,o.kt)("p",null,"Openssl dylib library not found or SSL module is not available problem"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"(Skip this step for non-macOS m1) For macOS m1 operating system, make sure you have a homebrew arm64e-version installed in /opt/homebrew, otherwise install the arm version of brew with the following command")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n# add to path\nexport PATH=/opt/homebrew/bin:$PATH\n')),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Install openssl (version 1.1) via brew")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"brew install openssl@1.1\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d9a047ee.31f9d1e2.js b/assets/js/d9a047ee.31f9d1e2.js new file mode 100644 index 00000000000..ed9083073d0 --- /dev/null +++ b/assets/js/d9a047ee.31f9d1e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[795],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=o,g=c["".concat(s,".").concat(d)]||c[d]||m[d]||a;return n?r.createElement(g,i(i({ref:t},u),{},{components:n})):r.createElement(g,i({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},i="monitoring",l={unversionedId:"kusion/reference/modules/workspace-configs/monitoring/prometheus",id:"version-v0.10/kusion/reference/modules/workspace-configs/monitoring/prometheus",title:"monitoring",description:"monitoring can be used to define workspace-level monitoring configurations.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/monitoring",slug:"/kusion/reference/modules/workspace-configs/monitoring/prometheus",permalink:"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/kusion/reference/modules/workspace-configs/database/postgres"},next:{title:"port",permalink:"/docs/kusion/reference/modules/workspace-configs/networking/port"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],u={toc:p};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"monitoring"},"monitoring"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"monitoring")," can be used to define workspace-level monitoring configurations."),(0,o.kt)("h2",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"operatorMode"),(0,o.kt)("br",null),"Whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,o.kt)("td",{parentName:"tr",align:null},"true ","|"," false"),(0,o.kt)("td",{parentName:"tr",align:null},"false"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"monitorType"),(0,o.kt)("br",null),"The kind of monitor to create. It only applies when operatorMode is set to True."),(0,o.kt)("td",{parentName:"tr",align:null},'"Service" ',"|",' "Pod"'),(0,o.kt)("td",{parentName:"tr",align:null},'"Service"'),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"interval"),(0,o.kt)("br",null),"The time interval which Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping interval can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"30s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"timeout"),(0,o.kt)("br",null),"The timeout when Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping timeout can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"15s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"scheme"),(0,o.kt)("br",null),"The scheme to scrape metrics from. Possible values are http and https."),(0,o.kt)("td",{parentName:"tr",align:null},'"http" ',"|",' "https"'),(0,o.kt)("td",{parentName:"tr",align:null},"http"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n timeout: 1m\n projectSelector:\n - foo\n - bar\n high_frequency:\n monitorType: Service\n interval: 10s\n timeout: 5s\n projectSelector:\n - helloworld\n - wordpress\n - prometheus-sample-app\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d9a047ee.63be3c37.js b/assets/js/d9a047ee.63be3c37.js deleted file mode 100644 index ba8d580933f..00000000000 --- a/assets/js/d9a047ee.63be3c37.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[795],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=o,g=c["".concat(s,".").concat(d)]||c[d]||m[d]||a;return n?r.createElement(g,i(i({ref:t},u),{},{components:n})):r.createElement(g,i({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var r=n(87462),o=(n(67294),n(3905));const a={},i="monitoring",l={unversionedId:"kusion/reference/modules/workspace-configs/monitoring/prometheus",id:"version-v0.10/kusion/reference/modules/workspace-configs/monitoring/prometheus",title:"monitoring",description:"monitoring can be used to define workspace-level monitoring configurations.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/monitoring",slug:"/kusion/reference/modules/workspace-configs/monitoring/prometheus",permalink:"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"postgres",permalink:"/docs/kusion/reference/modules/workspace-configs/database/postgres"},next:{title:"port",permalink:"/docs/kusion/reference/modules/workspace-configs/networking/port"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],u={toc:p};function m(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"monitoring"},"monitoring"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"monitoring")," can be used to define workspace-level monitoring configurations."),(0,o.kt)("h2",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"operatorMode"),(0,o.kt)("br",null),"Whether the Prometheus instance installed in the cluster runs as a Kubernetes operator or not. This determines the different kinds of resources Kusion manages."),(0,o.kt)("td",{parentName:"tr",align:null},"true ","|"," false"),(0,o.kt)("td",{parentName:"tr",align:null},"false"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"monitorType"),(0,o.kt)("br",null),"The kind of monitor to create. It only applies when operatorMode is set to True."),(0,o.kt)("td",{parentName:"tr",align:null},'"Service" ',"|",' "Pod"'),(0,o.kt)("td",{parentName:"tr",align:null},'"Service"'),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"interval"),(0,o.kt)("br",null),"The time interval which Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping interval can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"30s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"timeout"),(0,o.kt)("br",null),"The timeout when Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,o.kt)("br",null),"When operator mode is set to false, the scraping timeout can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"15s"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"scheme"),(0,o.kt)("br",null),"The scheme to scrape metrics from. Possible values are http and https."),(0,o.kt)("td",{parentName:"tr",align:null},'"http" ',"|",' "https"'),(0,o.kt)("td",{parentName:"tr",align:null},"http"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n monitoring:\n default:\n operatorMode: True\n monitorType: Pod\n scheme: http\n interval: 30s\n timeout: 15s\n low_frequency:\n operatorMode: False\n interval: 2m\n timeout: 1m\n projectSelector:\n - foo\n - bar\n high_frequency:\n monitorType: Service\n interval: 10s\n timeout: 5s\n projectSelector:\n - helloworld\n - wordpress\n - prometheus-sample-app\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/da7786fc.6c63c41b.js b/assets/js/da7786fc.6c63c41b.js new file mode 100644 index 00000000000..068ece233d0 --- /dev/null +++ b/assets/js/da7786fc.6c63c41b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3027],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=r,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return t?a.createElement(m,i(i({ref:n},c),{},{components:t})):a.createElement(m,i({ref:n},c))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={},i="Using KusionStack Operating to operate Pods gracefully",l={unversionedId:"operating/started/demo-graceful-operation",id:"version-v0.9/operating/started/demo-graceful-operation",title:"Using KusionStack Operating to operate Pods gracefully",description:"Applications always provide its service along with traffic routing.",source:"@site/versioned_docs/version-v0.9/operating/started/demo-graceful-operation.md",sourceDirName:"operating/started",slug:"/operating/started/demo-graceful-operation",permalink:"/docs/v0.9/operating/started/demo-graceful-operation",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/started/demo-graceful-operation.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",previous:{title:"Installation",permalink:"/docs/v0.9/operating/started/install"},next:{title:"PodOpsLifecycle",permalink:"/docs/v0.9/operating/concepts/podopslifecycle"}},s={},p=[{value:"Preparing",id:"preparing",level:2},{value:"Get started",id:"get-started",level:2},{value:"Create a new namespace",id:"create-a-new-namespace",level:3},{value:"Provision Pods and Services",id:"provision-pods-and-services",level:3},{value:"Provision a client",id:"provision-a-client",level:3},{value:"Update Pod revision",id:"update-pod-revision",level:3},{value:"Provision PodTransistionRule",id:"provision-podtransistionrule",level:3},{value:"Clean tutorial namespace",id:"clean-tutorial-namespace",level:3},{value:"Comparison with the Native Approach",id:"comparison-with-the-native-approach",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-kusionstack-operating-to-operate-pods-gracefully"},"Using KusionStack Operating to operate Pods gracefully"),(0,r.kt)("p",null,"Applications always provide its service along with traffic routing.\nOn Kubernetes, they should be a set of Pods and a corresponding Kubernetes Service resource to expose the service."),(0,r.kt)("p",null,"However, during operations such as updating Pod revisions,\nthere is a risk that client request traffic may be lost. This can lead to a poor user experience for developers."),(0,r.kt)("p",null,"This tutorial will demonstrate how to operate Pods gracefully in a KusionStack Operating way on Aliyun ACK\nwith SLB as a Service backend provider."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"You can also get the same point from ",(0,r.kt)("a",{parentName:"p",href:"https://www.bilibili.com/video/BV1n8411q7sP/?t=15.7"},"this video"),",\nwhich shows the same case using both KusionStack Kusion and Operating.\nThe sample used in this video can be found from ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/samples/wordpress"},"KusionStack Catalog"),".")),(0,r.kt)("h2",{id:"preparing"},"Preparing"),(0,r.kt)("p",null,"First, ensure that you have an Aliyun ACK Kubernetes cluster set up in order to provision an Aliyun SLB."),(0,r.kt)("p",null,"Next, install KusionStack Operating on this Kubernetes cluster\nfollowing ",(0,r.kt)("a",{parentName:"p",href:"https://kusionstack.io/docs/operating/started/install"},"installation doc"),"."),(0,r.kt)("h2",{id:"get-started"},"Get started"),(0,r.kt)("h3",{id:"create-a-new-namespace"},"Create a new namespace"),(0,r.kt)("p",null,"To begin, create a new namespace for this tutorial:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl create ns operating-tutorial\n")),(0,r.kt)("h3",{id:"provision-pods-and-services"},"Provision Pods and Services"),(0,r.kt)("p",null,"You can create a set of Pods to run up a demo application service\nby creating CollaSet resource using following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: server\n command:\n - /server\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"There should be 3 Pods created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nserver-c5lsr 1/1 Running 0 2m23s\nserver-p6wrx 1/1 Running 0 2m23s\nserver-zn62c 1/1 Running 0 2m23s\n")),(0,r.kt)("p",null,"Then create a Kubernetes Service by running following command,\nwhich will provision Aliyun SLB to expose service."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: v1\nkind: Service\nmetadata:\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n service.beta.kubernetes.io/backend-type: eni\n labels:\n kusionstack.io/control: \"true\" # this label is required\n name: server\nspec:\n ports:\n - port: 80\n protocol: TCP\n targetPort: 8080\n selector:\n app: server\n type: LoadBalancer\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"A service with external IP should be provisioned."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get svc server\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nserver LoadBalancer 192.168.225.55 47.101.49.182 80:30146/TCP 51s\n")),(0,r.kt)("p",null,"The label ",(0,r.kt)("inlineCode",{parentName:"p"},'kusionstack.io/control: "true"')," on Service is very important.\nIt means this service resource will be recognized by ResourceConsist framework, and then participate in PodOpsLifecycle\nto control the Aliyun SLB to switch off traffic before updating each Pod and switch on traffic after it finished,\nin order to protect the service."),(0,r.kt)("h3",{id:"provision-a-client"},"Provision a client"),(0,r.kt)("p",null,"Then we will provision a client to access the service we created before.\nPlease replace ",(0,r.kt)("inlineCode",{parentName:"p"},"")," in the following CollaSet yaml with the external IP from Kubernetes Service created above, and apply again."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: client\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: client\n template:\n metadata:\n labels:\n app: client\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: nginx\n command:\n - /client\n args:\n - -url\n - http:///echo # EXTERNAL_IP should be replaced\n - -m\n - POST\n - d\n - operating-tutorial\n - -qps\n - "10"\n - -worker\n - "10"\n - -timeout\n - "10000"\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"A client Pod should be created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-nc426 1/1 Running 0 30s\nserver-c5lsr 1/1 Running 0 19m\nserver-p6wrx 1/1 Running 0 19m\nserver-zn62c 1/1 Running 0 19m\n")),(0,r.kt)("p",null,"This client will continuously access the service using the configuration provided in the command.\nYou can monitor the response codes from its logs:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial logs -f client-nc426\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\n")),(0,r.kt)("p",null,"The accesses are all successful."),(0,r.kt)("h3",{id:"update-pod-revision"},"Update Pod revision"),(0,r.kt)("p",null,"To trigger a Pod revision update, run the following command\nto edit the container image and command in the PodTemplate of CollaSet:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.2\n name: server\n command:\n - /app/echo\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"It will trigger all Pods updated simultaneously. So the application ",(0,r.kt)("inlineCode",{parentName:"p"},"server")," has no Pod to serve.\nWe can observe the error from client logs."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'worker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:54040->47.101.49.182:80: read: connection reset by peer\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:34438->47.101.49.182:80: read: connection reset by peer\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 another loop, request: 20, failed: 3\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 another loop, request: 20, failed: 3\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n')),(0,r.kt)("h3",{id:"provision-podtransistionrule"},"Provision PodTransistionRule"),(0,r.kt)("p",null,"To avoid this problem, provision a PodTransitionRule with a maxUnavailable 50% rule by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n labels:\n name: server\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n selector:\n matchLabels:\n app: server\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"After updating the CollaSet of the server to trigger an update, you will see the Pods rolling update one by one,\nensuring that at least one Pod is always available to serve."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-rrfbj 1/1 Running 0 25s\nserver-457sn 0/1 Running 0 5s\nserver-bd5sz 0/1 Running 0 5s\nserver-l842s 1/1 Running 0 2m4s\n")),(0,r.kt)("p",null,"You can see from the client logs that no access requests fail during this update."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"worker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\n")),(0,r.kt)("h3",{id:"clean-tutorial-namespace"},"Clean tutorial namespace"),(0,r.kt)("p",null,"At the end of this tutorial, you can clean up the resources by deleting the namespace:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl delete ns operating-tutorial\n")),(0,r.kt)("h2",{id:"comparison-with-the-native-approach"},"Comparison with the Native Approach"),(0,r.kt)("p",null,"Kubernetes provides ",(0,r.kt)("inlineCode",{parentName:"p"},"preStop")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postStart")," hook in each container, by which users can also interact with service outside\nKubernetes like Aliyun SLB service. However, KusionStack Operating offers several advantages:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Pod level vs Container level")),(0,r.kt)("p",null,"Operating offers a Pod level hooks which have more complete information than one container,\nespecially there are several containers in one Pod."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Plugin-able")),(0,r.kt)("p",null,"Through KusionStack Operating, you can decouple operations executed before or after Pods actually change.\nFor example, traffic control can be added or removed without modifying the Pod's preStop configuration."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Rollback option")),(0,r.kt)("p",null,"In case of issues, rollback becomes a viable option when using the Operating approach to update Pods.\nSince Operating does not modify the Pods or their containers during the update,\nif the traffic service experiences problems, there is an opportunity to cancel the update."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/da7786fc.bb98a240.js b/assets/js/da7786fc.bb98a240.js deleted file mode 100644 index 0a16df861bc..00000000000 --- a/assets/js/da7786fc.bb98a240.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3027],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(t),h=r,m=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return t?a.createElement(m,i(i({ref:n},c),{},{components:t})):a.createElement(m,i({ref:n},c))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=t(87462),r=(t(67294),t(3905));const o={},i="Using KusionStack Operating to operate Pods gracefully",l={unversionedId:"operating/started/demo-graceful-operation",id:"version-v0.9/operating/started/demo-graceful-operation",title:"Using KusionStack Operating to operate Pods gracefully",description:"Applications always provide its service along with traffic routing.",source:"@site/versioned_docs/version-v0.9/operating/started/demo-graceful-operation.md",sourceDirName:"operating/started",slug:"/operating/started/demo-graceful-operation",permalink:"/docs/v0.9/operating/started/demo-graceful-operation",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/started/demo-graceful-operation.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",previous:{title:"Installation",permalink:"/docs/v0.9/operating/started/install"},next:{title:"PodOpsLifecycle",permalink:"/docs/v0.9/operating/concepts/podopslifecycle"}},s={},p=[{value:"Preparing",id:"preparing",level:2},{value:"Get started",id:"get-started",level:2},{value:"Create a new namespace",id:"create-a-new-namespace",level:3},{value:"Provision Pods and Services",id:"provision-pods-and-services",level:3},{value:"Provision a client",id:"provision-a-client",level:3},{value:"Update Pod revision",id:"update-pod-revision",level:3},{value:"Provision PodTransistionRule",id:"provision-podtransistionrule",level:3},{value:"Clean tutorial namespace",id:"clean-tutorial-namespace",level:3},{value:"Comparison with the Native Approach",id:"comparison-with-the-native-approach",level:2}],c={toc:p};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-kusionstack-operating-to-operate-pods-gracefully"},"Using KusionStack Operating to operate Pods gracefully"),(0,r.kt)("p",null,"Applications always provide its service along with traffic routing.\nOn Kubernetes, they should be a set of Pods and a corresponding Kubernetes Service resource to expose the service."),(0,r.kt)("p",null,"However, during operations such as updating Pod revisions,\nthere is a risk that client request traffic may be lost. This can lead to a poor user experience for developers."),(0,r.kt)("p",null,"This tutorial will demonstrate how to operate Pods gracefully in a KusionStack Operating way on Aliyun ACK\nwith SLB as a Service backend provider."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"You can also get the same point from ",(0,r.kt)("a",{parentName:"p",href:"https://www.bilibili.com/video/BV1n8411q7sP/?t=15.7"},"this video"),",\nwhich shows the same case using both KusionStack Kusion and Operating.\nThe sample used in this video can be found from ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog/tree/main/models/samples/wordpress"},"KusionStack Catalog"),".")),(0,r.kt)("h2",{id:"preparing"},"Preparing"),(0,r.kt)("p",null,"First, ensure that you have an Aliyun ACK Kubernetes cluster set up in order to provision an Aliyun SLB."),(0,r.kt)("p",null,"Next, install KusionStack Operating on this Kubernetes cluster\nfollowing ",(0,r.kt)("a",{parentName:"p",href:"https://kusionstack.io/docs/operating/started/install"},"installation doc"),"."),(0,r.kt)("h2",{id:"get-started"},"Get started"),(0,r.kt)("h3",{id:"create-a-new-namespace"},"Create a new namespace"),(0,r.kt)("p",null,"To begin, create a new namespace for this tutorial:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl create ns operating-tutorial\n")),(0,r.kt)("h3",{id:"provision-pods-and-services"},"Provision Pods and Services"),(0,r.kt)("p",null,"You can create a set of Pods to run up a demo application service\nby creating CollaSet resource using following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: server\n command:\n - /server\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"There should be 3 Pods created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nserver-c5lsr 1/1 Running 0 2m23s\nserver-p6wrx 1/1 Running 0 2m23s\nserver-zn62c 1/1 Running 0 2m23s\n")),(0,r.kt)("p",null,"Then create a Kubernetes Service by running following command,\nwhich will provision Aliyun SLB to expose service."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: v1\nkind: Service\nmetadata:\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n service.beta.kubernetes.io/backend-type: eni\n labels:\n kusionstack.io/control: \"true\" # this label is required\n name: server\nspec:\n ports:\n - port: 80\n protocol: TCP\n targetPort: 8080\n selector:\n app: server\n type: LoadBalancer\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"A service with external IP should be provisioned."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get svc server\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nserver LoadBalancer 192.168.225.55 47.101.49.182 80:30146/TCP 51s\n")),(0,r.kt)("p",null,"The label ",(0,r.kt)("inlineCode",{parentName:"p"},'kusionstack.io/control: "true"')," on Service is very important.\nIt means this service resource will be recognized by ResourceConsist framework, and then participate in PodOpsLifecycle\nto control the Aliyun SLB to switch off traffic before updating each Pod and switch on traffic after it finished,\nin order to protect the service."),(0,r.kt)("h3",{id:"provision-a-client"},"Provision a client"),(0,r.kt)("p",null,"Then we will provision a client to access the service we created before.\nPlease replace ",(0,r.kt)("inlineCode",{parentName:"p"},"")," in the following CollaSet yaml with the external IP from Kubernetes Service created above, and apply again."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: client\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: client\n template:\n metadata:\n labels:\n app: client\n spec:\n containers:\n - image: wu8685/echo:1.3\n name: nginx\n command:\n - /client\n args:\n - -url\n - http:///echo # EXTERNAL_IP should be replaced\n - -m\n - POST\n - d\n - operating-tutorial\n - -qps\n - "10"\n - -worker\n - "10"\n - -timeout\n - "10000"\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 1Gi\n memory: 100Mi\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"A client Pod should be created."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-nc426 1/1 Running 0 30s\nserver-c5lsr 1/1 Running 0 19m\nserver-p6wrx 1/1 Running 0 19m\nserver-zn62c 1/1 Running 0 19m\n")),(0,r.kt)("p",null,"This client will continuously access the service using the configuration provided in the command.\nYou can monitor the response codes from its logs:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial logs -f client-nc426\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\n")),(0,r.kt)("p",null,"The accesses are all successful."),(0,r.kt)("h3",{id:"update-pod-revision"},"Update Pod revision"),(0,r.kt)("p",null,"To trigger a Pod revision update, run the following command\nto edit the container image and command in the PodTemplate of CollaSet:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'echo \'\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: server\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: server\n template:\n metadata:\n labels:\n app: server\n spec:\n containers:\n - image: wu8685/echo:1.2\n name: server\n command:\n - /app/echo\n resources:\n limits:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n requests:\n cpu: "0.1"\n ephemeral-storage: 100Mi\n memory: 100Mi\n readinessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 3\n\' | kubectl -n operating-tutorial apply -f -\n')),(0,r.kt)("p",null,"It will trigger all Pods updated simultaneously. So the application ",(0,r.kt)("inlineCode",{parentName:"p"},"server")," has no Pod to serve.\nWe can observe the error from client logs."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'worker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:54040->47.101.49.182:80: read: connection reset by peer\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": read tcp 10.244.1.11:34438->47.101.49.182:80: read: connection reset by peer\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-1 another loop, request: 20, failed: 3\nworker-0 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\nworker-0 another loop, request: 20, failed: 3\nworker-1 fails to request POST http://47.101.49.182/echo : Post "http://47.101.49.182/echo": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n')),(0,r.kt)("h3",{id:"provision-podtransistionrule"},"Provision PodTransistionRule"),(0,r.kt)("p",null,"To avoid this problem, provision a PodTransitionRule with a maxUnavailable 50% rule by running the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"echo '\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodTransitionRule\nmetadata:\n labels:\n name: server\nspec:\n rules:\n - availablePolicy:\n maxUnavailableValue: 50%\n name: maxUnavailable\n selector:\n matchLabels:\n app: server\n' | kubectl -n operating-tutorial apply -f -\n")),(0,r.kt)("p",null,"After updating the CollaSet of the server to trigger an update, you will see the Pods rolling update one by one,\nensuring that at least one Pod is always available to serve."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl -n operating-tutorial get pod\nNAME READY STATUS RESTARTS AGE\nclient-rrfbj 1/1 Running 0 25s\nserver-457sn 0/1 Running 0 5s\nserver-bd5sz 0/1 Running 0 5s\nserver-l842s 1/1 Running 0 2m4s\n")),(0,r.kt)("p",null,"You can see from the client logs that no access requests fail during this update."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"worker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-1 another loop, request: 50, failed: 0\nworker-0 another loop, request: 50, failed: 0\n")),(0,r.kt)("h3",{id:"clean-tutorial-namespace"},"Clean tutorial namespace"),(0,r.kt)("p",null,"At the end of this tutorial, you can clean up the resources by deleting the namespace:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl delete ns operating-tutorial\n")),(0,r.kt)("h2",{id:"comparison-with-the-native-approach"},"Comparison with the Native Approach"),(0,r.kt)("p",null,"Kubernetes provides ",(0,r.kt)("inlineCode",{parentName:"p"},"preStop")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"postStart")," hook in each container, by which users can also interact with service outside\nKubernetes like Aliyun SLB service. However, KusionStack Operating offers several advantages:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Pod level vs Container level")),(0,r.kt)("p",null,"Operating offers a Pod level hooks which have more complete information than one container,\nespecially there are several containers in one Pod."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Plugin-able")),(0,r.kt)("p",null,"Through KusionStack Operating, you can decouple operations executed before or after Pods actually change.\nFor example, traffic control can be added or removed without modifying the Pod's preStop configuration."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Rollback option")),(0,r.kt)("p",null,"In case of issues, rollback becomes a viable option when using the Operating approach to update Pods.\nSince Operating does not modify the Pods or their containers during the update,\nif the traffic service experiences problems, there is an opportunity to cancel the update."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/db343463.ef5b8864.js b/assets/js/db343463.3da9b571.js similarity index 55% rename from assets/js/db343463.ef5b8864.js rename to assets/js/db343463.3da9b571.js index b94a9a6f492..5cced9f61d1 100644 --- a/assets/js/db343463.ef5b8864.js +++ b/assets/js/db343463.3da9b571.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8420],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||p[m]||o;return n?r.createElement(k,l(l({ref:t},u),{},{components:n})):r.createElement(k,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="job",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/job",id:"kusion/reference/modules/workspace-configs/workload/job",title:"job",description:"job can be used to define workspace-level job configuration.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/job",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule"},next:{title:"service",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/service"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"job"},"job"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"job")," can be used to define workspace-level job configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8420],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||p[m]||o;return n?r.createElement(k,l(l({ref:t},u),{},{components:n})):r.createElement(k,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="job",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/job",id:"kusion/reference/modules/workspace-configs/workload/job",title:"job",description:"job can be used to define workspace-level job configuration.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/job",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule"},next:{title:"service",permalink:"/docs/next/kusion/reference/modules/workspace-configs/workload/service"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"job"},"job"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"job")," can be used to define workspace-level job configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dbbf606f.62860f23.js b/assets/js/dbbf606f.97b635b4.js similarity index 59% rename from assets/js/dbbf606f.62860f23.js rename to assets/js/dbbf606f.97b635b4.js index 6861aa4b101..86c784afc07 100644 --- a/assets/js/dbbf606f.62860f23.js +++ b/assets/js/dbbf606f.97b635b4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7705],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||i;return n?r.createElement(f,a(a({ref:t},p),{},{components:n})):r.createElement(f,a({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion compile",s={unversionedId:"kusion/reference/commands/kusion-compile",id:"kusion/reference/commands/kusion-compile",title:"kusion compile",description:"Deprecated: Use 'kusion build' to generate the Intent instead",source:"@site/docs/kusion/6-reference/1-commands/kusion-compile.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-compile",permalink:"/docs/next/kusion/reference/commands/kusion-compile",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-compile.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion build",permalink:"/docs/next/kusion/reference/commands/kusion-build"},next:{title:"kusion destroy",permalink:"/docs/next/kusion/reference/commands/kusion-destroy"}},c={},l=[{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-compile"},"kusion compile"),(0,o.kt)("p",null,"Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion compile [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," Deprecated\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for compile\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7705],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||i;return n?r.createElement(f,a(a({ref:t},p),{},{components:n})):r.createElement(f,a({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion compile",s={unversionedId:"kusion/reference/commands/kusion-compile",id:"kusion/reference/commands/kusion-compile",title:"kusion compile",description:"Deprecated: Use 'kusion build' to generate the Intent instead",source:"@site/docs/kusion/6-reference/1-commands/kusion-compile.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-compile",permalink:"/docs/next/kusion/reference/commands/kusion-compile",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/1-commands/kusion-compile.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion build",permalink:"/docs/next/kusion/reference/commands/kusion-build"},next:{title:"kusion destroy",permalink:"/docs/next/kusion/reference/commands/kusion-destroy"}},c={},l=[{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-compile"},"kusion compile"),(0,o.kt)("p",null,"Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion compile [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," Deprecated\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for compile\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/next/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dc405d94.9417abb8.js b/assets/js/dc405d94.9417abb8.js deleted file mode 100644 index 5a0553247f2..00000000000 --- a/assets/js/dc405d94.9417abb8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6305],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=r.createContext({}),s=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=s(e.components);return r.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(t),m=o,h=d["".concat(p,".").concat(m)]||d[m]||u[m]||i;return t?r.createElement(h,a(a({ref:n},c),{},{components:t})):r.createElement(h,a({ref:n},c))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=d;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=t(87462),o=(t(67294),t(3905));const i={},a="Configure Resource Specification",l={unversionedId:"kusion/guides/working-with-k8s/resource-spec",id:"version-v0.9/kusion/guides/working-with-k8s/resource-spec",title:"Configure Resource Specification",description:"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/5-resource-spec.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/resource-spec",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/5-resource-spec.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{},sidebar:"kusion",previous:{title:"Upgrade Image",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade"},next:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/v0.9/kusion/guides/observability/prometheus"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"configure-resource-specification"},"Configure Resource Specification"),(0,o.kt)("p",null,"You can manage container-level resource specification in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,o.kt)("inlineCode",{parentName:"p"},"resources")," field (under the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," schema)."),(0,o.kt)("p",null,"For the full ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,o.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-container"},"here")," for more details."),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Please refer to the ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,o.kt)("p",null,"The example below also requires you to have ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,o.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,o.kt)("h2",{id:"example"},"Example"),(0,o.kt)("p",null,"Update the resources value in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.helloworld: {\n # dev stack has different resource requirements\n # set resources to your want\n # before:\n # resources: {\n # "cpu": "500m"\n # "memory": "512M"\n # }\n # after: \n resources: {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"Everything else in ",(0,o.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,o.kt)("h2",{id:"applying"},"Applying"),(0,o.kt)("p",null,"Re-run steps in ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS UnChanged v1:Service:helloworld:helloworld-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nUpdate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,o.kt)("h2",{id:"validation"},"Validation"),(0,o.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated resources attributes (cpu:250m, memory:256Mi) as defined in the container configuration:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kubectl get deployment -n helloworld -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v4\n ...\n resources:\n limits:\n cpu: 250m\n memory: 256Mi\n...\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dc405d94.9704fa68.js b/assets/js/dc405d94.9704fa68.js new file mode 100644 index 00000000000..25686a289e0 --- /dev/null +++ b/assets/js/dc405d94.9704fa68.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6305],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=r.createContext({}),s=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=s(e.components);return r.createElement(p.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(t),m=o,h=d["".concat(p,".").concat(m)]||d[m]||u[m]||i;return t?r.createElement(h,a(a({ref:n},c),{},{components:t})):r.createElement(h,a({ref:n},c))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=d;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l.mdxType="string"==typeof e?e:o,a[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=t(87462),o=(t(67294),t(3905));const i={},a="Configure Resource Specification",l={unversionedId:"kusion/guides/working-with-k8s/resource-spec",id:"version-v0.9/kusion/guides/working-with-k8s/resource-spec",title:"Configure Resource Specification",description:"You can manage container-level resource specification in the AppConfiguration model via the resources field (under the Container schema).",source:"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/5-resource-spec.md",sourceDirName:"kusion/guides/working-with-k8s",slug:"/kusion/guides/working-with-k8s/resource-spec",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/5-resource-spec.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{},sidebar:"kusion",previous:{title:"Upgrade Image",permalink:"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade"},next:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/v0.9/kusion/guides/observability/prometheus"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"configure-resource-specification"},"Configure Resource Specification"),(0,o.kt)("p",null,"You can manage container-level resource specification in the ",(0,o.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,o.kt)("inlineCode",{parentName:"p"},"resources")," field (under the ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," schema)."),(0,o.kt)("p",null,"For the full ",(0,o.kt)("inlineCode",{parentName:"p"},"Container")," schema reference, please see ",(0,o.kt)("a",{parentName:"p",href:"../../reference/model/catalog_models/workload/doc_service#schema-container"},"here")," for more details."),(0,o.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,o.kt)("p",null,"Please refer to the ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,o.kt)("p",null,"The example below also requires you to have ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,o.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will generate a ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,o.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the project directory."),(0,o.kt)("h2",{id:"example"},"Example"),(0,o.kt)("p",null,"Update the resources value in ",(0,o.kt)("inlineCode",{parentName:"p"},"dev/main.k"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\n\nhelloworld: ac.AppConfiguration {\n workload.containers.helloworld: {\n # dev stack has different resource requirements\n # set resources to your want\n # before:\n # resources: {\n # "cpu": "500m"\n # "memory": "512M"\n # }\n # after: \n resources: {\n "cpu": "250m"\n "memory": "256Mi"\n }\n }\n}\n')),(0,o.kt)("p",null,"Everything else in ",(0,o.kt)("inlineCode",{parentName:"p"},"main.k")," stay the same."),(0,o.kt)("h2",{id:"applying"},"Applying"),(0,o.kt)("p",null,"Re-run steps in ",(0,o.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Spec in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:helloworld UnChanged\n* \u251c\u2500 v1:Service:helloworld:helloworld-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:helloworld:helloworld-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:helloworld, skip \n SUCCESS UnChanged v1:Service:helloworld:helloworld-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:helloworld:helloworld-dev-helloworld success \nUpdate apps/v1:Deployment:helloworld:helloworld-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,o.kt)("h2",{id:"validation"},"Validation"),(0,o.kt)("p",null,"We can verify the application container (in the deployment template) now has the updated resources attributes (cpu:250m, memory:256Mi) as defined in the container configuration:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kubectl get deployment -n helloworld -o yaml\n...\n template:\n ...\n spec:\n containers:\n - env:\n ...\n image: gcr.io/google-samples/gb-frontend:v4\n ...\n resources:\n limits:\n cpu: 250m\n memory: 256Mi\n...\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/de200a2a.97fae5c5.js b/assets/js/de200a2a.97fae5c5.js deleted file mode 100644 index 96283910264..00000000000 --- a/assets/js/de200a2a.97fae5c5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3545],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,g=d["".concat(l,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},u),{},{components:n})):r.createElement(g,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const i={},a="What is KusionStack Operating?",s={unversionedId:"operating/introduction/introduction",id:"version-v0.9/operating/introduction/introduction",title:"What is KusionStack Operating?",description:"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,",source:"@site/versioned_docs/version-v0.9/operating/introduction/introduction.md",sourceDirName:"operating/introduction",slug:"/operating/introduction/",permalink:"/docs/v0.9/operating/introduction/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/introduction/introduction.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",next:{title:"Installation",permalink:"/docs/v0.9/operating/started/install"}},l={},c=[{value:"Key features",id:"key-features",level:2},{value:"Fine-grained operation",id:"fine-grained-operation",level:3},{value:"Advanced workloads",id:"advanced-workloads",level:3},{value:"Streamlined Pod Operation",id:"streamlined-pod-operation",level:3},{value:"Risk management",id:"risk-management",level:3},{value:"Future works",id:"future-works",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"what-is-kusionstack-operating"},"What is KusionStack Operating?"),(0,o.kt)("p",null,"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,\nwith a primary aim of bridging the gap between platform development and Kubernetes."),(0,o.kt)("p",null,"By keeping more operation works finished in Kubernetes layer,\nKusionStack Operating reduces complexity when interacting with Kubernetes\nand enhances convenience for platform developers."),(0,o.kt)("h2",{id:"key-features"},"Key features"),(0,o.kt)("p",null,"KusionStack Operating currently provides the following features,\nstreamlining application operations when developing platforms based on Kubernetes:"),(0,o.kt)("h3",{id:"fine-grained-operation"},"Fine-grained operation"),(0,o.kt)("p",null,"KusionStack Operating introduces PodOpsLifecycle to extend native Pod lifecycle with additional phases such as PreCheck, Preparing, etc.\nAll operators within KusionStack Operating will respect PodOpsLifecycle,\nso that PodOpsLifecycle is able to orchestrate all of these operators to operate each Pod coordinately. "),(0,o.kt)("h3",{id:"advanced-workloads"},"Advanced workloads"),(0,o.kt)("p",null,"KusionStack Operating offers several workloads to ensure it is convenient and effective to delivery and operate application resources."),(0,o.kt)("p",null,"Recently, Operating provides the workload CollaSet.\nBesides the basic ability of scaling and updating Pods like Deployment and StatefulSet of Kubernetes,\nCollaSet also provides a range of scale and update strategies,\nlike in-place update with container image and pod revision consistency."),(0,o.kt)("h3",{id:"streamlined-pod-operation"},"Streamlined Pod Operation"),(0,o.kt)("p",null,"KusionStack Operating introduces resource consist framework that offers a graceful way\nto integrate resource management around Pods, including traffic control, into the PodOpsLifecycle.\nThis simplifies the works for platform developers dealing with Pod operation details.\nKusionStack also integrates some resources by default, such as Aliyun SLB."),(0,o.kt)("h3",{id:"risk-management"},"Risk management"),(0,o.kt)("p",null,"Building upon the PodOpsLifecycle, KusionStack Operating introduces the workload named PodTransitionRule\nwhich will keep risks of pod operation under control.\nBy providing a MaxUnavailable rule similar to Kubernetes' PodDisruptionBudget (PDB),\nit ensures there are always enough Pods available for service.\nFurthermore, it allows for custom rules through extension via webhooks and label hooks."),(0,o.kt)("h2",{id:"future-works"},"Future works"),(0,o.kt)("p",null,"KusionStack Operating project is currently in its early stages.\nOur goal is to simplify platform development. We will continue building in areas such as application operations,\nobservability, and insight. We hope the Operating will make it easier for you to build platforms."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/de200a2a.c7ae3379.js b/assets/js/de200a2a.c7ae3379.js new file mode 100644 index 00000000000..b741d09fdd6 --- /dev/null +++ b/assets/js/de200a2a.c7ae3379.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3545],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(n),f=o,g=d["".concat(l,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},u),{},{components:n})):r.createElement(g,a({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const i={},a="What is KusionStack Operating?",s={unversionedId:"operating/introduction/introduction",id:"version-v0.9/operating/introduction/introduction",title:"What is KusionStack Operating?",description:"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,",source:"@site/versioned_docs/version-v0.9/operating/introduction/introduction.md",sourceDirName:"operating/introduction",slug:"/operating/introduction/",permalink:"/docs/v0.9/operating/introduction/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/introduction/introduction.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"operating",next:{title:"Installation",permalink:"/docs/v0.9/operating/started/install"}},l={},c=[{value:"Key features",id:"key-features",level:2},{value:"Fine-grained operation",id:"fine-grained-operation",level:3},{value:"Advanced workloads",id:"advanced-workloads",level:3},{value:"Streamlined Pod Operation",id:"streamlined-pod-operation",level:3},{value:"Risk management",id:"risk-management",level:3},{value:"Future works",id:"future-works",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"what-is-kusionstack-operating"},"What is KusionStack Operating?"),(0,o.kt)("p",null,"KusionStack Operating consists of workloads and operators built on Kubernetes Custom Resource Definitions,\nwith a primary aim of bridging the gap between platform development and Kubernetes."),(0,o.kt)("p",null,"By keeping more operation works finished in Kubernetes layer,\nKusionStack Operating reduces complexity when interacting with Kubernetes\nand enhances convenience for platform developers."),(0,o.kt)("h2",{id:"key-features"},"Key features"),(0,o.kt)("p",null,"KusionStack Operating currently provides the following features,\nstreamlining application operations when developing platforms based on Kubernetes:"),(0,o.kt)("h3",{id:"fine-grained-operation"},"Fine-grained operation"),(0,o.kt)("p",null,"KusionStack Operating introduces PodOpsLifecycle to extend native Pod lifecycle with additional phases such as PreCheck, Preparing, etc.\nAll operators within KusionStack Operating will respect PodOpsLifecycle,\nso that PodOpsLifecycle is able to orchestrate all of these operators to operate each Pod coordinately. "),(0,o.kt)("h3",{id:"advanced-workloads"},"Advanced workloads"),(0,o.kt)("p",null,"KusionStack Operating offers several workloads to ensure it is convenient and effective to delivery and operate application resources."),(0,o.kt)("p",null,"Recently, Operating provides the workload CollaSet.\nBesides the basic ability of scaling and updating Pods like Deployment and StatefulSet of Kubernetes,\nCollaSet also provides a range of scale and update strategies,\nlike in-place update with container image and pod revision consistency."),(0,o.kt)("h3",{id:"streamlined-pod-operation"},"Streamlined Pod Operation"),(0,o.kt)("p",null,"KusionStack Operating introduces resource consist framework that offers a graceful way\nto integrate resource management around Pods, including traffic control, into the PodOpsLifecycle.\nThis simplifies the works for platform developers dealing with Pod operation details.\nKusionStack also integrates some resources by default, such as Aliyun SLB."),(0,o.kt)("h3",{id:"risk-management"},"Risk management"),(0,o.kt)("p",null,"Building upon the PodOpsLifecycle, KusionStack Operating introduces the workload named PodTransitionRule\nwhich will keep risks of pod operation under control.\nBy providing a MaxUnavailable rule similar to Kubernetes' PodDisruptionBudget (PDB),\nit ensures there are always enough Pods available for service.\nFurthermore, it allows for custom rules through extension via webhooks and label hooks."),(0,o.kt)("h2",{id:"future-works"},"Future works"),(0,o.kt)("p",null,"KusionStack Operating project is currently in its early stages.\nOur goal is to simplify platform development. We will continue building in areas such as application operations,\nobservability, and insight. We hope the Operating will make it easier for you to build platforms."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/de7874bb.85b47aee.js b/assets/js/de7874bb.85b47aee.js deleted file mode 100644 index cdc88bc153c..00000000000 --- a/assets/js/de7874bb.85b47aee.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8026],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),f=i,h=u["".concat(l,".").concat(f)]||u[f]||d[f]||r;return n?o.createElement(h,a(a({ref:t},c),{},{components:n})):o.createElement(h,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var o=n(87462),i=(n(67294),n(3905));const r={id:"app-configuration",sidebar_label:"AppConfiguration"},a="AppConfiguration",s={unversionedId:"kusion/concepts/app-configuration",id:"kusion/concepts/app-configuration",title:"AppConfiguration",description:"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and AppConfiguration model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself.",source:"@site/docs/kusion/3-concepts/5-appconfiguration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/app-configuration",permalink:"/docs/next/kusion/concepts/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/5-appconfiguration.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"app-configuration",sidebar_label:"AppConfiguration"},sidebar:"kusion",previous:{title:"Workspace",permalink:"/docs/next/kusion/concepts/workspace"},next:{title:"Intent",permalink:"/docs/next/kusion/concepts/intent"}},l={},p=[{value:"Workload",id:"workload",level:4},{value:"Accessory",id:"accessory",level:4},{value:"Pipeline",id:"pipeline",level:4},{value:"Topologies",id:"topologies",level:4}],c={toc:p};function d(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"appconfiguration"},"AppConfiguration"),(0,i.kt)("p",null,"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model consolidates workload and their dependent accessories for the application deployment, along with any pipeline and operational requirements into one standardized, infrastructure-independent declarative specification. This declarative specification represents the intuitive user intent for the application, which drives a standardized and efficient application delivery and operation process in a hybrid environment."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"appconfig.png",src:n(57091).Z,width:"2486",height:"1767"})),(0,i.kt)("p",null,"AppConfiguration consists of four core concepts, namely ",(0,i.kt)("inlineCode",{parentName:"p"},"Workload"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessory"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency"),". We will walk through these concepts one by one."),(0,i.kt)("h4",{id:"workload"},"Workload"),(0,i.kt)("p",null,"Workload is a representation of the business logic that runs in the cluster. Common workload types include long-running services that should \u201cnever\u201d go down and batch jobs that take from a few seconds to a few days to complete. A valid AppConfiguration instance must include at least one Workload, which is made of one or more containers, along with their configurations, such as the container image, environment variables, and resource requirements."),(0,i.kt)("p",null,"In most cases, a Workload is a backend service or the frontend of an Application. For example, in a micro-service architecture, each service would be represented by a distinct Workload. This allows developers to manage and deploy their code in a more organized and efficient manner."),(0,i.kt)("h4",{id:"accessory"},"Accessory"),(0,i.kt)("p",null,"Using the analogy of a car, workload is the core engine of application, but only having the engine isn\u2019t enough for the application to function properly. In most cases there must be other supporting parts for the workload to operate as intended. For those supporting parts we call them Accessory. Accessory refers to various runtime capabilities and operational requirements provided by the underlying infrastructure, such as database, network load-balancer, storage and so on."),(0,i.kt)("p",null,"From the perspective of team collaboration, the platform team should be responsible for creating and maintaining various accessory definitions, providing reusable building blocks out-of-the-box. Application developers just need to leverage the existing accessories to cover the evolving application needs. This helps software organizations achieve separation of concern, so that different roles can focus on the subject matter they are an expert of."),(0,i.kt)("h4",{id:"pipeline"},"Pipeline"),(0,i.kt)("p",null,"Running reliable applications requires reliable delivery pipelines. By default, Kusion provides a relatively fixed built-in application delivery pipeline, which should be sufficient for most use cases. However, as the application scale and complexity grows, so does the need for a customizable delivery pipeline. Developers wish for more fine-tuned control and customization over the workflow to delivery their applications. That\u2019s why we introduced the Pipeline section in AppConfiguration model."),(0,i.kt)("p",null,"A customized delivery pipeline is made of several steps, each corresponds to an operation that needs to be executed, such as running certain tests after a deployment, scanning artifacts for vulnerabilities prior to a deployment, and so on. Implementation-wise, the execution of each step should be carried out in the form of a plugin, developed and managed by the platform owners."),(0,i.kt)("h4",{id:"topologies"},"Topologies"),(0,i.kt)("p",null,"Application dependencies refer to the external services or other software that an application relies on in order to function properly. These dependencies may be required in order to provide certain functionality or to use certain features in the application."),(0,i.kt)("p",null,"Similar to declaring a dependency from an application to an accessory, AppConfiguration lets you declare the dependencies between different applications in the same way."))}d.isMDXComponent=!0},57091:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/appconfig-6dd90bd8ff9307dc4e5f9b1553a52b29.png"}}]); \ No newline at end of file diff --git a/assets/js/de7874bb.d96d2922.js b/assets/js/de7874bb.d96d2922.js new file mode 100644 index 00000000000..a693278dedc --- /dev/null +++ b/assets/js/de7874bb.d96d2922.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8026],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),f=i,h=u["".concat(l,".").concat(f)]||u[f]||d[f]||a;return n?o.createElement(h,r(r({ref:t},c),{},{components:n})):o.createElement(h,r({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,r=new Array(a);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var o=n(87462),i=(n(67294),n(3905));const a={id:"app-configuration",sidebar_label:"AppConfiguration"},r="AppConfiguration",s={unversionedId:"kusion/concepts/app-configuration",id:"kusion/concepts/app-configuration",title:"AppConfiguration",description:"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and AppConfiguration model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself.",source:"@site/docs/kusion/3-concepts/5-appconfiguration.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/app-configuration",permalink:"/docs/next/kusion/concepts/app-configuration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/5-appconfiguration.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{id:"app-configuration",sidebar_label:"AppConfiguration"},sidebar:"kusion",previous:{title:"Workspace",permalink:"/docs/next/kusion/concepts/workspace"},next:{title:"Intent",permalink:"/docs/next/kusion/concepts/intent"}},l={},p=[{value:"Workload",id:"workload",level:4},{value:"Accessory",id:"accessory",level:4},{value:"Pipeline",id:"pipeline",level:4},{value:"Topologies",id:"topologies",level:4}],c={toc:p};function d(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"appconfiguration"},"AppConfiguration"),(0,i.kt)("p",null,"As a modern cloud-native application delivery toolchain, declarative intent-based actuation is the central idea of Kusion, and ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model plays the role of describing the intent, which provides a simpler path for on-boarding developers to the platform without leaking low level details in runtime infrastructure and allows developers to fully focus on the application logic itself."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model consolidates workload and their dependent accessories for the application deployment, along with any pipeline and operational requirements into one standardized, infrastructure-independent declarative specification. This declarative specification represents the intuitive user intent for the application, which drives a standardized and efficient application delivery and operation process in a hybrid environment."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"appconfig.png",src:n(57091).Z,width:"2486",height:"1767"})),(0,i.kt)("p",null,"AppConfiguration consists of four core concepts, namely ",(0,i.kt)("inlineCode",{parentName:"p"},"Workload"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessory"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency"),". We will walk through these concepts one by one."),(0,i.kt)("h4",{id:"workload"},"Workload"),(0,i.kt)("p",null,"Workload is a representation of the business logic that runs in the cluster. Common workload types include long-running services that should \u201cnever\u201d go down and batch jobs that take from a few seconds to a few days to complete. A valid AppConfiguration instance must include at least one Workload, which is made of one or more containers, along with their configurations, such as the container image, environment variables, and resource requirements."),(0,i.kt)("p",null,"In most cases, a Workload is a backend service or the frontend of an Application. For example, in a micro-service architecture, each service would be represented by a distinct Workload. This allows developers to manage and deploy their code in a more organized and efficient manner."),(0,i.kt)("h4",{id:"accessory"},"Accessory"),(0,i.kt)("p",null,"Using the analogy of a car, workload is the core engine of application, but only having the engine isn\u2019t enough for the application to function properly. In most cases there must be other supporting parts for the workload to operate as intended. For those supporting parts we call them Accessory. Accessory refers to various runtime capabilities and operational requirements provided by the underlying infrastructure, such as database, network load-balancer, storage and so on."),(0,i.kt)("p",null,"From the perspective of team collaboration, the platform team should be responsible for creating and maintaining various accessory definitions, providing reusable building blocks out-of-the-box. Application developers just need to leverage the existing accessories to cover the evolving application needs. This helps software organizations achieve separation of concern, so that different roles can focus on the subject matter they are an expert of."),(0,i.kt)("h4",{id:"pipeline"},"Pipeline"),(0,i.kt)("p",null,"Running reliable applications requires reliable delivery pipelines. By default, Kusion provides a relatively fixed built-in application delivery pipeline, which should be sufficient for most use cases. However, as the application scale and complexity grows, so does the need for a customizable delivery pipeline. Developers wish for more fine-tuned control and customization over the workflow to delivery their applications. That\u2019s why we introduced the Pipeline section in AppConfiguration model."),(0,i.kt)("p",null,"A customized delivery pipeline is made of several steps, each corresponds to an operation that needs to be executed, such as running certain tests after a deployment, scanning artifacts for vulnerabilities prior to a deployment, and so on. Implementation-wise, the execution of each step should be carried out in the form of a plugin, developed and managed by the platform owners."),(0,i.kt)("h4",{id:"topologies"},"Topologies"),(0,i.kt)("p",null,"Application dependencies refer to the external services or other software that an application relies on in order to function properly. These dependencies may be required in order to provide certain functionality or to use certain features in the application."),(0,i.kt)("p",null,"Similar to declaring a dependency from an application to an accessory, AppConfiguration lets you declare the dependencies between different applications in the same way."))}d.isMDXComponent=!0},57091:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/appconfig-6dd90bd8ff9307dc4e5f9b1553a52b29.png"}}]); \ No newline at end of file diff --git a/assets/js/dfc7c90d.2419115f.js b/assets/js/dfc7c90d.2419115f.js deleted file mode 100644 index 3488a33dd7b..00000000000 --- a/assets/js/dfc7c90d.2419115f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5655],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="job",o={unversionedId:"kusion/reference/modules/catalog-models/workload/job",id:"version-v0.10/kusion/reference/modules/catalog-models/workload/job",title:"job",description:"Schemas",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/job",permalink:"/docs/kusion/reference/modules/catalog-models/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/kusion/reference/modules/catalog-models/trait/opsrule"},next:{title:"service",permalink:"/docs/kusion/reference/modules/catalog-models/workload/service"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Job",id:"schema-job",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"job"},"job"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-job"},"Job"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret"))))),(0,r.kt)("h2",{id:"schema-job"},"Schema Job"),(0,r.kt)("p",null,"Job is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),"is typically used for tasks that take from a few seconds to a few days to complete."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"schedule")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a job with busybox image and runs every hour\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\njob: wl.Job {\n containers: {\n "busybox": c.Container{\n image: "busybox:1.28"\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n schedule: "0 * * * *"\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dfc7c90d.8a7ed7eb.js b/assets/js/dfc7c90d.8a7ed7eb.js new file mode 100644 index 00000000000..ea6d38bc5ed --- /dev/null +++ b/assets/js/dfc7c90d.8a7ed7eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5655],{3905:(t,e,a)=>{a.d(e,{Zo:()=>d,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),s=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},d=function(t){var e=s(t.components);return n.createElement(p.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,d=o(t,["components","mdxType","originalType","parentName"]),u=s(a),c=r,k=u["".concat(p,".").concat(c)]||u[c]||m[c]||l;return a?n.createElement(k,i(i({ref:e},d),{},{components:a})):n.createElement(k,i({ref:e},d))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=u;var o={};for(var p in e)hasOwnProperty.call(e,p)&&(o[p]=e[p]);o.originalType=t,o.mdxType="string"==typeof t?t:r,i[1]=o;for(var s=2;s{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={},i="job",o={unversionedId:"kusion/reference/modules/catalog-models/workload/job",id:"version-v0.10/kusion/reference/modules/catalog-models/workload/job",title:"job",description:"Schemas",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/workload",slug:"/kusion/reference/modules/catalog-models/workload/job",permalink:"/docs/kusion/reference/modules/catalog-models/workload/job",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/kusion/reference/modules/catalog-models/trait/opsrule"},next:{title:"service",permalink:"/docs/kusion/reference/modules/catalog-models/workload/service"}},p={},s=[{value:"Schemas",id:"schemas",level:2},{value:"Schema Job",id:"schema-job",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Base Schema",id:"base-schema",level:3},{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-2",level:3},{value:"Examples",id:"examples-2",level:3},{value:"Schema Probe",id:"schema-probe",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"Examples",id:"examples-3",level:3},{value:"Schema Exec",id:"schema-exec",level:2},{value:"Attributes",id:"attributes-4",level:3},{value:"Examples",id:"examples-4",level:3},{value:"Schema Http",id:"schema-http",level:2},{value:"Attributes",id:"attributes-5",level:3},{value:"Examples",id:"examples-5",level:3},{value:"Schema Tcp",id:"schema-tcp",level:2},{value:"Attributes",id:"attributes-6",level:3},{value:"Examples",id:"examples-6",level:3},{value:"Schema Lifecycle",id:"schema-lifecycle",level:2},{value:"Attributes",id:"attributes-7",level:3},{value:"Examples",id:"examples-7",level:3},{value:"Schema Secret",id:"schema-secret",level:2},{value:"Attributes",id:"attributes-8",level:3},{value:"Examples",id:"examples-8",level:3}],d={toc:s};function m(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"job"},"job"),(0,r.kt)("h2",{id:"schemas"},"Schemas"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-job"},"Job"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-container"},"Container"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-filespec"},"Filespec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-lifecycle"},"LifeCycle")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-probe"},"Probe"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-exec"},"Exec")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-http"},"Http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-tcp"},"Tcp")))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#schema-secret"},"Secret"))))),(0,r.kt)("h2",{id:"schema-job"},"Schema Job"),(0,r.kt)("p",null,"Job is a kind of workload profile that describes how to run your application code. This",(0,r.kt)("br",null),"is typically used for tasks that take from a few seconds to a few days to complete."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"containers"),(0,r.kt)("br",null),"Containers defines the templates of containers to be ran.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers"},"https://kubernetes.io/docs/concepts/containers")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-container"},"container.Container"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"schedule")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"replicas"),(0,r.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"2"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"secrets")),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-secret"},"secret.Secret"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"labels"),(0,r.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"annotations"),(0,r.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'Instantiate a job with busybox image and runs every hour\n\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\n\njob: wl.Job {\n containers: {\n "busybox": c.Container{\n image: "busybox:1.28"\n command: ["/bin/sh", "-c", "echo hello"]\n }\n }\n schedule: "0 * * * *"\n}\n')),(0,r.kt)("h3",{id:"base-schema"},"Base Schema"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"../internal/common#schema-workloadbase"},"WorkloadBase")),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-2"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')),(0,r.kt)("h2",{id:"schema-probe"},"Schema Probe"),(0,r.kt)("p",null,"Probe describes a health check to be performed against a container to determine whether it is",(0,r.kt)("br",null),"alive or ready to receive traffic. There are three probe types: readiness, liveness, and startup."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"probeHandler"),(0,r.kt)("br",null),"The action taken to determine the alive or health of a container"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-tcp"},"probe.Tcp")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"initialDelaySeconds"),(0,r.kt)("br",null),"The number of seconds before health checking is activated.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"timeoutSeconds"),(0,r.kt)("br",null),"The number of seconds after which the probe times out.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle%5C#container-probes"},"https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle\\#container-probes")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"periodSeconds"),(0,r.kt)("br",null),"How often (in seconds) to perform the probe."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"successThreshold"),(0,r.kt)("br",null),"Minimum consecutive successes for the probe to be considered successful after having failed."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"failureThreshold"),(0,r.kt)("br",null),"Minimum consecutive failures for the probe to be considered failed after having succeeded."),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"terminationGracePeriod")),(0,r.kt)("td",{parentName:"tr",align:null},"int"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-3"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nprobe = p.Probe {\n probeHandler: p.Http {\n path: "/healthz"\n }\n initialDelaySeconds: 10\n}\n')),(0,r.kt)("h2",{id:"schema-exec"},"Schema Exec"),(0,r.kt)("p",null,'Exec describes a "run in container" action.'),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"The command line to execute inside the container."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-4"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nexecProbe = p.Exec {\n command: ["probe.sh"]\n}\n')),(0,r.kt)("h2",{id:"schema-http"},"Schema Http"),(0,r.kt)("p",null,"Http describes an action based on HTTP Get requests."),(0,r.kt)("h3",{id:"attributes-5"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to send HTTP requests."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"headers"),(0,r.kt)("br",null),"Collection of custom headers to set in the request"),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-5"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\nhttpProbe = p.Http {\n url: "http://localhost:80"\n headers: {\n "X-HEADER": "VALUE"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-tcp"},"Schema Tcp"),(0,r.kt)("p",null,"Tcp describes an action based on opening a socket."),(0,r.kt)("h3",{id:"attributes-6"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"url"),(0,r.kt)("br",null),"The full qualified url to open a socket."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-6"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\n\ntcpProbe = p.Tcp {\n url: "tcp://localhost:1234"\n}\n')),(0,r.kt)("h2",{id:"schema-lifecycle"},"Schema Lifecycle"),(0,r.kt)("p",null,"Lifecycle describes actions that the management system should take in response",(0,r.kt)("br",null),"to container lifecycle events."),(0,r.kt)("h3",{id:"attributes-7"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"preStop"),(0,r.kt)("br",null),"The action to be taken before a container is terminated due to an API request or",(0,r.kt)("br",null),"management event such as liveness/startup probe failure, preemption, resource contention, etc.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"postStart"),(0,r.kt)("br",null),"The action to be taken after a container is created.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/%5C#container-hooks"},"https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\\#container-hooks")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#schema-exec"},"probe.Exec")," ","|"," ",(0,r.kt)("a",{parentName:"td",href:"#schema-http"},"probe.Http")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-7"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.container.lifecycle as lc\n\nlifecycleHook = lc.Lifecycle {\n preStop: p.Exec {\n command: ["preStop.sh"]\n }\n postStart: p.Http {\n url: "http://localhost:80"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-secret"},"Schema Secret"),(0,r.kt)("p",null,"Secret can be used to store sensitive data."),(0,r.kt)("h3",{id:"attributes-8"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"type"),(0,r.kt)("br",null),"Type of secret, used to facilitate programmatic handling of secret data.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/configuration/secret/%5C#secret-types"},"https://kubernetes.io/docs/concepts/configuration/secret/\\#secret-types")),(0,r.kt)("td",{parentName:"tr",align:null},'"basic" ',"|",' "opaque"'),(0,r.kt)("td",{parentName:"tr",align:null},"opaque"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"data"),(0,r.kt)("br",null),"Data contains the non-binary secret data in string form."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"immutable"),(0,r.kt)("br",null),"Immutable, if set to true, ensures that data stored in the Secret cannot be updated."),(0,r.kt)("td",{parentName:"tr",align:null},"bool"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples-8"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.secret as sec\n\nbasicAuth = sec.Secret {\n type: "basic"\n data: {\n "username": ""\n "password": ""\n }\n}\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e381d75c.bb9d48d2.js b/assets/js/e381d75c.bb9d48d2.js new file mode 100644 index 00000000000..fe5401b0fc6 --- /dev/null +++ b/assets/js/e381d75c.bb9d48d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9747],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=l(a),h=i,m=d["".concat(c,".").concat(h)]||d[h]||u[h]||r;return a?n.createElement(m,s(s({ref:t},p),{},{components:a})):n.createElement(m,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=d;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o.mdxType="string"==typeof e?e:i,s[1]=o;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=a(87462),i=(a(67294),a(3905));const r={},s="Deploy Application Securely and Efficiently via GitHub Actions",o={unversionedId:"kusion/user-guides/github-actions/deploy-application-via-github-actions",id:"version-v0.10/kusion/user-guides/github-actions/deploy-application-via-github-actions",title:"Deploy Application Securely and Efficiently via GitHub Actions",description:"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",sourceDirName:"kusion/5-user-guides/4-github-actions",slug:"/kusion/user-guides/github-actions/deploy-application-via-github-actions",permalink:"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/kusion/user-guides/observability/prometheus"},next:{title:"Using Cloud Secrets Manager",permalink:"/docs/kusion/user-guides/secrets-management/using-cloud-secrets"}},c={},l=[{value:"GitHub Actions Workflow",id:"github-actions-workflow",level:2},{value:"Get Changed Project and Stack",id:"get-changed-project-and-stack",level:2},{value:"Check Project and Stack Structure",id:"check-project-and-stack-structure",level:2},{value:"Test Code Correctness",id:"test-code-correctness",level:2},{value:"Preview Changed Stack",id:"preview-changed-stack",level:2},{value:"Apply Changed Stack",id:"apply-changed-stack",level:2},{value:"Summary",id:"summary",level:2}],p={toc:l};function u(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deploy-application-securely-and-efficiently-via-github-actions"},"Deploy Application Securely and Efficiently via GitHub Actions"),(0,i.kt)("p",null,"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions."),(0,i.kt)("p",null,"Using git repository is a very reliable and common way to manage code, and the same goes for Kusion-managed configuration code. ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," is a CI/CD platform. By customizing ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/using-workflows/about-workflows"},"GitHub Actions workflow"),", the pipeline such as building, testing, and deploying will be executed automatically."),(0,i.kt)("p",null,"Kusion has a commendable integration with GitHub Actions. You can use GitHub Actions to test configuration correctness, preview change, and deploy application. This tutorial demonstrates how to deploy and operate an application through GitHub Actions."),(0,i.kt)("h2",{id:"github-actions-workflow"},"GitHub Actions Workflow"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig"},"KusionStack/konfig")," is the official example repository, and provides the GitHub Actions workflow ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/deploy/deploy.yml"},(0,i.kt)("em",{parentName:"a"},"deploy")),". The workflow is triggered by a push on the main branch, and includes multiple jobs, which ensures the reliability of configuration code, and deploys the changed application."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"workflow",src:a(74559).Z,width:"2594",height:"1364"})),(0,i.kt)("p",null,"The workflow to deploy an application is shown above, which includes the following jobs:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Get changed project and stack"),(0,i.kt)("li",{parentName:"ul"},"Check project and stack structure"),(0,i.kt)("li",{parentName:"ul"},"Test code correctness"),(0,i.kt)("li",{parentName:"ul"},"Preview changed stack"),(0,i.kt)("li",{parentName:"ul"},"Apply changed stack")),(0,i.kt)("p",null,"These jobs ensure the security and efficiency of the application deployment. Next, this tutorial will introduce the usage and function of these jobs. To show how they work more visually, updating port configuration in file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k")," of ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/service-multi-stack"},(0,i.kt)("em",{parentName:"a"},"service-multi-stack")),' (referred to "the example" in the below) is given as an example.'),(0,i.kt)("h2",{id:"get-changed-project-and-stack"},"Get Changed Project and Stack"),(0,i.kt)("p",null,"As Kusion organizes code by project and stack, to deploy the affected applications, analyze the changed project and stack is the first step."),(0,i.kt)("p",null,"The job, ",(0,i.kt)("strong",{parentName:"p"},"get-changed-project-stack")," perfectly accomplish the analysis. The main steps are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Obtain the list of changed files through ",(0,i.kt)("inlineCode",{parentName:"li"},"git diff"),";"),(0,i.kt)("li",{parentName:"ul"},"Based on the changed file list, obtain the changed projects and stacks which are indicated by ",(0,i.kt)("inlineCode",{parentName:"li"},"project.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"stack.yaml")," respectively.")),(0,i.kt)("p",null,"The example changes the file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k"),", where the affected project is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack"),", and the stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". Delightfully, the result, which is shown below, meets our expectation."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"changed-project-stack",src:a(15203).Z,width:"2248",height:"1104"})),(0,i.kt)("h2",{id:"check-project-and-stack-structure"},"Check Project and Stack Structure"),(0,i.kt)("p",null,"The job ",(0,i.kt)("strong",{parentName:"p"},"check-structure")," guarantees the structure legality of the changed project and stack, so that Kusion CLI tools can be used correctly. The check items are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in project.yaml;"),(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in stack.yaml.")),(0,i.kt)("p",null,"The success of structure-check means the correctness of structure. A ",(0,i.kt)("a",{parentName:"p",href:"https://docs.pytest.org/en/7.3.x/"},"pytest")," report ",(0,i.kt)("inlineCode",{parentName:"p"},"check-structure-report")," is also generated, and you can get it from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/managing-workflow-runs/downloading-workflow-artifacts"},"GithHub Actions Artifacts")," ."),(0,i.kt)("p",null,"The example passes the directory structure verification. It is clear from the report that the changed project and stack have get checked, and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n \n\n')),(0,i.kt)("h2",{id:"test-code-correctness"},"Test Code Correctness"),(0,i.kt)("p",null,"Besides a rightful structure, the code must have correct syntax and semantics, and the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," ensures the correctness. ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," get executed on the changed stacks. If succeeded, there are no syntax errors; or the configuration code is illegal, and the following application deployment will fail."),(0,i.kt)("p",null,"In this job, not only the correctness of AppConfiguration is checked, but also the workspace configuration. Hence, you should prepare workspace configuration in advance. Now, the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," supports you put workspace configuration files under directory ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces")," with file name's prefix the same as the workspace name and suffix ",(0,i.kt)("inlineCode",{parentName:"p"},".yaml"),". For example, if you have two workspaces named ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"prod"),", you should provide files ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/dev.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/prod.yaml")," with corresponding workspace configuration."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"The jobs preview and apply also ask for the workspace configuration files."),(0,i.kt)("p",{parentName:"admonition"},"Putting AppConfiguration and workspace configuration in one repository seems not a good idea. Doing this is to give a simple illustration. You can change it in your real production practice, and you can get more information of ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/app-configuration"},"AppConfiguration")," and ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspace")," here.")),(0,i.kt)("p",null,"The report whose name is ",(0,i.kt)("inlineCode",{parentName:"p"},"test-correctness-report")," get generated."),(0,i.kt)("p",null,"The example passes the code correctness test. The report shows that the tested stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n\n')),(0,i.kt)("h2",{id:"preview-changed-stack"},"Preview Changed Stack"),(0,i.kt)("p",null,"After passing the above jobs, security of the configuration change is guaranteed, and it's time to deploy your application. Before applying the change to the real infrastructure, it's necessary to get the expected result of the application deployment. The job ",(0,i.kt)("strong",{parentName:"p"},"preview")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion preview")," to get the expected change result, the result is uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"preview-report"),". If the result meets your requirement, you can go to the next job and deploy the application."),(0,i.kt)("p",null,"The example changes stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". The following picture shows the preview result of ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", where the result is to create a Kubernetes Namespace, Service and Deployment if call ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack Create\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n")),(0,i.kt)("h2",{id:"apply-changed-stack"},"Apply Changed Stack"),(0,i.kt)("p",null,"Finally, the last step is arrived, i.e. deploy application. The job ",(0,i.kt)("strong",{parentName:"p"},"apply")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply")," to apply the configuration change to the real infrastructure. If the job succeeded, the result will be uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"apply-report"),"."),(0,i.kt)("p",null,"For the stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod")," in the example, a Kubernetes Namespace, Service and Deployment get created, which is consistent with the preview result."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack UnChanged\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n\nStart applying diffs ...\n \nSUCCESS: UnChanged v1:Namespace:service-multi-stack, skip \nSUCCESS: Create v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public success \nSUCCESS: Create apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver success\n\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"summary"},"Summary"),(0,i.kt)("p",null,"This tutorial demonstrates how Kusion integrates with GitHub Actions to deploy an application. By structure check, correctness test, preview and apply, Kusion with GitHub Actions enables you deploy application efficiently and securely."))}u.isMDXComponent=!0},15203:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-changed-project-stack-de4c7df77236ad9eeb758f1f9e2af703.png"},74559:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/workflow-052aa326816199187357363891109493.png"}}]); \ No newline at end of file diff --git a/assets/js/e381d75c.ef4bf99a.js b/assets/js/e381d75c.ef4bf99a.js deleted file mode 100644 index a3f25c89349..00000000000 --- a/assets/js/e381d75c.ef4bf99a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9747],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=l(a),h=i,m=d["".concat(c,".").concat(h)]||d[h]||u[h]||r;return a?n.createElement(m,s(s({ref:t},p),{},{components:a})):n.createElement(m,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=d;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o.mdxType="string"==typeof e?e:i,s[1]=o;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=a(87462),i=(a(67294),a(3905));const r={},s="Deploy Application Securely and Efficiently via GitHub Actions",o={unversionedId:"kusion/user-guides/github-actions/deploy-application-via-github-actions",id:"version-v0.10/kusion/user-guides/github-actions/deploy-application-via-github-actions",title:"Deploy Application Securely and Efficiently via GitHub Actions",description:"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",sourceDirName:"kusion/5-user-guides/4-github-actions",slug:"/kusion/user-guides/github-actions/deploy-application-via-github-actions",permalink:"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Monitoring Behavior With Prometheus",permalink:"/docs/kusion/user-guides/observability/prometheus"},next:{title:"Using Cloud Secrets Manager",permalink:"/docs/kusion/user-guides/secrets-management/using-cloud-secrets"}},c={},l=[{value:"GitHub Actions Workflow",id:"github-actions-workflow",level:2},{value:"Get Changed Project and Stack",id:"get-changed-project-and-stack",level:2},{value:"Check Project and Stack Structure",id:"check-project-and-stack-structure",level:2},{value:"Test Code Correctness",id:"test-code-correctness",level:2},{value:"Preview Changed Stack",id:"preview-changed-stack",level:2},{value:"Apply Changed Stack",id:"apply-changed-stack",level:2},{value:"Summary",id:"summary",level:2}],p={toc:l};function u(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deploy-application-securely-and-efficiently-via-github-actions"},"Deploy Application Securely and Efficiently via GitHub Actions"),(0,i.kt)("p",null,"This document provides the instruction to deploy your application securely and efficiently via GitHub Actions."),(0,i.kt)("p",null,"Using git repository is a very reliable and common way to manage code, and the same goes for Kusion-managed configuration code. ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," is a CI/CD platform. By customizing ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/using-workflows/about-workflows"},"GitHub Actions workflow"),", the pipeline such as building, testing, and deploying will be executed automatically."),(0,i.kt)("p",null,"Kusion has a commendable integration with GitHub Actions. You can use GitHub Actions to test configuration correctness, preview change, and deploy application. This tutorial demonstrates how to deploy and operate an application through GitHub Actions."),(0,i.kt)("h2",{id:"github-actions-workflow"},"GitHub Actions Workflow"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig"},"KusionStack/konfig")," is the official example repository, and provides the GitHub Actions workflow ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/blob/main/.github/workflows/deploy/deploy.yml"},(0,i.kt)("em",{parentName:"a"},"deploy")),". The workflow is triggered by a push on the main branch, and includes multiple jobs, which ensures the reliability of configuration code, and deploys the changed application."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"workflow",src:a(74559).Z,width:"2594",height:"1364"})),(0,i.kt)("p",null,"The workflow to deploy an application is shown above, which includes the following jobs:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Get changed project and stack"),(0,i.kt)("li",{parentName:"ul"},"Check project and stack structure"),(0,i.kt)("li",{parentName:"ul"},"Test code correctness"),(0,i.kt)("li",{parentName:"ul"},"Preview changed stack"),(0,i.kt)("li",{parentName:"ul"},"Apply changed stack")),(0,i.kt)("p",null,"These jobs ensure the security and efficiency of the application deployment. Next, this tutorial will introduce the usage and function of these jobs. To show how they work more visually, updating port configuration in file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k")," of ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/konfig/tree/main/example/service-multi-stack"},(0,i.kt)("em",{parentName:"a"},"service-multi-stack")),' (referred to "the example" in the below) is given as an example.'),(0,i.kt)("h2",{id:"get-changed-project-and-stack"},"Get Changed Project and Stack"),(0,i.kt)("p",null,"As Kusion organizes code by project and stack, to deploy the affected applications, analyze the changed project and stack is the first step."),(0,i.kt)("p",null,"The job, ",(0,i.kt)("strong",{parentName:"p"},"get-changed-project-stack")," perfectly accomplish the analysis. The main steps are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Obtain the list of changed files through ",(0,i.kt)("inlineCode",{parentName:"li"},"git diff"),";"),(0,i.kt)("li",{parentName:"ul"},"Based on the changed file list, obtain the changed projects and stacks which are indicated by ",(0,i.kt)("inlineCode",{parentName:"li"},"project.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"stack.yaml")," respectively.")),(0,i.kt)("p",null,"The example changes the file ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/base/base.k"),", where the affected project is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack"),", and the stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". Delightfully, the result, which is shown below, meets our expectation."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"changed-project-stack",src:a(15203).Z,width:"2248",height:"1104"})),(0,i.kt)("h2",{id:"check-project-and-stack-structure"},"Check Project and Stack Structure"),(0,i.kt)("p",null,"The job ",(0,i.kt)("strong",{parentName:"p"},"check-structure")," guarantees the structure legality of the changed project and stack, so that Kusion CLI tools can be used correctly. The check items are as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in project.yaml;"),(0,i.kt)("li",{parentName:"ul"},"The field ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," is required in stack.yaml.")),(0,i.kt)("p",null,"The success of structure-check means the correctness of structure. A ",(0,i.kt)("a",{parentName:"p",href:"https://docs.pytest.org/en/7.3.x/"},"pytest")," report ",(0,i.kt)("inlineCode",{parentName:"p"},"check-structure-report")," is also generated, and you can get it from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/managing-workflow-runs/downloading-workflow-artifacts"},"GithHub Actions Artifacts")," ."),(0,i.kt)("p",null,"The example passes the directory structure verification. It is clear from the report that the changed project and stack have get checked, and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n \n\n')),(0,i.kt)("h2",{id:"test-code-correctness"},"Test Code Correctness"),(0,i.kt)("p",null,"Besides a rightful structure, the code must have correct syntax and semantics, and the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," ensures the correctness. ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion build")," get executed on the changed stacks. If succeeded, there are no syntax errors; or the configuration code is illegal, and the following application deployment will fail."),(0,i.kt)("p",null,"In this job, not only the correctness of AppConfiguration is checked, but also the workspace configuration. Hence, you should prepare workspace configuration in advance. Now, the job ",(0,i.kt)("strong",{parentName:"p"},"test-correctness")," supports you put workspace configuration files under directory ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces")," with file name's prefix the same as the workspace name and suffix ",(0,i.kt)("inlineCode",{parentName:"p"},".yaml"),". For example, if you have two workspaces named ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"prod"),", you should provide files ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/dev.yaml")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"workspaces/prod.yaml")," with corresponding workspace configuration."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"The jobs preview and apply also ask for the workspace configuration files."),(0,i.kt)("p",{parentName:"admonition"},"Putting AppConfiguration and workspace configuration in one repository seems not a good idea. Doing this is to give a simple illustration. You can change it in your real production practice, and you can get more information of ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/app-configuration"},"AppConfiguration")," and ",(0,i.kt)("a",{parentName:"p",href:"../../concepts/workspace"},"workspace")," here.")),(0,i.kt)("p",null,"The report whose name is ",(0,i.kt)("inlineCode",{parentName:"p"},"test-correctness-report")," get generated."),(0,i.kt)("p",null,"The example passes the code correctness test. The report shows that the tested stack is ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", and the result is passed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-xml"},'\n \n \n \n \n\n')),(0,i.kt)("h2",{id:"preview-changed-stack"},"Preview Changed Stack"),(0,i.kt)("p",null,"After passing the above jobs, security of the configuration change is guaranteed, and it's time to deploy your application. Before applying the change to the real infrastructure, it's necessary to get the expected result of the application deployment. The job ",(0,i.kt)("strong",{parentName:"p"},"preview")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion preview")," to get the expected change result, the result is uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"preview-report"),". If the result meets your requirement, you can go to the next job and deploy the application."),(0,i.kt)("p",null,"The example changes stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/dev")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),". The following picture shows the preview result of ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod"),", where the result is to create a Kubernetes Namespace, Service and Deployment if call ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack Create\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n")),(0,i.kt)("h2",{id:"apply-changed-stack"},"Apply Changed Stack"),(0,i.kt)("p",null,"Finally, the last step is arrived, i.e. deploy application. The job ",(0,i.kt)("strong",{parentName:"p"},"apply")," calls ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion apply")," to apply the configuration change to the real infrastructure. If the job succeeded, the result will be uploaded to the artifact ",(0,i.kt)("inlineCode",{parentName:"p"},"apply-report"),"."),(0,i.kt)("p",null,"For the stack ",(0,i.kt)("inlineCode",{parentName:"p"},"example/service-multi-stack/prod")," in the example, a Kubernetes Namespace, Service and Deployment get created, which is consistent with the preview result."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Generating Intent in the Stack prod...\ncloning 'https://github.com/KusionStack/catalog.git' with tag '0.1.2'\n\nStack: prod ID Action\n* \u251c\u2500 v1:Namespace:service-multi-stack UnChanged\n* \u251c\u2500 v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public Create\n* \u2514\u2500 apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver Create\n\nStart applying diffs ...\n \nSUCCESS: UnChanged v1:Namespace:service-multi-stack, skip \nSUCCESS: Create v1:Service:service-multi-stack:service-multi-stack-prod-echoserver-public success \nSUCCESS: Create apps/v1:Deployment:service-multi-stack:service-multi-stack-prod-echoserver success\n\nApply complete! Resources: 2 created, 0 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"summary"},"Summary"),(0,i.kt)("p",null,"This tutorial demonstrates how Kusion integrates with GitHub Actions to deploy an application. By structure check, correctness test, preview and apply, Kusion with GitHub Actions enables you deploy application efficiently and securely."))}u.isMDXComponent=!0},15203:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/kusion-changed-project-stack-de4c7df77236ad9eeb758f1f9e2af703.png"},74559:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/workflow-052aa326816199187357363891109493.png"}}]); \ No newline at end of file diff --git a/assets/js/e4f1eb77.5d5c3e3f.js b/assets/js/e4f1eb77.5d5c3e3f.js deleted file mode 100644 index 99a3a5c5810..00000000000 --- a/assets/js/e4f1eb77.5d5c3e3f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2636],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=l(n),m=i,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(h,o(o({ref:t},c),{},{components:n})):r.createElement(h,o({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=u;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p.mdxType="string"==typeof e?e:i,o[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>l});var r=n(87462),i=(n(67294),n(3905));const a={},o="Expose Service",p={unversionedId:"kusion/user-guides/working-with-k8s/service",id:"kusion/user-guides/working-with-k8s/service",title:"Expose Service",description:"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/3-service.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/service",permalink:"/docs/next/kusion/user-guides/working-with-k8s/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/3-service.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Containers",permalink:"/docs/next/kusion/user-guides/working-with-k8s/container"},next:{title:"Upgrade Image",permalink:"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade"}},s={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function d(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"expose-service"},"Expose Service"),(0,i.kt)("p",null,"You can determine how to expose your service in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). The ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field defines a list of all the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port"),"s you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications."),(0,i.kt)("p",null,"Unless explicitly defined, each of the ports exposed is by default exposed privately as a ",(0,i.kt)("inlineCode",{parentName:"p"},"ClusterIP")," type service. You can expose a port publicly by specifying the ",(0,i.kt)("inlineCode",{parentName:"p"},"exposeInternet")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema. At the moment, the implementation for publicly access is done via Load Balancer type service backed by cloud providers. Ingress will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-port"},"here")," for more details."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the services to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/networking/port"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 8080\n targetPort: 80\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"The code above changes the service port to expose from ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," in the last guide to ",(0,i.kt)("inlineCode",{parentName:"p"},"8080"),", but still targeting the container port ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," because that's what the application is listening on."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new service configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Update\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld UnChanged\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Update v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS UnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip \nUnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the Kubernetes service now has the updated attributes (mapping service port 8080 to container port 80) as defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl get svc -n simple-service -o yaml\n...\n spec:\n ...\n ports:\n - name: simple-service-dev-helloworld-private-8080-tcp\n port: 8080\n protocol: TCP\n targetPort: 80\n...\n")),(0,i.kt)("p",null,"Exposing service port 8080:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:8080\n")),(0,i.kt)("p",null,"Open browser and visit ",(0,i.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),", the application should be up and running\uff1a"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}d.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/e4f1eb77.ee805867.js b/assets/js/e4f1eb77.ee805867.js new file mode 100644 index 00000000000..ddbfcef9c50 --- /dev/null +++ b/assets/js/e4f1eb77.ee805867.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2636],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=l(n),m=i,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(h,o(o({ref:t},c),{},{components:n})):r.createElement(h,o({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=u;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p.mdxType="string"==typeof e?e:i,o[1]=p;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>l});var r=n(87462),i=(n(67294),n(3905));const a={},o="Expose Service",p={unversionedId:"kusion/user-guides/working-with-k8s/service",id:"kusion/user-guides/working-with-k8s/service",title:"Expose Service",description:"You can determine how to expose your service in the AppConfiguration model via the ports field (under the workload schemas). The ports field defines a list of all the Ports you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications.",source:"@site/docs/kusion/5-user-guides/2-working-with-k8s/3-service.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/service",permalink:"/docs/next/kusion/user-guides/working-with-k8s/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/5-user-guides/2-working-with-k8s/3-service.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:3,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Containers",permalink:"/docs/next/kusion/user-guides/working-with-k8s/container"},next:{title:"Upgrade Image",permalink:"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade"}},s={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],c={toc:l};function d(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"expose-service"},"Expose Service"),(0,i.kt)("p",null,"You can determine how to expose your service in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field (under the ",(0,i.kt)("inlineCode",{parentName:"p"},"workload")," schemas). The ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," field defines a list of all the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port"),"s you want to expose for the application (and their corresponding listening ports on the container, if they don't match the service ports), so that it can be consumed by other applications."),(0,i.kt)("p",null,"Unless explicitly defined, each of the ports exposed is by default exposed privately as a ",(0,i.kt)("inlineCode",{parentName:"p"},"ClusterIP")," type service. You can expose a port publicly by specifying the ",(0,i.kt)("inlineCode",{parentName:"p"},"exposeInternet")," field in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema. At the moment, the implementation for publicly access is done via Load Balancer type service backed by cloud providers. Ingress will be supported in a future version of kusion."),(0,i.kt)("p",null,"For the ",(0,i.kt)("inlineCode",{parentName:"p"},"Port")," schema reference, please see ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/catalog-models/workload/service#schema-port"},"here")," for more details."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the services to standardize the behavior of applications in the ",(0,i.kt)("inlineCode",{parentName:"p"},"dev")," workspace, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("p",null,"For a full reference of what can be configured in the workspace level, please see the ",(0,i.kt)("a",{parentName:"p",href:"../../reference/modules/workspace-configs/networking/port"},"workspace reference"),"."),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.container.probe as p\nimport catalog.models.schema.v1.workload.network as n\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n "helloworld": c.Container {\n image: "gcr.io/google-samples/gb-frontend:v4"\n env: {\n "env1": "VALUE"\n "env2": "VALUE2"\n }\n resources: {\n "cpu": "500m"\n "memory": "512M"\n }\n # Configure an HTTP readiness probe\n readinessProbe: p.Probe {\n probeHandler: p.Http {\n url: "http://localhost:80"\n }\n initialDelaySeconds: 10\n }\n }\n }\n replicas: 2\n ports: [\n n.Port {\n port: 8080\n targetPort: 80\n }\n ]\n }\n}\n')),(0,i.kt)("p",null,"The code above changes the service port to expose from ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," in the last guide to ",(0,i.kt)("inlineCode",{parentName:"p"},"8080"),", but still targeting the container port ",(0,i.kt)("inlineCode",{parentName:"p"},"80")," because that's what the application is listening on."),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", new service configuration can be applied."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n \u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private Update\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld UnChanged\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS Update v1:Service:simple-service:simple-service-dev-helloworld-private success \n SUCCESS UnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip \nUnChanged apps/v1:Deployment:simple-service:simple-service-dev-helloworld, skip [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the Kubernetes service now has the updated attributes (mapping service port 8080 to container port 80) as defined in the ",(0,i.kt)("inlineCode",{parentName:"p"},"ports")," configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl get svc -n simple-service -o yaml\n...\n spec:\n ...\n ports:\n - name: simple-service-dev-helloworld-private-8080-tcp\n port: 8080\n protocol: TCP\n targetPort: 80\n...\n")),(0,i.kt)("p",null,"Exposing service port 8080:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"kubectl port-forward svc/simple-service-dev-helloworld-private -n simple-service 30000:8080\n")),(0,i.kt)("p",null,"Open browser and visit ",(0,i.kt)("a",{parentName:"p",href:"http://127.0.0.1:30000"},"http://127.0.0.1:30000"),", the application should be up and running\uff1a"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"app-preview",src:n(92287).Z,width:"1830",height:"330"})))}d.isMDXComponent=!0},92287:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/app-preview-de5274f4267fa725d2a65099e47c6c2c.png"}}]); \ No newline at end of file diff --git a/assets/js/e6798fa1.59bd1f38.js b/assets/js/e6798fa1.59bd1f38.js deleted file mode 100644 index 9d1eb62a5e0..00000000000 --- a/assets/js/e6798fa1.59bd1f38.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1858],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,f=m["".concat(i,".").concat(u)]||m[u]||c[u]||a;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},l="ResourceConsist",s={unversionedId:"operating/manuals/resourceconsist",id:"version-v0.9/operating/manuals/resourceconsist",title:"ResourceConsist",description:"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following",source:"@site/versioned_docs/version-v0.9/operating/manuals/resourceconsist.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/resourceconsist",permalink:"/docs/v0.9/operating/manuals/resourceconsist",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/resourceconsist.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"CollaSet",permalink:"/docs/v0.9/operating/manuals/collaset"},next:{title:"PodTransitionRule",permalink:"/docs/v0.9/operating/manuals/podtransitionrule"}},i={},p=[{value:"Tutorials",id:"tutorials",level:2},{value:"adapters",id:"adapters",level:3},{value:"alibabacloudslb adapter",id:"alibabacloudslb-adapter",level:4},{value:"experimental/adapters",id:"experimentaladapters",level:3},{value:"demo adapter",id:"demo-adapter",level:3}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resourceconsist"},"ResourceConsist"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist/blob/main/README.md"},(0,o.kt)("strong",{parentName:"a"},"ResourceConsist"))," aims to make a customized controller can be realized easily, and offering the ability of following\n",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," for controllers."),(0,o.kt)("h2",{id:"tutorials"},"Tutorials"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"kusionstack.io/resourceconsit")," mainly consists of frame, experimental/adapters and adapters."),(0,o.kt)("p",null,"The frame, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame"),", is used for adapters starting a controller, which handles\nReconcile and Employer/Employees' spec&status. If you wrote an adapter in your own repo, you can import\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/webhook"),",\n]and call AddToMgr to start a controller."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"webhookAdapter is only necessary to be implemented for controllers following PodOpsLifecycle.")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n controllerframe "kusionstack.io/resourceconsist/pkg/frame/controller"\n webhookframe "kusionstack.io/resourceconsist/pkg/frame/webhook"\n)\n\nfunc main() {\n controllerframe.AddToMgr(manager, yourOwnControllerAdapter)\n webhookframe.AddToMgr(manager, yourOwnWebhookAdapter)\n}\n')),(0,o.kt)("h3",{id:"adapters"},"adapters"),(0,o.kt)("p",null,"The adapters, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters"),", consists of built-in adapters. You can start a\ncontroller with built-in adapters just calling AddBuiltinControllerAdaptersToMgr and AddBuiltinWebhookAdaptersToMgr,\npassing built-in adapters' names. Currently, an aliababacloudslb adapter has released. You can use it as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "kusionstack.io/resourceconsist/pkg/adapters"\n)\n\nfunc main() {\n adapters.AddBuiltinControllerAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n adapters.AddBuiltinWebhookAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n}\n')),(0,o.kt)("p",null,"Built-in adapters can also be used like how frame used. You can call NewAdapter from a certain built-in adapter pkg\nand the call frame.AddToMgr to start a controller/webhook"),(0,o.kt)("p",null,"More built-in adapters will be implemented in the future. To make this repo stable, all new built-in adapters will\nbe added to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/pkg/experimental/adapters")," first, and then moved to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/pkg/adapters"),"\nuntil ready to be released."),(0,o.kt)("h4",{id:"alibabacloudslb-adapter"},"alibabacloudslb adapter"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb")," is an adapter that implements ReconcileAdapter. It follows ",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," to\nhandle various scenarios during pod operations, such as creating a new pod, deleting an existing pod, or handling\nchanges to pod configurations. This adapter ensures minimal traffic loss and provides a seamless experience for users\naccessing services load balanced by Alibaba Cloud SLB."),(0,o.kt)("p",null,"In ",(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb"),", the real server is removed from SLB before pod operation in ACK. The LB\nmanagement and real server management are handled by CCM in ACK. Since alibabacloudslb adapter follows PodOpsLifecycle\nand real servers are managed by CCM, ReconcileLifecycleOptions should be implemented. If the cluster is not in ACK or\nCCM is not working in the cluster, the alibabacloudslb controller should implement additional methods of ReconcileAdapter."),(0,o.kt)("h3",{id:"experimentaladapters"},"experimental/adapters"),(0,o.kt)("p",null,"The experimental/adapters is more like a pre-release pkg for built-in adapters. Usage of experimental/adapters is same\nwith built-in adapters, and be aware that ",(0,o.kt)("strong",{parentName:"p"},"DO NOT USE EXPERIMENTAL/ADAPTERS IN PRODUCTION")),(0,o.kt)("h3",{id:"demo-adapter"},"demo adapter"),(0,o.kt)("p",null,"A demo is implemented in ",(0,o.kt)("inlineCode",{parentName:"p"},"resource_controller_suite_test.go"),". In the demo controller, the employer is represented\nas a service and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoServiceStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n }\n}\n')),(0,o.kt)("p",null,"The employee is represented as a pod and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoPodStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n EmployeeStatuses: PodEmployeeStatuses{\n Ip: string,\n Ipv6: string,\n LifecycleReady: bool,\n ExtraStatus: PodExtraStatus{\n TrafficOn: bool,\n TrafficWeight: int,\n },\n }\n}\n")),(0,o.kt)("p",null,"The DemoResourceProviderClient is a fake client that handles backend provider resources related to the employer/employee\n(service/pods). In the Demo Controller, ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"\nare mocked as resources in the backend provider."),(0,o.kt)("p",null,"How the demo controller adapter realized will be introduced in detail as follows,\n",(0,o.kt)("inlineCode",{parentName:"p"},"DemoControllerAdapter")," was defined, including a kubernetes client and a resourceProviderClient. What included in\nthe Adapter struct can be defined as needed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type DemoControllerAdapter struct {\n client.Client\n resourceProviderClient *DemoResourceProviderClient\n}\n")),(0,o.kt)("p",null,"Declaring that the DemoControllerAdapter implemented ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileAdapter")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),".\nImplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"RconcileAdapter")," is a must action, while ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," isn't, check the remarks\nfor ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller/types.go")," to find why."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"var _ ReconcileAdapter = &DemoControllerAdapter{}\nvar _ ReconcileLifecycleOptions = &DemoControllerAdapter{}\n")),(0,o.kt)("p",null,"Following two methods for DemoControllerAdapter inplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),", defines whether\nDemoControllerAdapter following PodOpsLifecycle and need record employees."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"func (r *DemoControllerAdapter) FollowPodOpsLifeCycle() bool {\n return true\n}\n\nfunc (r *DemoControllerAdapter) NeedRecordEmployees() bool {\n return needRecordEmployees\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"IEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"IEmployee")," are interfaces that includes several methods indicating the status employer and\nemployee."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type IEmployer interface {\n GetEmployerId() string\n GetEmployerStatuses() interface{}\n EmployerEqual(employer IEmployer) (bool, error)\n}\n\ntype IEmployee interface {\n GetEmployeeId() string\n GetEmployeeName() string\n GetEmployeeStatuses() interface{}\n EmployeeEqual(employee IEmployee) (bool, error)\n}\n\ntype DemoServiceStatus struct {\n EmployerId string\n EmployerStatuses DemoServiceDetails\n}\n\ntype DemoServiceDetails struct {\n RemoteVIP string\n RemoteVIPQPS int\n}\n\ntype DemoPodStatus struct {\n EmployeeId string\n EmployeeName string\n EmployeeStatuses PodEmployeeStatuses\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," returns all employees' names selected by employer, here is pods' names selected by\nservice. ",(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," is used for ensuring LifecycleFinalizer and ExpectedFinalizer, so you can give\nit an empty return if your adapter doesn't follow PodOpsLifecycle."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) {\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n selected := make([]string, len(podList.Items))\n for idx, pod := range podList.Items {\n selected[idx] = pod.Name\n }\n\n return selected, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployer")," defines what is expected under the spec of employer and what is\ncurrent status, like the load balancer from a cloud provider. Here in the demo adapter, expected is defined by hardcode\nand current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return nil, nil\n }\n var expect []IEmployer\n expect = append(expect, DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n },\n })\n return expect, nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n var current []IEmployer\n\n req := &DemoResourceVipOps{}\n resp, err := r.resourceProviderClient.QueryVip(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource vip query resp is nil")\n }\n\n for _, employerStatus := range resp.VipStatuses {\n current = append(current, employerStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles creation/update/deletion of resources related to employer on\nrelated backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles\n",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n\n toCreateDemoServiceStatus := make([]DemoServiceStatus, len(toCreates))\n for idx, create := range toCreates {\n createDemoServiceStatus, ok := create.(DemoServiceStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreates employer is not DemoServiceStatus")\n }\n toCreateDemoServiceStatus[idx] = createDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.CreateVip(&DemoResourceVipOps{\n VipStatuses: toCreateDemoServiceStatus,\n })\n if err != nil {\n return nil, toCreates, err\n }\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoServiceStatus := make([]DemoServiceStatus, len(toUpdates))\n for idx, update := range toUpdates {\n updateDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdates employer is not DemoServiceStatus")\n }\n toUpdateDemoServiceStatus[idx] = updateDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.UpdateVip(&DemoResourceVipOps{\n VipStatuses: toUpdateDemoServiceStatus,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoServiceStatus := make([]DemoServiceStatus, len(toDeletes))\n for idx, update := range toDeletes {\n deleteDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDeletes employer is not DemoServiceStatus")\n }\n toDeleteDemoServiceStatus[idx] = deleteDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.DeleteVip(&DemoResourceVipOps{\n VipStatuses: toDeleteDemoServiceStatus,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n return toDeletes, nil, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployee"),"and",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployee")," defines what is expected under the spec of employer and employees\nand what is current status, like real servers under the load balancer from a cloud provider. Here in the demo adapter,\nexpected is calculated from pods and current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'// GetExpectEmployeeStatus return expect employee status\nfunc (r *DemoControllerAdapter) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return []IEmployee{}, nil\n }\n\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n expected := make([]IEmployee, len(podList.Items))\n expectIdx := 0\n for _, pod := range podList.Items {\n if !pod.DeletionTimestamp.IsZero() {\n continue\n }\n status := DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n }\n employeeStatuses, err := GetCommonPodEmployeeStatus(&pod)\n if err != nil {\n return nil, err\n }\n extraStatus := PodExtraStatus{}\n if employeeStatuses.LifecycleReady {\n extraStatus.TrafficOn = true\n extraStatus.TrafficWeight = 100\n } else {\n extraStatus.TrafficOn = false\n extraStatus.TrafficWeight = 0\n }\n employeeStatuses.ExtraStatus = extraStatus\n status.EmployeeStatuses = employeeStatuses\n expected[expectIdx] = status\n expectIdx++\n }\n\n return expected[:expectIdx], nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n var current []IEmployee\n req := &DemoResourceRsOps{}\n resp, err := r.resourceProviderClient.QueryRealServer(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource rs query resp is nil")\n }\n\n for _, rsStatus := range resp.RsStatuses {\n current = append(current, rsStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees")," handles creation/update/deletion of resources related to employee\non related backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees"),"\nhandles ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n toCreateDemoPodStatuses := make([]DemoPodStatus, len(toCreates))\n\n for idx, toCreate := range toCreates {\n podStatus, ok := toCreate.(DemoPodStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreate is not DemoPodStatus")\n }\n toCreateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.CreateRealServer(&DemoResourceRsOps{\n RsStatuses: toCreateDemoPodStatuses,\n })\n if err != nil {\n return nil, toCreates, err\n }\n\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoPodStatuses := make([]DemoPodStatus, len(toUpdates))\n\n for idx, toUpdate := range toUpdates {\n podStatus, ok := toUpdate.(DemoPodStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdate is not DemoPodStatus")\n }\n toUpdateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.UpdateRealServer(&DemoResourceRsOps{\n RsStatuses: toUpdateDemoPodStatuses,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoPodStatuses := make([]DemoPodStatus, len(toDeletes))\n\n for idx, toDelete := range toDeletes {\n podStatus, ok := toDelete.(DemoPodStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDelete is not DemoPodStatus")\n }\n toDeleteDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.DeleteRealServer(&DemoResourceRsOps{\n RsStatuses: toDeleteDemoPodStatuses,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n\n return toDeletes, nil, nil\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e6798fa1.86a6cbff.js b/assets/js/e6798fa1.86a6cbff.js new file mode 100644 index 00000000000..acad4831213 --- /dev/null +++ b/assets/js/e6798fa1.86a6cbff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1858],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),m=p(r),u=o,f=m["".concat(i,".").concat(u)]||m[u]||c[u]||a;return r?n.createElement(f,l(l({ref:t},d),{},{components:r})):n.createElement(f,l({ref:t},d))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:o,l[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},l="ResourceConsist",s={unversionedId:"operating/manuals/resourceconsist",id:"version-v0.9/operating/manuals/resourceconsist",title:"ResourceConsist",description:"ResourceConsist aims to make a customized controller can be realized easily, and offering the ability of following",source:"@site/versioned_docs/version-v0.9/operating/manuals/resourceconsist.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/resourceconsist",permalink:"/docs/v0.9/operating/manuals/resourceconsist",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/operating/manuals/resourceconsist.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"operating",previous:{title:"CollaSet",permalink:"/docs/v0.9/operating/manuals/collaset"},next:{title:"PodTransitionRule",permalink:"/docs/v0.9/operating/manuals/podtransitionrule"}},i={},p=[{value:"Tutorials",id:"tutorials",level:2},{value:"adapters",id:"adapters",level:3},{value:"alibabacloudslb adapter",id:"alibabacloudslb-adapter",level:4},{value:"experimental/adapters",id:"experimentaladapters",level:3},{value:"demo adapter",id:"demo-adapter",level:3}],d={toc:p};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"resourceconsist"},"ResourceConsist"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/resourceconsist/blob/main/README.md"},(0,o.kt)("strong",{parentName:"a"},"ResourceConsist"))," aims to make a customized controller can be realized easily, and offering the ability of following\n",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," for controllers."),(0,o.kt)("h2",{id:"tutorials"},"Tutorials"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"kusionstack.io/resourceconsit")," mainly consists of frame, experimental/adapters and adapters."),(0,o.kt)("p",null,"The frame, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame"),", is used for adapters starting a controller, which handles\nReconcile and Employer/Employees' spec&status. If you wrote an adapter in your own repo, you can import\n",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/webhook"),",\n]and call AddToMgr to start a controller."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"webhookAdapter is only necessary to be implemented for controllers following PodOpsLifecycle.")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n controllerframe "kusionstack.io/resourceconsist/pkg/frame/controller"\n webhookframe "kusionstack.io/resourceconsist/pkg/frame/webhook"\n)\n\nfunc main() {\n controllerframe.AddToMgr(manager, yourOwnControllerAdapter)\n webhookframe.AddToMgr(manager, yourOwnWebhookAdapter)\n}\n')),(0,o.kt)("h3",{id:"adapters"},"adapters"),(0,o.kt)("p",null,"The adapters, ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/adapters"),", consists of built-in adapters. You can start a\ncontroller with built-in adapters just calling AddBuiltinControllerAdaptersToMgr and AddBuiltinWebhookAdaptersToMgr,\npassing built-in adapters' names. Currently, an aliababacloudslb adapter has released. You can use it as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'import (\n "kusionstack.io/resourceconsist/pkg/adapters"\n)\n\nfunc main() {\n adapters.AddBuiltinControllerAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n adapters.AddBuiltinWebhookAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb})\n}\n')),(0,o.kt)("p",null,"Built-in adapters can also be used like how frame used. You can call NewAdapter from a certain built-in adapter pkg\nand the call frame.AddToMgr to start a controller/webhook"),(0,o.kt)("p",null,"More built-in adapters will be implemented in the future. To make this repo stable, all new built-in adapters will\nbe added to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/pkg/experimental/adapters")," first, and then moved to ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/pkg/adapters"),"\nuntil ready to be released."),(0,o.kt)("h4",{id:"alibabacloudslb-adapter"},"alibabacloudslb adapter"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb")," is an adapter that implements ReconcileAdapter. It follows ",(0,o.kt)("strong",{parentName:"p"},"PodOpsLifecycle")," to\nhandle various scenarios during pod operations, such as creating a new pod, deleting an existing pod, or handling\nchanges to pod configurations. This adapter ensures minimal traffic loss and provides a seamless experience for users\naccessing services load balanced by Alibaba Cloud SLB."),(0,o.kt)("p",null,"In ",(0,o.kt)("inlineCode",{parentName:"p"},"pkg/adapters/alibabacloudslb"),", the real server is removed from SLB before pod operation in ACK. The LB\nmanagement and real server management are handled by CCM in ACK. Since alibabacloudslb adapter follows PodOpsLifecycle\nand real servers are managed by CCM, ReconcileLifecycleOptions should be implemented. If the cluster is not in ACK or\nCCM is not working in the cluster, the alibabacloudslb controller should implement additional methods of ReconcileAdapter."),(0,o.kt)("h3",{id:"experimentaladapters"},"experimental/adapters"),(0,o.kt)("p",null,"The experimental/adapters is more like a pre-release pkg for built-in adapters. Usage of experimental/adapters is same\nwith built-in adapters, and be aware that ",(0,o.kt)("strong",{parentName:"p"},"DO NOT USE EXPERIMENTAL/ADAPTERS IN PRODUCTION")),(0,o.kt)("h3",{id:"demo-adapter"},"demo adapter"),(0,o.kt)("p",null,"A demo is implemented in ",(0,o.kt)("inlineCode",{parentName:"p"},"resource_controller_suite_test.go"),". In the demo controller, the employer is represented\nas a service and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoServiceStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n }\n}\n')),(0,o.kt)("p",null,"The employee is represented as a pod and is expected to have the following ",(0,o.kt)("strong",{parentName:"p"},"DemoPodStatus"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n EmployeeStatuses: PodEmployeeStatuses{\n Ip: string,\n Ipv6: string,\n LifecycleReady: bool,\n ExtraStatus: PodExtraStatus{\n TrafficOn: bool,\n TrafficWeight: int,\n },\n }\n}\n")),(0,o.kt)("p",null,"The DemoResourceProviderClient is a fake client that handles backend provider resources related to the employer/employee\n(service/pods). In the Demo Controller, ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"\nare mocked as resources in the backend provider."),(0,o.kt)("p",null,"How the demo controller adapter realized will be introduced in detail as follows,\n",(0,o.kt)("inlineCode",{parentName:"p"},"DemoControllerAdapter")," was defined, including a kubernetes client and a resourceProviderClient. What included in\nthe Adapter struct can be defined as needed."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type DemoControllerAdapter struct {\n client.Client\n resourceProviderClient *DemoResourceProviderClient\n}\n")),(0,o.kt)("p",null,"Declaring that the DemoControllerAdapter implemented ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileAdapter")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),".\nImplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"RconcileAdapter")," is a must action, while ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," isn't, check the remarks\nfor ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions")," in ",(0,o.kt)("inlineCode",{parentName:"p"},"kusionstack.io/resourceconsist/pkg/frame/controller/types.go")," to find why."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"var _ ReconcileAdapter = &DemoControllerAdapter{}\nvar _ ReconcileLifecycleOptions = &DemoControllerAdapter{}\n")),(0,o.kt)("p",null,"Following two methods for DemoControllerAdapter inplementing ",(0,o.kt)("inlineCode",{parentName:"p"},"ReconcileLifecycleOptions"),", defines whether\nDemoControllerAdapter following PodOpsLifecycle and need record employees."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"func (r *DemoControllerAdapter) FollowPodOpsLifeCycle() bool {\n return true\n}\n\nfunc (r *DemoControllerAdapter) NeedRecordEmployees() bool {\n return needRecordEmployees\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"IEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"IEmployee")," are interfaces that includes several methods indicating the status employer and\nemployee."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},"type IEmployer interface {\n GetEmployerId() string\n GetEmployerStatuses() interface{}\n EmployerEqual(employer IEmployer) (bool, error)\n}\n\ntype IEmployee interface {\n GetEmployeeId() string\n GetEmployeeName() string\n GetEmployeeStatuses() interface{}\n EmployeeEqual(employee IEmployee) (bool, error)\n}\n\ntype DemoServiceStatus struct {\n EmployerId string\n EmployerStatuses DemoServiceDetails\n}\n\ntype DemoServiceDetails struct {\n RemoteVIP string\n RemoteVIPQPS int\n}\n\ntype DemoPodStatus struct {\n EmployeeId string\n EmployeeName string\n EmployeeStatuses PodEmployeeStatuses\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," returns all employees' names selected by employer, here is pods' names selected by\nservice. ",(0,o.kt)("inlineCode",{parentName:"p"},"GetSelectedEmployeeNames")," is used for ensuring LifecycleFinalizer and ExpectedFinalizer, so you can give\nit an empty return if your adapter doesn't follow PodOpsLifecycle."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) {\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n selected := make([]string, len(podList.Items))\n for idx, pod := range podList.Items {\n selected[idx] = pod.Name\n }\n\n return selected, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployer")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployer")," defines what is expected under the spec of employer and what is\ncurrent status, like the load balancer from a cloud provider. Here in the demo adapter, expected is defined by hardcode\nand current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return nil, nil\n }\n var expect []IEmployer\n expect = append(expect, DemoServiceStatus{\n EmployerId: employer.GetName(),\n EmployerStatuses: DemoServiceDetails{\n RemoteVIP: "demo-remote-VIP",\n RemoteVIPQPS: 100,\n },\n })\n return expect, nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) {\n var current []IEmployer\n\n req := &DemoResourceVipOps{}\n resp, err := r.resourceProviderClient.QueryVip(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource vip query resp is nil")\n }\n\n for _, employerStatus := range resp.VipStatuses {\n current = append(current, employerStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles creation/update/deletion of resources related to employer on\nrelated backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployer/UpdateEmployer/DeleteEmployer")," handles\n",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceVipStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n\n toCreateDemoServiceStatus := make([]DemoServiceStatus, len(toCreates))\n for idx, create := range toCreates {\n createDemoServiceStatus, ok := create.(DemoServiceStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreates employer is not DemoServiceStatus")\n }\n toCreateDemoServiceStatus[idx] = createDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.CreateVip(&DemoResourceVipOps{\n VipStatuses: toCreateDemoServiceStatus,\n })\n if err != nil {\n return nil, toCreates, err\n }\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoServiceStatus := make([]DemoServiceStatus, len(toUpdates))\n for idx, update := range toUpdates {\n updateDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdates employer is not DemoServiceStatus")\n }\n toUpdateDemoServiceStatus[idx] = updateDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.UpdateVip(&DemoResourceVipOps{\n VipStatuses: toUpdateDemoServiceStatus,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoServiceStatus := make([]DemoServiceStatus, len(toDeletes))\n for idx, update := range toDeletes {\n deleteDemoServiceStatus, ok := update.(DemoServiceStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDeletes employer is not DemoServiceStatus")\n }\n toDeleteDemoServiceStatus[idx] = deleteDemoServiceStatus\n }\n\n _, err := r.resourceProviderClient.DeleteVip(&DemoResourceVipOps{\n VipStatuses: toDeleteDemoServiceStatus,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n return toDeletes, nil, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"GetExpectedEmployee"),"and",(0,o.kt)("inlineCode",{parentName:"p"},"GetCurrentEmployee")," defines what is expected under the spec of employer and employees\nand what is current status, like real servers under the load balancer from a cloud provider. Here in the demo adapter,\nexpected is calculated from pods and current is retrieved from a fake resource provider ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'// GetExpectEmployeeStatus return expect employee status\nfunc (r *DemoControllerAdapter) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n if !employer.GetDeletionTimestamp().IsZero() {\n return []IEmployee{}, nil\n }\n\n svc, ok := employer.(*corev1.Service)\n if !ok {\n return nil, fmt.Errorf("expect employer kind is Service")\n }\n selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated()\n\n var podList corev1.PodList\n err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector})\n if err != nil {\n return nil, err\n }\n\n expected := make([]IEmployee, len(podList.Items))\n expectIdx := 0\n for _, pod := range podList.Items {\n if !pod.DeletionTimestamp.IsZero() {\n continue\n }\n status := DemoPodStatus{\n EmployeeId: pod.Name,\n EmployeeName: pod.Name,\n }\n employeeStatuses, err := GetCommonPodEmployeeStatus(&pod)\n if err != nil {\n return nil, err\n }\n extraStatus := PodExtraStatus{}\n if employeeStatuses.LifecycleReady {\n extraStatus.TrafficOn = true\n extraStatus.TrafficWeight = 100\n } else {\n extraStatus.TrafficOn = false\n extraStatus.TrafficWeight = 0\n }\n employeeStatuses.ExtraStatus = extraStatus\n status.EmployeeStatuses = employeeStatuses\n expected[expectIdx] = status\n expectIdx++\n }\n\n return expected[:expectIdx], nil\n}\n\nfunc (r *DemoControllerAdapter) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) {\n var current []IEmployee\n req := &DemoResourceRsOps{}\n resp, err := r.resourceProviderClient.QueryRealServer(req)\n if err != nil {\n return current, err\n }\n if resp == nil {\n return current, fmt.Errorf("demo resource rs query resp is nil")\n }\n\n for _, rsStatus := range resp.RsStatuses {\n current = append(current, rsStatus)\n }\n return current, nil\n}\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees")," handles creation/update/deletion of resources related to employee\non related backend provider. Here in the demo adapter, ",(0,o.kt)("inlineCode",{parentName:"p"},"CreateEmployees/UpdateEmployees/DeleteEmployees"),"\nhandles ",(0,o.kt)("inlineCode",{parentName:"p"},"demoResourceRsStatusInProvider"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-go"},'func (r *DemoControllerAdapter) CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toCreates == nil || len(toCreates) == 0 {\n return toCreates, nil, nil\n }\n toCreateDemoPodStatuses := make([]DemoPodStatus, len(toCreates))\n\n for idx, toCreate := range toCreates {\n podStatus, ok := toCreate.(DemoPodStatus)\n if !ok {\n return nil, toCreates, fmt.Errorf("toCreate is not DemoPodStatus")\n }\n toCreateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.CreateRealServer(&DemoResourceRsOps{\n RsStatuses: toCreateDemoPodStatuses,\n })\n if err != nil {\n return nil, toCreates, err\n }\n\n return toCreates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toUpdates == nil || len(toUpdates) == 0 {\n return toUpdates, nil, nil\n }\n\n toUpdateDemoPodStatuses := make([]DemoPodStatus, len(toUpdates))\n\n for idx, toUpdate := range toUpdates {\n podStatus, ok := toUpdate.(DemoPodStatus)\n if !ok {\n return nil, toUpdates, fmt.Errorf("toUpdate is not DemoPodStatus")\n }\n toUpdateDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.UpdateRealServer(&DemoResourceRsOps{\n RsStatuses: toUpdateDemoPodStatuses,\n })\n if err != nil {\n return nil, toUpdates, err\n }\n\n return toUpdates, nil, nil\n}\n\nfunc (r *DemoControllerAdapter) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) {\n if toDeletes == nil || len(toDeletes) == 0 {\n return toDeletes, nil, nil\n }\n\n toDeleteDemoPodStatuses := make([]DemoPodStatus, len(toDeletes))\n\n for idx, toDelete := range toDeletes {\n podStatus, ok := toDelete.(DemoPodStatus)\n if !ok {\n return nil, toDeletes, fmt.Errorf("toDelete is not DemoPodStatus")\n }\n toDeleteDemoPodStatuses[idx] = podStatus\n }\n\n _, err := r.resourceProviderClient.DeleteRealServer(&DemoResourceRsOps{\n RsStatuses: toDeleteDemoPodStatuses,\n })\n if err != nil {\n return nil, toDeletes, err\n }\n\n return toDeletes, nil, nil\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e695a9f3.b7fd9f41.js b/assets/js/e695a9f3.e9c83c36.js similarity index 59% rename from assets/js/e695a9f3.b7fd9f41.js rename to assets/js/e695a9f3.e9c83c36.js index e2e78a8e3c0..ab399aff353 100644 --- a/assets/js/e695a9f3.b7fd9f41.js +++ b/assets/js/e695a9f3.e9c83c36.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[216],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||i;return n?r.createElement(f,a(a({ref:t},p),{},{components:n})):r.createElement(f,a({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion compile",s={unversionedId:"kusion/reference/commands/kusion-compile",id:"version-v0.10/kusion/reference/commands/kusion-compile",title:"kusion compile",description:"Deprecated: Use 'kusion build' to generate the Intent instead",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-compile.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-compile",permalink:"/docs/kusion/reference/commands/kusion-compile",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-compile.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion build",permalink:"/docs/kusion/reference/commands/kusion-build"},next:{title:"kusion destroy",permalink:"/docs/kusion/reference/commands/kusion-destroy"}},c={},l=[{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-compile"},"kusion compile"),(0,o.kt)("p",null,"Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion compile [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," Deprecated\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for compile\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[216],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(n),d=o,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||i;return n?r.createElement(f,a(a({ref:t},p),{},{components:n})):r.createElement(f,a({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(87462),o=(n(67294),n(3905));const i={},a="kusion compile",s={unversionedId:"kusion/reference/commands/kusion-compile",id:"version-v0.10/kusion/reference/commands/kusion-compile",title:"kusion compile",description:"Deprecated: Use 'kusion build' to generate the Intent instead",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-compile.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-compile",permalink:"/docs/kusion/reference/commands/kusion-compile",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-compile.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion build",permalink:"/docs/kusion/reference/commands/kusion-build"},next:{title:"kusion destroy",permalink:"/docs/kusion/reference/commands/kusion-destroy"}},c={},l=[{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],p={toc:l};function u(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-compile"},"kusion compile"),(0,o.kt)("p",null,"Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion compile [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," Deprecated\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for compile\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/"},"kusion"),"\t - Kusion is the Platform Orchestrator of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e696141c.fc99a527.js b/assets/js/e696141c.07b0088b.js similarity index 56% rename from assets/js/e696141c.fc99a527.js rename to assets/js/e696141c.07b0088b.js index d96187dccbc..28c68aca51a 100644 --- a/assets/js/e696141c.fc99a527.js +++ b/assets/js/e696141c.07b0088b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1421],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),m=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=m(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),c=m(r),d=o,h=c["".concat(s,".").concat(d)]||c[d]||u[d]||a;return r?n.createElement(h,l(l({ref:t},p),{},{components:r})):n.createElement(h,l({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=c;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,l[1]=i;for(var m=2;m{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>m});var n=r(87462),o=(r(67294),r(3905));const a={},l="prometheus",i={unversionedId:"kusion/reference/modules/catalog-models/monitoring/prometheus",id:"kusion/reference/modules/catalog-models/monitoring/prometheus",title:"prometheus",description:"Schema Prometheus",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/monitoring",slug:"/kusion/reference/modules/catalog-models/monitoring/prometheus",permalink:"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"secret",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/"},next:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule"}},s={},m=[{value:"Schema Prometheus",id:"schema-prometheus",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:m};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"prometheus"},"prometheus"),(0,o.kt)("h2",{id:"schema-prometheus"},"Schema Prometheus"),(0,o.kt)("p",null,"Prometheus can be used to define monitoring requirements"),(0,o.kt)("h3",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"path"),(0,o.kt)("br",null),"The path to scrape metrics from."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"/metrics"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"port"),(0,o.kt)("br",null),"The port to scrape metrics from. When using Prometheus operator, this needs to be the port NAME. Otherwise, this can be a port name or a number."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"container ports when scraping pod (monitorType is pod) and service port when scraping service (monitorType is service)"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.monitoring as m\n\nmonitoring: m.Prometheus{\n path: "/metrics"\n port: "web"\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1421],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),m=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=m(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),c=m(r),d=o,h=c["".concat(s,".").concat(d)]||c[d]||u[d]||a;return r?n.createElement(h,l(l({ref:t},p),{},{components:r})):n.createElement(h,l({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=c;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:o,l[1]=i;for(var m=2;m{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>m});var n=r(87462),o=(r(67294),r(3905));const a={},l="prometheus",i={unversionedId:"kusion/reference/modules/catalog-models/monitoring/prometheus",id:"kusion/reference/modules/catalog-models/monitoring/prometheus",title:"prometheus",description:"Schema Prometheus",source:"@site/docs/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/monitoring",slug:"/kusion/reference/modules/catalog-models/monitoring/prometheus",permalink:"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"secret",permalink:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/"},next:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule"}},s={},m=[{value:"Schema Prometheus",id:"schema-prometheus",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:m};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"prometheus"},"prometheus"),(0,o.kt)("h2",{id:"schema-prometheus"},"Schema Prometheus"),(0,o.kt)("p",null,"Prometheus can be used to define monitoring requirements"),(0,o.kt)("h3",{id:"attributes"},"Attributes"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,o.kt)("th",{parentName:"tr",align:null},"Type"),(0,o.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,o.kt)("th",{parentName:"tr",align:null},"Required"))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"path"),(0,o.kt)("br",null),"The path to scrape metrics from."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"/metrics"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"td"},"port"),(0,o.kt)("br",null),"The port to scrape metrics from. When using Prometheus operator, this needs to be the port NAME. Otherwise, this can be a port name or a number."),(0,o.kt)("td",{parentName:"tr",align:null},"str"),(0,o.kt)("td",{parentName:"tr",align:null},"container ports when scraping pod (monitorType is pod) and service port when scraping service (monitorType is service)"),(0,o.kt)("td",{parentName:"tr",align:null},"optional")))),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.monitoring as m\n\nmonitoring: m.Prometheus{\n path: "/metrics"\n port: "web"\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e701010f.a002a4c1.js b/assets/js/e701010f.b698b789.js similarity index 53% rename from assets/js/e701010f.a002a4c1.js rename to assets/js/e701010f.b698b789.js index f396c0d4a1c..0c56d2ca20a 100644 --- a/assets/js/e701010f.a002a4c1.js +++ b/assets/js/e701010f.b698b789.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6531],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},c),{},{components:n})):r.createElement(k,l({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/workspace-configs/networking/port",id:"kusion/reference/modules/workspace-configs/networking/port",title:"port",description:"port can be used to define workspace-level networking configurations.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/networking",slug:"/kusion/reference/modules/workspace-configs/networking/port",permalink:"/docs/next/kusion/reference/modules/workspace-configs/networking/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"monitoring",permalink:"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus"},next:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"port")," can be used to define workspace-level networking configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"The specific cloud vendor that provides load balancer."),(0,a.kt)("td",{parentName:"tr",align:null},'"alicloud" ',"|",' "aws"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"The attached labels of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"The attached annotations of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6531],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},c),{},{components:n})):r.createElement(k,l({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/workspace-configs/networking/port",id:"kusion/reference/modules/workspace-configs/networking/port",title:"port",description:"port can be used to define workspace-level networking configurations.",source:"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/networking",slug:"/kusion/reference/modules/workspace-configs/networking/port",permalink:"/docs/next/kusion/reference/modules/workspace-configs/networking/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"monitoring",permalink:"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus"},next:{title:"opsrule",permalink:"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"port")," can be used to define workspace-level networking configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"The specific cloud vendor that provides load balancer."),(0,a.kt)("td",{parentName:"tr",align:null},'"alicloud" ',"|",' "aws"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"The attached labels of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"The attached annotations of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e7e8cb25.6b10ab5e.js b/assets/js/e7e8cb25.6b10ab5e.js deleted file mode 100644 index 1fc129db707..00000000000 --- a/assets/js/e7e8cb25.6b10ab5e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9089],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>h});var n=o(67294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var l=n.createContext({}),p=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var o=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(o),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||a;return o?n.createElement(m,r(r({ref:t},c),{},{components:o})):n.createElement(m,r({ref:t},c))}));function h(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=o.length,r=new Array(a);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=o(87462),i=(o(67294),o(3905));const a={id:"overview",title:"Overview",slug:"/"},r="Overview",s={unversionedId:"kusion/what-is-kusion/overview",id:"version-v0.10/kusion/what-is-kusion/overview",title:"Overview",description:"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.",source:"@site/versioned_docs/version-v0.10/kusion/1-what-is-kusion/1-overview.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/",permalink:"/docs/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/1-what-is-kusion/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview",title:"Overview",slug:"/"},sidebar:"kusion",next:{title:"Kusion vs Other Software",permalink:"/docs/kusion/what-is-kusion/kusion-vs-x"}},l={},p=[{value:"What is Kusion?",id:"what-is-kusion",level:2},{value:"Why Kusion?",id:"why-kusion",level:2},{value:"Kusion Highlights",id:"kusion-highlights",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"overview"},"Overview"),(0,i.kt)("p",null,"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the ",(0,i.kt)("a",{parentName:"p",href:"kusion/getting-started/install-kusion"},"Getting Started")," section."),(0,i.kt)("h2",{id:"what-is-kusion"},"What is Kusion?"),(0,i.kt)("p",null,"Kusion is a modern application delivery and management toolchain that enables developers to specify desired intent in a declarative way and then using a consistent workflow to drive continuous deployment through application lifecycle. Inspired by the phrase ",(0,i.kt)("strong",{parentName:"p"},"Fusion on Kubernetes"),", Kusion aims to help application and platform developers to develop and deliver in a self-serviceable, fast, reliable, and collaborative way."),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,i.kt)("h2",{id:"why-kusion"},"Why Kusion?"),(0,i.kt)("p",null,"Developers should be able to deploy and run their applications and services end to end. ",(0,i.kt)("strong",{parentName:"p"},'"You build it, you run it", the original promise of DevOps.')),(0,i.kt)("p",null,"But the modern day for most software organizations this promise quickly become unrelalistic since the increasingly complex cloud-native toolchains, while cloud native technologies made huge improvements in areas such as scalability, availability and operability, it also brings downside - the growing burden on developers, which leads to the rise of ",(0,i.kt)("a",{parentName:"p",href:"https://platformengineering.org/"},"Platform Engineering"),"."),(0,i.kt)("p",null,"Another challenge we saw is that a series of ",(0,i.kt)("a",{parentName:"p",href:"https://web.devopstopologies.com/#anti-types"},"antipatterns")," emerge when regular software organizations tries to implement true DevOps. Without well proven reference architecture and supporting tools, it's much more difficult to accomplish the original promise."),(0,i.kt)("p",null,"On one hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion was build to minimize developer's cognitive load"),". With application-centric configuration model, you don't need to deal with tedious infrastructure and configuration management tooling, all you need to be familiar with is ",(0,i.kt)("a",{parentName:"p",href:"kusion/configuration-walkthrough/overview"},"AppConfigation"),". This approach shields developers from the configurational complexity of Kubernetes but still enable standardization by design."),(0,i.kt)("p",null,"On the other hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion defines a new way of how different engineering teams collaboration"),". With the separation of concerns, different roles could focus on their work based on their knowledge and responsibility. Through such a division of labor, the platform team can better manage the differences and complexities of the platform, and app developers could participate in ops work with less cognitive load."),(0,i.kt)("h2",{id:"kusion-highlights"},"Kusion Highlights"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Platform as Code")),(0,i.kt)("p",{parentName:"li"},"Specify desired application intent through declarative configuration code, drive continuous deployment with any CI/CD systems or GitOps to match that intent. No ad-hoc scripts, no hard maintain custom workflows, just declarative configuration code.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Dynamic Configuration Management")),(0,i.kt)("p",{parentName:"li"},"Enable platform teams to set baseline-templates, control how and where to deploy application workloads and provision accessory resources. While still enabling application developers freedom via workload-centric specification and deployment. ")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Security & Compliance Built In")),(0,i.kt)("p",{parentName:"li"},"Enforce security and infrastructure best practices with out-of-box ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"base models"),", create security and compliance guardrails for any Kusion deploy with third-party Policy as Code tools. All accessory resource secrets are automatically injected into Workloads.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Lightweight and Open Model Ecosystem")),(0,i.kt)("p",{parentName:"li"},"Pure client-side solution ensures good portability and the rich APIs make it easier to integrate and automate. Large growing model ecosystem covers all stages in application lifecycle, with extensive connections to various infrastructure capabilities. "))),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"Kusion is an early project.")," The end goal of Kusion is to boost ",(0,i.kt)("a",{parentName:"p",href:"https://internaldeveloperplatform.org/"},"Internal Developer Platform")," revolution, and we are iterating on Kusion quickly to strive towards this goal. For any help or feedback, please contact us in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/community/discussions/categories/meeting"},"Slack")," or ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"issues"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e7e8cb25.8655f88d.js b/assets/js/e7e8cb25.8655f88d.js new file mode 100644 index 00000000000..2e20b533859 --- /dev/null +++ b/assets/js/e7e8cb25.8655f88d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9089],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>h});var n=o(67294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var l=n.createContext({}),p=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var o=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(o),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||a;return o?n.createElement(m,r(r({ref:t},c),{},{components:o})):n.createElement(m,r({ref:t},c))}));function h(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=o.length,r=new Array(a);r[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=o(87462),i=(o(67294),o(3905));const a={id:"overview",title:"Overview",slug:"/"},r="Overview",s={unversionedId:"kusion/what-is-kusion/overview",id:"version-v0.10/kusion/what-is-kusion/overview",title:"Overview",description:"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the Getting Started section.",source:"@site/versioned_docs/version-v0.10/kusion/1-what-is-kusion/1-overview.md",sourceDirName:"kusion/1-what-is-kusion",slug:"/",permalink:"/docs/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/1-what-is-kusion/1-overview.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{id:"overview",title:"Overview",slug:"/"},sidebar:"kusion",next:{title:"Kusion vs Other Software",permalink:"/docs/kusion/what-is-kusion/kusion-vs-x"}},l={},p=[{value:"What is Kusion?",id:"what-is-kusion",level:2},{value:"Why Kusion?",id:"why-kusion",level:2},{value:"Kusion Highlights",id:"kusion-highlights",level:2}],c={toc:p};function u(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"overview"},"Overview"),(0,i.kt)("p",null,"Welcome to Kusion! This introduction section covers what Kusion is, the problem Kusion aims to solve, and how Kusion compares to other software. If you just want to dive into using Kusion, feel free to skip ahead to the ",(0,i.kt)("a",{parentName:"p",href:"kusion/getting-started/install-kusion"},"Getting Started")," section."),(0,i.kt)("h2",{id:"what-is-kusion"},"What is Kusion?"),(0,i.kt)("p",null,"Kusion is a modern application delivery and management toolchain that enables developers to specify desired intent in a declarative way and then using a consistent workflow to drive continuous deployment through application lifecycle. Inspired by the phrase ",(0,i.kt)("strong",{parentName:"p"},"Fusion on Kubernetes"),", Kusion aims to help application and platform developers to develop and deliver in a self-serviceable, fast, reliable, and collaborative way."),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,i.kt)("h2",{id:"why-kusion"},"Why Kusion?"),(0,i.kt)("p",null,"Developers should be able to deploy and run their applications and services end to end. ",(0,i.kt)("strong",{parentName:"p"},'"You build it, you run it", the original promise of DevOps.')),(0,i.kt)("p",null,"But the modern day for most software organizations this promise quickly become unrelalistic since the increasingly complex cloud-native toolchains, while cloud native technologies made huge improvements in areas such as scalability, availability and operability, it also brings downside - the growing burden on developers, which leads to the rise of ",(0,i.kt)("a",{parentName:"p",href:"https://platformengineering.org/"},"Platform Engineering"),"."),(0,i.kt)("p",null,"Another challenge we saw is that a series of ",(0,i.kt)("a",{parentName:"p",href:"https://web.devopstopologies.com/#anti-types"},"antipatterns")," emerge when regular software organizations tries to implement true DevOps. Without well proven reference architecture and supporting tools, it's much more difficult to accomplish the original promise."),(0,i.kt)("p",null,"On one hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion was build to minimize developer's cognitive load"),". With application-centric configuration model, you don't need to deal with tedious infrastructure and configuration management tooling, all you need to be familiar with is ",(0,i.kt)("a",{parentName:"p",href:"kusion/configuration-walkthrough/overview"},"AppConfigation"),". This approach shields developers from the configurational complexity of Kubernetes but still enable standardization by design."),(0,i.kt)("p",null,"On the other hand, ",(0,i.kt)("strong",{parentName:"p"},"Kusion defines a new way of how different engineering teams collaboration"),". With the separation of concerns, different roles could focus on their work based on their knowledge and responsibility. Through such a division of labor, the platform team can better manage the differences and complexities of the platform, and app developers could participate in ops work with less cognitive load."),(0,i.kt)("h2",{id:"kusion-highlights"},"Kusion Highlights"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Platform as Code")),(0,i.kt)("p",{parentName:"li"},"Specify desired application intent through declarative configuration code, drive continuous deployment with any CI/CD systems or GitOps to match that intent. No ad-hoc scripts, no hard maintain custom workflows, just declarative configuration code.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Dynamic Configuration Management")),(0,i.kt)("p",{parentName:"li"},"Enable platform teams to set baseline-templates, control how and where to deploy application workloads and provision accessory resources. While still enabling application developers freedom via workload-centric specification and deployment. ")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Security & Compliance Built In")),(0,i.kt)("p",{parentName:"li"},"Enforce security and infrastructure best practices with out-of-box ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"base models"),", create security and compliance guardrails for any Kusion deploy with third-party Policy as Code tools. All accessory resource secrets are automatically injected into Workloads.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"Lightweight and Open Model Ecosystem")),(0,i.kt)("p",{parentName:"li"},"Pure client-side solution ensures good portability and the rich APIs make it easier to integrate and automate. Large growing model ecosystem covers all stages in application lifecycle, with extensive connections to various infrastructure capabilities. "))),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("strong",{parentName:"p"},"Kusion is an early project.")," The end goal of Kusion is to boost ",(0,i.kt)("a",{parentName:"p",href:"https://internaldeveloperplatform.org/"},"Internal Developer Platform")," revolution, and we are iterating on Kusion quickly to strive towards this goal. For any help or feedback, please contact us in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/community/discussions/categories/meeting"},"Slack")," or ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/issues"},"issues"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e8149155.9a5b1f0c.js b/assets/js/e8149155.9a5b1f0c.js deleted file mode 100644 index 1e2a9c0d194..00000000000 --- a/assets/js/e8149155.9a5b1f0c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2839],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>g});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),s=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(t),g=r,k=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return t?o.createElement(k,i(i({ref:n},c),{},{components:t})):o.createElement(k,i({ref:n},c))}));function g(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,i=new Array(a);i[0]=d;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,i[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var o=t(87462),r=(t(67294),t(3905));const a={sidebar_position:5},i="Application Networking",p={unversionedId:"kusion/config-walkthrough/networking",id:"version-v0.9/kusion/config-walkthrough/networking",title:"Application Networking",description:"In addition to configuring application's container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/networking.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/networking",permalink:"/docs/v0.9/kusion/config-walkthrough/networking",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/networking.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"kusion",previous:{title:"Workload",permalink:"/docs/v0.9/kusion/config-walkthrough/workload"},next:{title:"Managed Databases",permalink:"/docs/v0.9/kusion/config-walkthrough/database"}},l={},s=[{value:"Import",id:"import",level:2},{value:"Private vs Public Access",id:"private-vs-public-access",level:2},{value:"Mapping ports",id:"mapping-ports",level:2},{value:"Exposing multiple ports",id:"exposing-multiple-ports",level:2},{value:"Choosing protocol",id:"choosing-protocol",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-networking"},"Application Networking"),(0,r.kt)("p",null,"In addition to configuring application's ",(0,r.kt)("a",{parentName:"p",href:"workload#configure-containers"},"container specifications"),", you can also configure its networking behaviors, including how to expose the application and how it can be accessed."),(0,r.kt)("p",null,"In future versions, this will also include ingress-based routing strategy and DNS configurations."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n")),(0,r.kt)("h2",{id:"private-vs-public-access"},"Private vs Public Access"),(0,r.kt)("p",null,"Private network access means the service can only be access from within the target cluster."),(0,r.kt)("p",null,"Public access is implemented using public load balancers on the cloud as of v0.9.0. This generally requires a Kubernetes cluster that is running on the cloud with a vendor-specific service controller."),(0,r.kt)("p",null,"Any ports defined default to private access unless explicitly specified."),(0,r.kt)("p",null,"To expose port 80 to be accessed privately:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n")),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly on AWS using an AWS Load Balancer:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n type: "aws"\n port: 80\n public: True\n }\n ]\n }\n}\n')),(0,r.kt)("h2",{id:"mapping-ports"},"Mapping ports"),(0,r.kt)("p",null,"To expose a port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," that maps to a different port ",(0,r.kt)("inlineCode",{parentName:"p"},"8088")," on the container:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n }\n ]\n }\n}\n")),(0,r.kt)("h2",{id:"exposing-multiple-ports"},"Exposing multiple ports"),(0,r.kt)("p",null,"You can also expose multiple ports and configure them separately. "),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly on an AliCloud load balancer, and port 9099 for private access (to be scraped by Prometheus, for example):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n public: True\n }\n n.Port {\n port: 9099\n }\n ]\n }\n}\n')),(0,r.kt)("h2",{id:"choosing-protocol"},"Choosing protocol"),(0,r.kt)("p",null,"To expose a port using the ",(0,r.kt)("inlineCode",{parentName:"p"},"UDP")," protocol:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n protocol: "UDP"\n }\n ]\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e8149155.d98e2fe2.js b/assets/js/e8149155.d98e2fe2.js new file mode 100644 index 00000000000..d8ae1672771 --- /dev/null +++ b/assets/js/e8149155.d98e2fe2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2839],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>g});var o=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),s=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(t),g=r,k=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return t?o.createElement(k,i(i({ref:n},c),{},{components:t})):o.createElement(k,i({ref:n},c))}));function g(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,i=new Array(a);i[0]=d;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p.mdxType="string"==typeof e?e:r,i[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var o=t(87462),r=(t(67294),t(3905));const a={sidebar_position:5},i="Application Networking",p={unversionedId:"kusion/config-walkthrough/networking",id:"version-v0.9/kusion/config-walkthrough/networking",title:"Application Networking",description:"In addition to configuring application's container specifications, you can also configure its networking behaviors, including how to expose the application and how it can be accessed.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/networking.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/networking",permalink:"/docs/v0.9/kusion/config-walkthrough/networking",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/networking.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"kusion",previous:{title:"Workload",permalink:"/docs/v0.9/kusion/config-walkthrough/workload"},next:{title:"Managed Databases",permalink:"/docs/v0.9/kusion/config-walkthrough/database"}},l={},s=[{value:"Import",id:"import",level:2},{value:"Private vs Public Access",id:"private-vs-public-access",level:2},{value:"Mapping ports",id:"mapping-ports",level:2},{value:"Exposing multiple ports",id:"exposing-multiple-ports",level:2},{value:"Choosing protocol",id:"choosing-protocol",level:2}],c={toc:s};function u(e){let{components:n,...t}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"application-networking"},"Application Networking"),(0,r.kt)("p",null,"In addition to configuring application's ",(0,r.kt)("a",{parentName:"p",href:"workload#configure-containers"},"container specifications"),", you can also configure its networking behaviors, including how to expose the application and how it can be accessed."),(0,r.kt)("p",null,"In future versions, this will also include ingress-based routing strategy and DNS configurations."),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.network as n\n")),(0,r.kt)("h2",{id:"private-vs-public-access"},"Private vs Public Access"),(0,r.kt)("p",null,"Private network access means the service can only be access from within the target cluster."),(0,r.kt)("p",null,"Public access is implemented using public load balancers on the cloud as of v0.9.0. This generally requires a Kubernetes cluster that is running on the cloud with a vendor-specific service controller."),(0,r.kt)("p",null,"Any ports defined default to private access unless explicitly specified."),(0,r.kt)("p",null,"To expose port 80 to be accessed privately:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n }\n ]\n }\n}\n")),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly on AWS using an AWS Load Balancer:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n type: "aws"\n port: 80\n public: True\n }\n ]\n }\n}\n')),(0,r.kt)("h2",{id:"mapping-ports"},"Mapping ports"),(0,r.kt)("p",null,"To expose a port ",(0,r.kt)("inlineCode",{parentName:"p"},"80")," that maps to a different port ",(0,r.kt)("inlineCode",{parentName:"p"},"8088")," on the container:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n }\n ]\n }\n}\n")),(0,r.kt)("h2",{id:"exposing-multiple-ports"},"Exposing multiple ports"),(0,r.kt)("p",null,"You can also expose multiple ports and configure them separately. "),(0,r.kt)("p",null,"To expose port 80 to be accessed publicly on an AliCloud load balancer, and port 9099 for private access (to be scraped by Prometheus, for example):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n type: "aliyun"\n port: 80\n public: True\n }\n n.Port {\n port: 9099\n }\n ]\n }\n}\n')),(0,r.kt)("h2",{id:"choosing-protocol"},"Choosing protocol"),(0,r.kt)("p",null,"To expose a port using the ",(0,r.kt)("inlineCode",{parentName:"p"},"UDP")," protocol:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n ports: [\n n.Port {\n port: 80\n targetPort: 8088\n protocol: "UDP"\n }\n ]\n }\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e877f19f.79dc2d14.js b/assets/js/e877f19f.e3eeb47f.js similarity index 63% rename from assets/js/e877f19f.79dc2d14.js rename to assets/js/e877f19f.e3eeb47f.js index 3fb22bd242b..2a0afa5d051 100644 --- a/assets/js/e877f19f.79dc2d14.js +++ b/assets/js/e877f19f.e3eeb47f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4605],{3905:(e,n,r)=>{r.d(n,{Zo:()=>l,kt:()=>k});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=t.createContext({}),c=function(e){var n=t.useContext(u),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},l=function(e){var n=c(e.components);return t.createElement(u.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},f=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),f=c(r),k=o,d=f["".concat(u,".").concat(k)]||f[k]||p[k]||i;return r?t.createElement(d,s(s({ref:n},l),{},{components:r})):t.createElement(d,s({ref:n},l))}));function k(e,n){var r=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=f;var a={};for(var u in n)hasOwnProperty.call(n,u)&&(a[u]=n[u]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=r(87462),o=(r(67294),r(3905));const i={},s="kusion version",a={unversionedId:"kusion/reference/cli/kusion/kusion_version",id:"version-v0.9/kusion/reference/cli/kusion/kusion_version",title:"kusion version",description:"Print the Kusion version information for the current context",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_version.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_version",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_version.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion preview",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview"},next:{title:"Backend Configuration",permalink:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration"}},u={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],l={toc:c};function p(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,t.Z)({},l,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-version"},"kusion version"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion version [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Print the Kusion version\n kusion version\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for version\n -o, --output string Output format. Only json format is supported for now\n")),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4605],{3905:(e,n,r)=>{r.d(n,{Zo:()=>l,kt:()=>k});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=t.createContext({}),c=function(e){var n=t.useContext(u),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},l=function(e){var n=c(e.components);return t.createElement(u.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},f=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),f=c(r),k=o,d=f["".concat(u,".").concat(k)]||f[k]||p[k]||i;return r?t.createElement(d,s(s({ref:n},l),{},{components:r})):t.createElement(d,s({ref:n},l))}));function k(e,n){var r=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=f;var a={};for(var u in n)hasOwnProperty.call(n,u)&&(a[u]=n[u]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=r(87462),o=(r(67294),r(3905));const i={},s="kusion version",a={unversionedId:"kusion/reference/cli/kusion/kusion_version",id:"version-v0.9/kusion/reference/cli/kusion/kusion_version",title:"kusion version",description:"Print the Kusion version information for the current context",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_version.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_version",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_version.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion preview",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview"},next:{title:"Backend Configuration",permalink:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration"}},u={},c=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],l={toc:c};function p(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,t.Z)({},l,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-version"},"kusion version"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"Print the Kusion version information for the current context"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion version [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Print the Kusion version\n kusion version\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for version\n -o, --output string Output format. Only json format is supported for now\n")),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e89e36c0.5babc632.js b/assets/js/e89e36c0.5babc632.js new file mode 100644 index 00000000000..79e763df2bd --- /dev/null +++ b/assets/js/e89e36c0.5babc632.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7816],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>u});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function l(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var p=t.createContext({}),s=function(e){var n=t.useContext(p),a=n;return e&&(a="function"==typeof e?e(n):l(l({},n),e)),a},d=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},m=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),m=s(a),u=o,f=m["".concat(p,".").concat(u)]||m[u]||c[u]||i;return a?t.createElement(f,l(l({ref:n},d),{},{components:a})):t.createElement(f,l({ref:n},d))}));function u(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=a.length,l=new Array(i);l[0]=m;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r.mdxType="string"==typeof e?e:o,l[1]=r;for(var s=2;s{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>i,metadata:()=>r,toc:()=>s});var t=a(87462),o=(a(67294),a(3905));const i={sidebar_position:4},l="PodDecoration",r={unversionedId:"operating/manuals/poddecoration",id:"version-v0.10/operating/manuals/poddecoration",title:"PodDecoration",description:"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.",source:"@site/versioned_docs/version-v0.10/operating/manuals/poddecoration.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/poddecoration",permalink:"/docs/operating/manuals/poddecoration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/poddecoration.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"operating",previous:{title:"PodTransitionRule",permalink:"/docs/operating/manuals/podtransitionrule"}},p={},s=[{value:"Create CollaSet",id:"create-collaset",level:2},{value:"Create PodDecoration",id:"create-poddecoration",level:2},{value:"Update PodDecoration",id:"update-poddecoration",level:2},{value:"Rolling update v1",id:"rolling-update-v1",level:3},{value:"Rolling update v1 -> v2",id:"rolling-update-v1---v2",level:3},{value:"Injection",id:"injection",level:2},{value:"Metadata",id:"metadata",level:3},{value:"Primary Container",id:"primary-container",level:3},{value:"Sidecar Container",id:"sidecar-container",level:3},{value:"InitContainer",id:"initcontainer",level:3},{value:"Upgrade strategy",id:"upgrade-strategy",level:2}],d={toc:s};function c(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"poddecoration"},"PodDecoration"),(0,o.kt)("p",null,"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria. "),(0,o.kt)("p",null,"PodDecoration not only allows injecting sidecar containers to Pods but also enables modifying existing container configurations, metadata, and scheduling parameters etc.\nThe PodDecoration controller does not control the upgrade of Pods. The actual upgrade process is fully controlled by the CollaSet controller. This means that the injection upgrade of PodDecoration can also be performed ",(0,o.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible"),"."),(0,o.kt)("p",null,"About ",(0,o.kt)("a",{parentName:"p",href:"/docs/operating/manuals/collaset"},"CollaSet"),"."),(0,o.kt)("h1",{id:"example"},"Example"),(0,o.kt)("h2",{id:"create-collaset"},"Create CollaSet"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# collaset.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: foo\n namespace: default\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: foo\n")),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"collaset.yaml")," to create three pods under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," management."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f collaset.yaml\ncollaset.apps.kusionstack.io/foo created\n\n$ kubectl get cls\nNAME DESIRED CURRENT AVAILABLE UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\nfoo 3 3 3 3 3 3 foo-7bdb974bc7 foo-7bdb974bc7 7s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2wnnf 1/1 Running 0 41s\nfoo-hqpx7 1/1 Running 0 41s\nfoo-mqt48 1/1 Running 0 41s\n")),(0,o.kt)("h2",{id:"create-poddecoration"},"Create PodDecoration"),(0,o.kt)("p",null,"The following ",(0,o.kt)("inlineCode",{parentName:"p"},"poddecoration.yaml")," file describes a PodDecoration, which selects the pod under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," and injects the content in ",(0,o.kt)("inlineCode",{parentName:"p"},"template")," into the pod with ",(0,o.kt)("inlineCode",{parentName:"p"},"instance-id=0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nmetadata:\n name: sample-pd\nspec:\n selector: # selected pod range in which PodDecoration takes effect\n matchLabels:\n app: foo\n updateStrategy:\n rollingUpdate:\n selector: # select pod to upgrade in effect range\n matchLabels:\n collaset.kusionstack.io/instance-id: "0"\n template:\n metadata:\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v1"\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n command: ["sleep", "2h"]\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n')),(0,o.kt)("p",null,"Create PodDecoration ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to upgrade selected pod "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f poddecoration.yaml\npoddecoration.apps.kusionstack.io/sample-pd created\n")),(0,o.kt)("p",null,"The status of PodDecoration is updated, and one pod is injected with sidecar through recreate."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 1 1 1 sample-pd-9465f4c84 20s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 15s\nfoo-2wnnf 1/1 Running 0 2m\nfoo-hqpx7 1/1 Running 0 2m\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-2wnnf\n escaped: true\n - name: foo-hqpx7\n escaped: true\n matchedPods: 3\n injectedPods: 1\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h2",{id:"update-poddecoration"},"Update PodDecoration"),(0,o.kt)("h3",{id:"rolling-update-v1"},"Rolling update v1"),(0,o.kt)("p",null,"Edit ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to expand the upgrade scope."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Edit updateStrategy to select instance-id in [0, 1, 2]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector: \n matchExpressions:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n - "1" \n - "2" \n template:\n ...\n')),(0,o.kt)("p",null,"All pods updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 3 3 sample-pd-9465f4c84 sample-pd-9465f4c84 3m\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 3m\nfoo-lftw8 2/2 Running 0 8s\nfoo-n57rr 2/2 Running 0 8s\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n currentRevision: sample-pd-9465f4c84\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 3\n updatedReadyPods: 3\n updatedAvailablePods: 3\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h3",{id:"rolling-update-v1---v2"},"Rolling update v1 -> v2"),(0,o.kt)("p",null,"Update ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd"),"'s sidecar container image and ",(0,o.kt)("inlineCode",{parentName:"p"},"updateStrategy"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Update sidecar-a\'s image with ubuntu:22.10\n# Edit updateStrategy to select instance-id in [0]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n template:\n ...\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.10\n ...\n')),(0,o.kt)("p",null,"Pod ",(0,o.kt)("inlineCode",{parentName:"p"},"foo-2gnnl")," in-place upgrade sidecar container image."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 1 1 sample-pd-9465f4c84 sample-pd-8697d4bf8c 6min\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 1 (12s ago) 6m\nfoo-lftw8 2/2 Running 0 3min\nfoo-n57rr 2/2 Running 0 3min\n\n$ kubectl get pod foo-2gnnl -o yaml | grep "image: ubuntu"\n image: ubuntu:22.10\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-8697d4bf8c\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-8697d4bf8c\n')),(0,o.kt)("h1",{id:"features"},"Features"),(0,o.kt)("h2",{id:"injection"},"Injection"),(0,o.kt)("h3",{id:"metadata"},"Metadata"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n metadata:\n - patchPolicy: MergePatchJson\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"sample-pd","version":"v2"}]\'\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-name: sample-pd\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"patchPolicy")," is the injected policy, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Retain"),": The original value of annotations and labels will be retained."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Overwrite"),": The value of annotations and labels corresponding to the existing key will be overwritten."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MergePatchJson"),": It only takes effect for annotation. If the key does not exist, the value will be written directly. Otherwise, the json value will be merged.")),(0,o.kt)("p",null,"For example\uff1a"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# Old pod metadata\nmetadata:\n labels:\n custom.io/sidecar-version: "v1"\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}]\'\n\n# After metadata injected\nmetadata:\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-type: sample-pd\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}, {"name":"sample-pd","version":"v2"}]\'\n')),(0,o.kt)("h3",{id:"primary-container"},"Primary Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n primaryContainers:\n - targetPolicy: ByName\n name: foo\n image: foo:v2\n env: \n - name: APP_NAME\n value: foo\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n")),(0,o.kt)("p",null,"Injection into the primary containers only supports limited fields: ",(0,o.kt)("inlineCode",{parentName:"p"},"image"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"env")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"volumeMounts"),"."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"targetPolicy")," indicates which existed container these configuration should inject into, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ByName"),": Only inject containers matching ",(0,o.kt)("inlineCode",{parentName:"li"},"name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"All"),": Inject all primary containers."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"First"),": Inject into first primary container."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Last"),": Inject into last primary container.")),(0,o.kt)("h3",{id:"sidecar-container"},"Sidecar Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n containers:\n - injectPolicy: AfterPrimaryContainer # Container injected policy, AfterPrimaryContainer or BeforePrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n ...\n")),(0,o.kt)("p",null,"Inject a new sidecar container. Optional, it can be placed in front or behind the primary container."),(0,o.kt)("h3",{id:"initcontainer"},"InitContainer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n initContainers:\n - name: init\n image: custom-init-image:v1\n ...\n")),(0,o.kt)("h2",{id:"upgrade-strategy"},"Upgrade strategy"),(0,o.kt)("p",null,"Coming soon..."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e89e36c0.d5a819be.js b/assets/js/e89e36c0.d5a819be.js deleted file mode 100644 index b4c23545424..00000000000 --- a/assets/js/e89e36c0.d5a819be.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7816],{3905:(e,n,a)=>{a.d(n,{Zo:()=>d,kt:()=>u});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function l(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var p=t.createContext({}),s=function(e){var n=t.useContext(p),a=n;return e&&(a="function"==typeof e?e(n):l(l({},n),e)),a},d=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},m=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),m=s(a),u=o,f=m["".concat(p,".").concat(u)]||m[u]||c[u]||i;return a?t.createElement(f,l(l({ref:n},d),{},{components:a})):t.createElement(f,l({ref:n},d))}));function u(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=a.length,l=new Array(i);l[0]=m;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r.mdxType="string"==typeof e?e:o,l[1]=r;for(var s=2;s{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>c,frontMatter:()=>i,metadata:()=>r,toc:()=>s});var t=a(87462),o=(a(67294),a(3905));const i={sidebar_position:4},l="PodDecoration",r={unversionedId:"operating/manuals/poddecoration",id:"version-v0.10/operating/manuals/poddecoration",title:"PodDecoration",description:"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria.",source:"@site/versioned_docs/version-v0.10/operating/manuals/poddecoration.md",sourceDirName:"operating/manuals",slug:"/operating/manuals/poddecoration",permalink:"/docs/operating/manuals/poddecoration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/operating/manuals/poddecoration.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"operating",previous:{title:"PodTransitionRule",permalink:"/docs/operating/manuals/podtransitionrule"}},p={},s=[{value:"Create CollaSet",id:"create-collaset",level:2},{value:"Create PodDecoration",id:"create-poddecoration",level:2},{value:"Update PodDecoration",id:"update-poddecoration",level:2},{value:"Rolling update v1",id:"rolling-update-v1",level:3},{value:"Rolling update v1 -> v2",id:"rolling-update-v1---v2",level:3},{value:"Injection",id:"injection",level:2},{value:"Metadata",id:"metadata",level:3},{value:"Primary Container",id:"primary-container",level:3},{value:"Sidecar Container",id:"sidecar-container",level:3},{value:"InitContainer",id:"initcontainer",level:3},{value:"Upgrade strategy",id:"upgrade-strategy",level:2}],d={toc:s};function c(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},d,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"poddecoration"},"PodDecoration"),(0,o.kt)("p",null,"PodDecoration works in conjunction with CollaSet to selectively inject specific configurations to Pods that meet certain criteria. "),(0,o.kt)("p",null,"PodDecoration not only allows injecting sidecar containers to Pods but also enables modifying existing container configurations, metadata, and scheduling parameters etc.\nThe PodDecoration controller does not control the upgrade of Pods. The actual upgrade process is fully controlled by the CollaSet controller. This means that the injection upgrade of PodDecoration can also be performed ",(0,o.kt)("inlineCode",{parentName:"p"},"InPlaceIfPossible"),"."),(0,o.kt)("p",null,"About ",(0,o.kt)("a",{parentName:"p",href:"/docs/operating/manuals/collaset"},"CollaSet"),"."),(0,o.kt)("h1",{id:"example"},"Example"),(0,o.kt)("h2",{id:"create-collaset"},"Create CollaSet"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# collaset.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: CollaSet\nmetadata:\n name: foo\n namespace: default\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: foo\n template:\n metadata:\n labels:\n app: foo\n spec:\n containers:\n - image: nginx:1.25.2\n name: foo\n")),(0,o.kt)("p",null,"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"collaset.yaml")," to create three pods under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," management."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f collaset.yaml\ncollaset.apps.kusionstack.io/foo created\n\n$ kubectl get cls\nNAME DESIRED CURRENT AVAILABLE UPDATED UPDATED_READY UPDATED_AVAILABLE CURRENT_REVISION UPDATED_REVISION AGE\nfoo 3 3 3 3 3 3 foo-7bdb974bc7 foo-7bdb974bc7 7s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2wnnf 1/1 Running 0 41s\nfoo-hqpx7 1/1 Running 0 41s\nfoo-mqt48 1/1 Running 0 41s\n")),(0,o.kt)("h2",{id:"create-poddecoration"},"Create PodDecoration"),(0,o.kt)("p",null,"The following ",(0,o.kt)("inlineCode",{parentName:"p"},"poddecoration.yaml")," file describes a PodDecoration, which selects the pod under CollaSet ",(0,o.kt)("inlineCode",{parentName:"p"},"foo")," and injects the content in ",(0,o.kt)("inlineCode",{parentName:"p"},"template")," into the pod with ",(0,o.kt)("inlineCode",{parentName:"p"},"instance-id=0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\napiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nmetadata:\n name: sample-pd\nspec:\n selector: # selected pod range in which PodDecoration takes effect\n matchLabels:\n app: foo\n updateStrategy:\n rollingUpdate:\n selector: # select pod to upgrade in effect range\n matchLabels:\n collaset.kusionstack.io/instance-id: "0"\n template:\n metadata:\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v1"\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n command: ["sleep", "2h"]\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n')),(0,o.kt)("p",null,"Create PodDecoration ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to upgrade selected pod "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl apply -f poddecoration.yaml\npoddecoration.apps.kusionstack.io/sample-pd created\n")),(0,o.kt)("p",null,"The status of PodDecoration is updated, and one pod is injected with sidecar through recreate."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 1 1 1 sample-pd-9465f4c84 20s\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 15s\nfoo-2wnnf 1/1 Running 0 2m\nfoo-hqpx7 1/1 Running 0 2m\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-2wnnf\n escaped: true\n - name: foo-hqpx7\n escaped: true\n matchedPods: 3\n injectedPods: 1\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h2",{id:"update-poddecoration"},"Update PodDecoration"),(0,o.kt)("h3",{id:"rolling-update-v1"},"Rolling update v1"),(0,o.kt)("p",null,"Edit ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd")," to expand the upgrade scope."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Edit updateStrategy to select instance-id in [0, 1, 2]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector: \n matchExpressions:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n - "1" \n - "2" \n template:\n ...\n')),(0,o.kt)("p",null,"All pods updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 3 3 sample-pd-9465f4c84 sample-pd-9465f4c84 3m\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 0 3m\nfoo-lftw8 2/2 Running 0 8s\nfoo-n57rr 2/2 Running 0 8s\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n currentRevision: sample-pd-9465f4c84\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-9465f4c84\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 3\n updatedReadyPods: 3\n updatedAvailablePods: 3\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-9465f4c84\n")),(0,o.kt)("h3",{id:"rolling-update-v1---v2"},"Rolling update v1 -> v2"),(0,o.kt)("p",null,"Update ",(0,o.kt)("inlineCode",{parentName:"p"},"sample-pd"),"'s sidecar container image and ",(0,o.kt)("inlineCode",{parentName:"p"},"updateStrategy"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"$ kubectl edit pd sample-pd\n")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# poddecoration.yaml\n# Update sidecar-a\'s image with ubuntu:22.10\n# Edit updateStrategy to select instance-id in [0]\n...\nspec:\n ...\n updateStrategy:\n rollingUpdate:\n selector:\n - key: collaset.kusionstack.io/instance-id\n operator: In\n values:\n - "0"\n template:\n ...\n containers:\n - injectPolicy: AfterPrimaryContainer\n name: sidecar-a\n image: ubuntu:22.10\n ...\n')),(0,o.kt)("p",null,"Pod ",(0,o.kt)("inlineCode",{parentName:"p"},"foo-2gnnl")," in-place upgrade sidecar container image."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ kubectl get pd\nNAME EFFECTIVE MATCHED INJECTED UPDATED UPDATED_READY CURRENT_REVISION UPDATED_REVISION AGE\nsample-pd true 3 3 1 1 sample-pd-9465f4c84 sample-pd-8697d4bf8c 6min\n\n$ kubectl get pod\nNAME READY STATUS RESTARTS AGE\nfoo-2gnnl 2/2 Running 1 (12s ago) 6m\nfoo-lftw8 2/2 Running 0 3min\nfoo-n57rr 2/2 Running 0 3min\n\n$ kubectl get pod foo-2gnnl -o yaml | grep "image: ubuntu"\n image: ubuntu:22.10\n\n$ kubectl get pd sample-pd -o yaml | grep -A20 status\nstatus:\n details:\n - affectedReplicas: 3\n collaSet: foo\n pods:\n - name: foo-2gnnl\n revision: sample-pd-8697d4bf8c\n - name: foo-lftw8\n revision: sample-pd-9465f4c84\n - name: foo-n57rr\n revision: sample-pd-9465f4c84\n matchedPods: 3\n injectedPods: 3\n updatedPods: 1\n updatedReadyPods: 1\n updatedAvailablePods: 1\n isEffective: true\n currentRevision: sample-pd-9465f4c84\n updatedRevision: sample-pd-8697d4bf8c\n')),(0,o.kt)("h1",{id:"features"},"Features"),(0,o.kt)("h2",{id:"injection"},"Injection"),(0,o.kt)("h3",{id:"metadata"},"Metadata"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n metadata:\n - patchPolicy: MergePatchJson\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"sample-pd","version":"v2"}]\'\n - patchPolicy: Overwrite\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-name: sample-pd\n')),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"patchPolicy")," is the injected policy, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Retain"),": The original value of annotations and labels will be retained."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Overwrite"),": The value of annotations and labels corresponding to the existing key will be overwritten."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"MergePatchJson"),": It only takes effect for annotation. If the key does not exist, the value will be written directly. Otherwise, the json value will be merged.")),(0,o.kt)("p",null,"For example\uff1a"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},'# Old pod metadata\nmetadata:\n labels:\n custom.io/sidecar-version: "v1"\n annotations:\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}]\'\n\n# After metadata injected\nmetadata:\n labels:\n custom.io/sidecar-version: "v2"\n annotations:\n cafe.sofastack.io/decoration-type: sample-pd\n cafe.sofastack.io/decoration-version: \'[{"name":"old-pd","version":"v1"}, {"name":"sample-pd","version":"v2"}]\'\n')),(0,o.kt)("h3",{id:"primary-container"},"Primary Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps.kusionstack.io/v1alpha1\nkind: PodDecoration\nspec:\n template:\n primaryContainers:\n - targetPolicy: ByName\n name: foo\n image: foo:v2\n env: \n - name: APP_NAME\n value: foo\n volumeMounts:\n - name: sample-volume\n mountPath: /vol/sample\n volumes:\n - name: sample-volume\n emptyDir: {}\n")),(0,o.kt)("p",null,"Injection into the primary containers only supports limited fields: ",(0,o.kt)("inlineCode",{parentName:"p"},"image"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"env")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"volumeMounts"),"."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"targetPolicy")," indicates which existed container these configuration should inject into, as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"ByName"),": Only inject containers matching ",(0,o.kt)("inlineCode",{parentName:"li"},"name"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"All"),": Inject all primary containers."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"First"),": Inject into first primary container."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Last"),": Inject into last primary container.")),(0,o.kt)("h3",{id:"sidecar-container"},"Sidecar Container"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n containers:\n - injectPolicy: AfterPrimaryContainer # Container injected policy, AfterPrimaryContainer or BeforePrimaryContainer\n name: sidecar-a\n image: ubuntu:22.04\n ...\n")),(0,o.kt)("p",null,"Inject a new sidecar container. Optional, it can be placed in front or behind the primary container."),(0,o.kt)("h3",{id:"initcontainer"},"InitContainer"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"spec:\n template:\n initContainers:\n - name: init\n image: custom-init-image:v1\n ...\n")),(0,o.kt)("h2",{id:"upgrade-strategy"},"Upgrade strategy"),(0,o.kt)("p",null,"Coming soon..."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ebf27649.a13fb837.js b/assets/js/ebf27649.a13fb837.js deleted file mode 100644 index a2ab5468328..00000000000 --- a/assets/js/ebf27649.a13fb837.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2136],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),c=p(n),u=r,k=c["".concat(s,".").concat(u)]||c[u]||m[u]||l;return n?a.createElement(k,o(o({ref:t},d),{},{components:n})):a.createElement(k,o({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=c;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={id:"naming-conventions",sidebar_label:"Naming Conventions"},o="Naming Conventions",i={unversionedId:"kusion/reference/model/naming-conventions",id:"version-v0.9/kusion/reference/model/naming-conventions",title:"Naming Conventions",description:"Kubernetes Resources",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/naming-conventions.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/naming-conventions",permalink:"/docs/v0.9/kusion/reference/model/naming-conventions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/naming-conventions.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{id:"naming-conventions",sidebar_label:"Naming Conventions"},sidebar:"kusion",previous:{title:"secret",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret"},next:{title:"Project & Stack Config Items",permalink:"/docs/v0.9/kusion/reference/model/project-stack-config-items"}},s={},p=[{value:"Kubernetes Resources",id:"kubernetes-resources",level:2},{value:"Terraform Resources",id:"terraform-resources",level:2},{value:"Apply Options",id:"apply-options",level:2},{value:"Magic Variables",id:"magic-variables",level:2},{value:"Concept Explanation",id:"concept-explanation",level:3},{value:"List of Magic Variables",id:"list-of-magic-variables",level:3},{value:"Sensitive Database Information",id:"sensitive-database-information",level:4}],d={toc:p};function m(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"naming-conventions"},"Naming Conventions"),(0,r.kt)("h2",{id:"kubernetes-resources"},"Kubernetes Resources"),(0,r.kt)("p",null,"Kusion adheres to specific rules when generating the Kubernetes resources for users' applications. The table below lists some common Kubernetes resource naming conventions. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Resource"),(0,r.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,r.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name")),(0,r.kt)("td",{parentName:"tr",align:null},"v1:Namespace:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"stack name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"apps/v1:Deployment:wordpress:wordpress-dev-wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CronJob"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"stack name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"batch/v1:CronJob:helloworld:helloworld-dev-helloworld")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Service"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"stack name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"app name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"public"),"/",(0,r.kt)("inlineCode",{parentName:"td"},"private")),(0,r.kt)("td",{parentName:"tr",align:null},"v1:Service:helloworld:helloworld-dev-helloworld-public")))),(0,r.kt)("h2",{id:"terraform-resources"},"Terraform Resources"),(0,r.kt)("p",null,"Similarly, Kusion also adheres to specific naming conventions when generating the Terraform Resources. Some common resources are listed below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Resource"),(0,r.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,r.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"random_password"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"db")),(0,r.kt)("td",{parentName:"tr",align:null},"hashicorp:random:random_password:wordpress-db")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"aws_security_group"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"db")),(0,r.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_security_group:wordpress-db")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"aws_db_instance"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_db_instance:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"alicloud_db_instance"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_instance:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"alicloud_db_connection"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_connection:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"alicloud_rds_account"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_rds_account:wordpress")))),(0,r.kt)("h2",{id:"apply-options"},"Apply Options"),(0,r.kt)("p",null,"Before applying the project, users may need to export some environment variables to specify the Provider information for provisioning cloud resources. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Environment Variable"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"),(0,r.kt)("th",{parentName:"tr",align:null},"Example"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"AWS_PROVIDER_REGION"),(0,r.kt)("td",{parentName:"tr",align:null},"The region where the aws provider provisions the resources"),(0,r.kt)("td",{parentName:"tr",align:null},"us-east-1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"AWS_ACCESS_KEY_ID"),(0,r.kt)("td",{parentName:"tr",align:null},"The access key for the aws provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"AWS_SECRET_ACCESS_KEY"),(0,r.kt)("td",{parentName:"tr",align:null},"The secret key for the aws provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ALICLOUD_PROVIDER_REGION"),(0,r.kt)("td",{parentName:"tr",align:null},"The region where the alicloud provider provisions the resources"),(0,r.kt)("td",{parentName:"tr",align:null},"cn-beijing")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ALICLOUD_ACCESS_KEY"),(0,r.kt)("td",{parentName:"tr",align:null},"The access key for the alicloud provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ALICLOUD_SECRET_KEY"),(0,r.kt)("td",{parentName:"tr",align:null},"The secret key for the alicloud provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("h2",{id:"magic-variables"},"Magic Variables"),(0,r.kt)("h3",{id:"concept-explanation"},"Concept Explanation"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Magic variables")," are preconfigured variables representing fundamental metadata or environment variables automatically generated and injected into the application container by Kusion, which are typically used for accessories such as databases. "),(0,r.kt)("h3",{id:"list-of-magic-variables"},"List of Magic Variables"),(0,r.kt)("h4",{id:"sensitive-database-information"},"Sensitive Database Information"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host address"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB_HOST"),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB_USERNAME"),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB_PASSWORD"),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ebf27649.e699151a.js b/assets/js/ebf27649.e699151a.js new file mode 100644 index 00000000000..237b0f543bc --- /dev/null +++ b/assets/js/ebf27649.e699151a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2136],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),c=p(n),u=r,k=c["".concat(s,".").concat(u)]||c[u]||m[u]||l;return n?a.createElement(k,i(i({ref:t},d),{},{components:n})):a.createElement(k,i({ref:t},d))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var a=n(87462),r=(n(67294),n(3905));const l={id:"naming-conventions",sidebar_label:"Naming Conventions"},i="Naming Conventions",o={unversionedId:"kusion/reference/model/naming-conventions",id:"version-v0.9/kusion/reference/model/naming-conventions",title:"Naming Conventions",description:"Kubernetes Resources",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/naming-conventions.md",sourceDirName:"kusion/reference/model",slug:"/kusion/reference/model/naming-conventions",permalink:"/docs/v0.9/kusion/reference/model/naming-conventions",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/naming-conventions.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{id:"naming-conventions",sidebar_label:"Naming Conventions"},sidebar:"kusion",previous:{title:"secret",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret"},next:{title:"Project & Stack Config Items",permalink:"/docs/v0.9/kusion/reference/model/project-stack-config-items"}},s={},p=[{value:"Kubernetes Resources",id:"kubernetes-resources",level:2},{value:"Terraform Resources",id:"terraform-resources",level:2},{value:"Apply Options",id:"apply-options",level:2},{value:"Magic Variables",id:"magic-variables",level:2},{value:"Concept Explanation",id:"concept-explanation",level:3},{value:"List of Magic Variables",id:"list-of-magic-variables",level:3},{value:"Sensitive Database Information",id:"sensitive-database-information",level:4}],d={toc:p};function m(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"naming-conventions"},"Naming Conventions"),(0,r.kt)("h2",{id:"kubernetes-resources"},"Kubernetes Resources"),(0,r.kt)("p",null,"Kusion adheres to specific rules when generating the Kubernetes resources for users' applications. The table below lists some common Kubernetes resource naming conventions. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Resource"),(0,r.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,r.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Namespace"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name")),(0,r.kt)("td",{parentName:"tr",align:null},"v1:Namespace:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"stack name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"apps/v1:Deployment:wordpress:wordpress-dev-wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CronJob"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"stack name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"batch/v1:CronJob:helloworld:helloworld-dev-helloworld")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Service"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"project name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"stack name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"app name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"public"),"/",(0,r.kt)("inlineCode",{parentName:"td"},"private")),(0,r.kt)("td",{parentName:"tr",align:null},"v1:Service:helloworld:helloworld-dev-helloworld-public")))),(0,r.kt)("h2",{id:"terraform-resources"},"Terraform Resources"),(0,r.kt)("p",null,"Similarly, Kusion also adheres to specific naming conventions when generating the Terraform Resources. Some common resources are listed below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Resource"),(0,r.kt)("th",{parentName:"tr",align:null},"Concatenation Rule"),(0,r.kt)("th",{parentName:"tr",align:null},"Example ID"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"random_password"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"db")),(0,r.kt)("td",{parentName:"tr",align:null},"hashicorp:random:random_password:wordpress-db")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"aws_security_group"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name"),"-",(0,r.kt)("inlineCode",{parentName:"td"},"db")),(0,r.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_security_group:wordpress-db")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"aws_db_instance"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"hashicorp:aws:aws_db_instance:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"alicloud_db_instance"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_instance:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"alicloud_db_connection"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_db_connection:wordpress")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"alicloud_rds_account"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"app name")),(0,r.kt)("td",{parentName:"tr",align:null},"aliyun:alicloud:alicloud_rds_account:wordpress")))),(0,r.kt)("h2",{id:"apply-options"},"Apply Options"),(0,r.kt)("p",null,"Before applying the project, users may need to export some environment variables to specify the Provider information for provisioning cloud resources. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Environment Variable"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"),(0,r.kt)("th",{parentName:"tr",align:null},"Example"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"AWS_PROVIDER_REGION"),(0,r.kt)("td",{parentName:"tr",align:null},"The region where the aws provider provisions the resources"),(0,r.kt)("td",{parentName:"tr",align:null},"us-east-1")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"AWS_ACCESS_KEY_ID"),(0,r.kt)("td",{parentName:"tr",align:null},"The access key for the aws provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"AWS_SECRET_ACCESS_KEY"),(0,r.kt)("td",{parentName:"tr",align:null},"The secret key for the aws provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ALICLOUD_PROVIDER_REGION"),(0,r.kt)("td",{parentName:"tr",align:null},"The region where the alicloud provider provisions the resources"),(0,r.kt)("td",{parentName:"tr",align:null},"cn-beijing")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ALICLOUD_ACCESS_KEY"),(0,r.kt)("td",{parentName:"tr",align:null},"The access key for the alicloud provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"ALICLOUD_SECRET_KEY"),(0,r.kt)("td",{parentName:"tr",align:null},"The secret key for the alicloud provider to provision the resources"),(0,r.kt)("td",{parentName:"tr",align:null})))),(0,r.kt)("h2",{id:"magic-variables"},"Magic Variables"),(0,r.kt)("h3",{id:"concept-explanation"},"Concept Explanation"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Magic variables")," are preconfigured variables representing fundamental metadata or environment variables automatically generated and injected into the application container by Kusion, which are typically used for accessories such as databases. "),(0,r.kt)("h3",{id:"list-of-magic-variables"},"List of Magic Variables"),(0,r.kt)("h4",{id:"sensitive-database-information"},"Sensitive Database Information"),(0,r.kt)("p",null,"For sensitive information such as the ",(0,r.kt)("strong",{parentName:"p"},"host address"),", ",(0,r.kt)("strong",{parentName:"p"},"username")," and ",(0,r.kt)("strong",{parentName:"p"},"password")," for the database instance, Kusion will automatically inject them into the application container for users through environment variables. The relevant environment variables are listed in the table below. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Explanation"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB_HOST"),(0,r.kt)("td",{parentName:"tr",align:null},"Host address for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB_USERNAME"),(0,r.kt)("td",{parentName:"tr",align:null},"Account username for accessing the database instance")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"KUSION_DB_PASSWORD"),(0,r.kt)("td",{parentName:"tr",align:null},"Account password for accessing the database instance")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ecaa6eee.1683acaa.js b/assets/js/ecaa6eee.eb4b9d9e.js similarity index 54% rename from assets/js/ecaa6eee.1683acaa.js rename to assets/js/ecaa6eee.eb4b9d9e.js index 35f497b0ab6..92e9fe99580 100644 --- a/assets/js/ecaa6eee.1683acaa.js +++ b/assets/js/ecaa6eee.eb4b9d9e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5156],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},c),{},{components:n})):r.createElement(k,l({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/workspace-configs/networking/port",id:"version-v0.10/kusion/reference/modules/workspace-configs/networking/port",title:"port",description:"port can be used to define workspace-level networking configurations.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/networking",slug:"/kusion/reference/modules/workspace-configs/networking/port",permalink:"/docs/kusion/reference/modules/workspace-configs/networking/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"monitoring",permalink:"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus"},next:{title:"opsrule",permalink:"/docs/kusion/reference/modules/workspace-configs/trait/opsrule"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"port")," can be used to define workspace-level networking configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"The specific cloud vendor that provides load balancer."),(0,a.kt)("td",{parentName:"tr",align:null},'"alicloud" ',"|",' "aws"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"The attached labels of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"The attached annotations of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5156],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},c),{},{components:n})):r.createElement(k,l({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const o={},l="port",i={unversionedId:"kusion/reference/modules/workspace-configs/networking/port",id:"version-v0.10/kusion/reference/modules/workspace-configs/networking/port",title:"port",description:"port can be used to define workspace-level networking configurations.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/networking",slug:"/kusion/reference/modules/workspace-configs/networking/port",permalink:"/docs/kusion/reference/modules/workspace-configs/networking/port",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"monitoring",permalink:"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus"},next:{title:"opsrule",permalink:"/docs/kusion/reference/modules/workspace-configs/trait/opsrule"}},s={},p=[{value:"Attributes",id:"attributes",level:2},{value:"Examples",id:"examples",level:3}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"port"},"port"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"port")," can be used to define workspace-level networking configurations."),(0,a.kt)("h2",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"The specific cloud vendor that provides load balancer."),(0,a.kt)("td",{parentName:"tr",align:null},'"alicloud" ',"|",' "aws"'),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"The attached labels of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"The attached annotations of the port."),(0,a.kt)("td",{parentName:"tr",align:null},"{str:str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n port:\n default:\n type: alicloud\n labels:\n kusionstack.io/control: "true"\n annotations:\n service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ecbd3f41.05abb6bd.js b/assets/js/ecbd3f41.05abb6bd.js new file mode 100644 index 00000000000..a55a2ba0f6f --- /dev/null +++ b/assets/js/ecbd3f41.05abb6bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9529],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>f});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(t),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||a;return t?n.createElement(m,i(i({ref:r},l),{},{components:t})):n.createElement(m,i({ref:r},l))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=d;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var p=2;p{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=t(87462),o=(t(67294),t(3905));const a={},i="kusion workspace create",s={unversionedId:"kusion/reference/commands/kusion-workspace-create",id:"version-v0.10/kusion/reference/commands/kusion-workspace-create",title:"kusion workspace create",description:"Create a new workspace",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-create.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-create",permalink:"/docs/kusion/reference/commands/kusion-workspace-create",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-create.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion version",permalink:"/docs/kusion/reference/commands/kusion-version"},next:{title:"kusion workspace delete",permalink:"/docs/kusion/reference/commands/kusion-workspace-delete"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-create"},"kusion workspace create"),(0,o.kt)("p",null,"Create a new workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command creates a workspace with specified name and configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace create\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Create a new workspace\n kusion workspace create dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for create\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ecbd3f41.a7744f53.js b/assets/js/ecbd3f41.a7744f53.js deleted file mode 100644 index b24b84e35a7..00000000000 --- a/assets/js/ecbd3f41.a7744f53.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9529],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>f});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),d=p(t),f=o,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||a;return t?n.createElement(m,s(s({ref:r},l),{},{components:t})):n.createElement(m,s({ref:r},l))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,s=new Array(a);s[0]=d;var i={};for(var c in r)hasOwnProperty.call(r,c)&&(i[c]=r[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,s[1]=i;for(var p=2;p{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var n=t(87462),o=(t(67294),t(3905));const a={},s="kusion workspace create",i={unversionedId:"kusion/reference/commands/kusion-workspace-create",id:"version-v0.10/kusion/reference/commands/kusion-workspace-create",title:"kusion workspace create",description:"Create a new workspace",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-create.md",sourceDirName:"kusion/6-reference/1-commands",slug:"/kusion/reference/commands/kusion-workspace-create",permalink:"/docs/kusion/reference/commands/kusion-workspace-create",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-create.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion version",permalink:"/docs/kusion/reference/commands/kusion-version"},next:{title:"kusion workspace delete",permalink:"/docs/kusion/reference/commands/kusion-workspace-delete"}},c={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 4-Jan-2024",id:"auto-generated-by-spf13cobra-on-4-jan-2024",level:6}],l={toc:p};function u(e){let{components:r,...t}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-workspace-create"},"kusion workspace create"),(0,o.kt)("p",null,"Create a new workspace"),(0,o.kt)("h3",{id:"synopsis"},"Synopsis"),(0,o.kt)("p",null,"This command creates a workspace with specified name and configuration file, where the file must be in the YAML format."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion workspace create\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," # Create a new workspace\n kusion workspace create dev -f dev.yaml\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -f, --file string the path of workspace configuration file\n -h, --help help for create\n")),(0,o.kt)("h3",{id:"options-inherited-from-parent-commands"},"Options inherited from parent commands"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},' --profile string Name of profile to capture. One of (none|cpu|heap|goroutine|threadcreate|block|mutex) (default "none")\n --profile-output string Name of the file to write the profile to (default "profile.pprof")\n')),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/kusion/reference/commands/kusion-workspace"},"kusion workspace"),"\t - Workspace is a logical concept representing a target that stacks will be deployed to")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-4-jan-2024"},"Auto generated by spf13/cobra on 4-Jan-2024"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/eccaeac4.538071fd.js b/assets/js/eccaeac4.538071fd.js new file mode 100644 index 00000000000..7936469655d --- /dev/null +++ b/assets/js/eccaeac4.538071fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4995],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>d});var i=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},f=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),f=p(n),d=r,m=f["".concat(l,".").concat(d)]||f[d]||u[d]||o;return n?i.createElement(m,a(a({ref:t},c),{},{components:n})):i.createElement(m,a({ref:t},c))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,a=new Array(o);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),r=(n(67294),n(3905));const o={},a="kusion init",s={unversionedId:"kusion/reference/cli/kusion/kusion_init",id:"version-v0.9/kusion/reference/cli/kusion/kusion_init",title:"kusion init",description:"Initialize the scaffolding for a project",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_init.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_init",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_init.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion destroy",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy"},next:{title:"kusion preview",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-init"},"kusion init"),(0,r.kt)("p",null,"Initialize the scaffolding for a project"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"This command initializes the scaffolding for a project, generating a project from an appointed template with correct structure."),(0,r.kt)("p",null," The scaffold templates can be retrieved from local or online. The built-in templates are used by default, self-defined templates are also supported by assigning the template repository path."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion init\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Initialize a project from internal templates\n kusion init\n \n # Initialize a project from default online templates\n kusion init --online=true\n \n # Initialize a project from a specific online template\n kusion init https://github.com// --online=true\n \n # Initialize a project from a specific local template\n kusion init /path/to/templates\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," --custom-params string Custom params in JSON. If specified, it will be used as the template default value and skip prompts\n --force Force generating the scaffolding files, even if it would change the existing files\n -h, --help help for init\n --online Use templates from online repository to initialize project, or use locally cached templates\n --project-name string Initialize with specified project name. If not specified, a prompt will request it\n --template-name string Initialize with specified template. If not specified, a prompt will request it\n --yes Skip prompts and proceed with default values\n")),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/eccaeac4.c95926af.js b/assets/js/eccaeac4.c95926af.js deleted file mode 100644 index a1feb6736e6..00000000000 --- a/assets/js/eccaeac4.c95926af.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4995],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>d});var i=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},f=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),f=p(n),d=r,m=f["".concat(l,".").concat(d)]||f[d]||u[d]||o;return n?i.createElement(m,a(a({ref:t},c),{},{components:n})):i.createElement(m,a({ref:t},c))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,a=new Array(o);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var i=n(87462),r=(n(67294),n(3905));const o={},a="kusion init",s={unversionedId:"kusion/reference/cli/kusion/kusion_init",id:"version-v0.9/kusion/reference/cli/kusion/kusion_init",title:"kusion init",description:"Initialize the scaffolding for a project",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_init.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_init",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_init.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion destroy",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy"},next:{title:"kusion preview",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview"}},l={},p=[{value:"Synopsis",id:"synopsis",level:3},{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 28-Sep-2023",id:"auto-generated-by-spf13cobra-on-28-sep-2023",level:6}],c={toc:p};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"kusion-init"},"kusion init"),(0,r.kt)("p",null,"Initialize the scaffolding for a project"),(0,r.kt)("h3",{id:"synopsis"},"Synopsis"),(0,r.kt)("p",null,"This command initializes the scaffolding for a project, generating a project from an appointed template with correct structure."),(0,r.kt)("p",null," The scaffold templates can be retrieved from local or online. The built-in templates are used by default, self-defined templates are also supported by assigning the template repository path."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"kusion init\n")),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," # Initialize a project from internal templates\n kusion init\n \n # Initialize a project from default online templates\n kusion init --online=true\n \n # Initialize a project from a specific online template\n kusion init https://github.com// --online=true\n \n # Initialize a project from a specific local template\n kusion init /path/to/templates\n")),(0,r.kt)("h3",{id:"options"},"Options"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"}," --custom-params string Custom params in JSON. If specified, it will be used as the template default value and skip prompts\n --force Force generating the scaffolding files, even if it would change the existing files\n -h, --help help for init\n --online Use templates from online repository to initialize project, or use locally cached templates\n --project-name string Initialize with specified project name. If not specified, a prompt will request it\n --template-name string Initialize with specified template. If not specified, a prompt will request it\n --yes Skip prompts and proceed with default values\n")),(0,r.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,r.kt)("h6",{id:"auto-generated-by-spf13cobra-on-28-sep-2023"},"Auto generated by spf13/cobra on 28-Sep-2023"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ed2e9c54.8b9e5d08.js b/assets/js/ed2e9c54.ca949112.js similarity index 83% rename from assets/js/ed2e9c54.8b9e5d08.js rename to assets/js/ed2e9c54.ca949112.js index 720b0af3b42..7abaf6c7afa 100644 --- a/assets/js/ed2e9c54.8b9e5d08.js +++ b/assets/js/ed2e9c54.ca949112.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9037],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),f=p(r),d=o,m=f["".concat(c,".").concat(d)]||f[d]||l[d]||i;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=f;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const i={},s="KCL",a={unversionedId:"kusion/support/kcl",id:"version-v0.9/kusion/support/kcl",title:"KCL",description:"Visit the KCL website for more documents.",source:"@site/versioned_docs/version-v0.9/kusion/support/kcl.md",sourceDirName:"kusion/support",slug:"/kusion/support/kcl",permalink:"/docs/v0.9/kusion/support/kcl",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/support/kcl.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Installation",permalink:"/docs/v0.9/kusion/support/install-error"}},c={},p=[],u={toc:p};function l(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kcl"},"KCL"),(0,o.kt)("p",null,"Visit the ",(0,o.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website")," for more documents."))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9037],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),f=p(r),d=o,m=f["".concat(c,".").concat(d)]||f[d]||l[d]||i;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=f;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const i={},s="KCL",a={unversionedId:"kusion/support/kcl",id:"version-v0.9/kusion/support/kcl",title:"KCL",description:"Visit the KCL website for more documents.",source:"@site/versioned_docs/version-v0.9/kusion/support/kcl.md",sourceDirName:"kusion/support",slug:"/kusion/support/kcl",permalink:"/docs/v0.9/kusion/support/kcl",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/support/kcl.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Installation",permalink:"/docs/v0.9/kusion/support/install-error"}},c={},p=[],u={toc:p};function l(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kcl"},"KCL"),(0,o.kt)("p",null,"Visit the ",(0,o.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website")," for more documents."))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ee59e712.905fad65.js b/assets/js/ee59e712.905fad65.js deleted file mode 100644 index 92b37714f92..00000000000 --- a/assets/js/ee59e712.905fad65.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2846],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=i,f=u["".concat(l,".").concat(h)]||u[h]||d[h]||a;return n?o.createElement(f,r(r({ref:t},c),{},{components:n})):o.createElement(f,r({ref:t},c))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,r=new Array(a);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var o=n(87462),i=(n(67294),n(3905));const a={sidebar_position:4,sidebar_label:"AppConfiguration"},r="Declarative Application Configuration Model - AppConfiguration",s={unversionedId:"kusion/concepts/appconfiguration",id:"version-v0.9/kusion/concepts/appconfiguration",title:"Declarative Application Configuration Model - AppConfiguration",description:"Abstract",source:"@site/versioned_docs/version-v0.9/kusion/concepts/appconfiguration.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/appconfiguration",permalink:"/docs/v0.9/kusion/concepts/appconfiguration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/appconfiguration.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4,sidebar_label:"AppConfiguration"},sidebar:"kusion",previous:{title:"How Kusion Works",permalink:"/docs/v0.9/kusion/concepts/kusion"},next:{title:"Intent",permalink:"/docs/v0.9/kusion/concepts/intent"}},l={},p=[{value:"Abstract",id:"abstract",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design",id:"design",level:2},{value:"Core Principles",id:"core-principles",level:3},{value:"Developer First",id:"developer-first",level:4},{value:"Application-Centric",id:"application-centric",level:4},{value:"Platform Agnostic",id:"platform-agnostic",level:4},{value:"Model Architecture",id:"model-architecture",level:3},{value:"Core Concepts",id:"core-concepts",level:3},{value:"Component",id:"component",level:4},{value:"Pipeline",id:"pipeline",level:4},{value:"Topologies",id:"topologies",level:4},{value:"PolicySets",id:"policysets",level:4},{value:"Dependency",id:"dependency",level:4},{value:"References",id:"references",level:2}],c={toc:p};function d(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"declarative-application-configuration-model---appconfiguration"},"Declarative Application Configuration Model - AppConfiguration"),(0,i.kt)("h2",{id:"abstract"},"Abstract"),(0,i.kt)("p",null,"Kusion consumes the declarative configuration that describes the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure. In order to do that, we need a declarative model that can best describe the intent for a given application."),(0,i.kt)("p",null,"This design document elaborates on the core design considerations and a high-level architecture of the next-generation declarative application configuration model. The AppConfiguration model is expected to continuously iterate over time, with the purpose to better encapsulate the application configuration needs declaratively in its full lifecycle and reduce cognitive complexity as much as possible for the developers."),(0,i.kt)("p",null,"AppConfiguration consists of multiple elements that each represents a significant portion in the application lifecycle, either the application workload itself, its dependencies, relevant deployment workflows or operational expectations."),(0,i.kt)("h2",{id:"motivation"},"Motivation"),(0,i.kt)("p",null,"In AntGroup, we have heavily invested in the efforts to enable application delivery on a massive scale. What we have observed in the past few years is a trend of continuous evolution of infrastructure complexity over time, as a result of the increasing business needs."),(0,i.kt)("p",null,"We are motivated to find a new paradigm that highlights collaborations between different parts of the software organizations and enables self-service ability as much as possible to get to a mature level of standardization and efficiency in application delivery."),(0,i.kt)("p",null,"The centerpiece of this paradigm is a consistent, comprehensive and declarative application model that captures the application needs in an intuitive and self-explanatory way."),(0,i.kt)("p",null,"This paradigm will also require a core workflow that KusionStack advocates, an effort of retrofitting that workflow based on different organizational needs, a golden path that represents industry best practices, and a shift in organizational culture. We won't go into those details in this document."),(0,i.kt)("h2",{id:"design"},"Design"),(0,i.kt)("h3",{id:"core-principles"},"Core Principles"),(0,i.kt)("h4",{id:"developer-first"},"Developer First"),(0,i.kt)("p",null,"The AppConfiguration model serves as the interface for the application developers. The model design should favor the perspective of application developers, rather than platform or infrastructure developers. The primary purpose of a unified and abstract application delivery model is to be able to define an application with concepts and semantics that are intuitive and easy for developers to understand, without the need for any advanced knowledge on infrastructure. The goal is to reduce the cognitive burden of application developers by hiding the increasing complexity of the underlying infrastructure, be it different clouds, runtimes, or product offerings."),(0,i.kt)("p",null,'Developers should be able to describe an application as simple as "I want a database of type X and version Y to go along my application".'),(0,i.kt)("h4",{id:"application-centric"},"Application-Centric"),(0,i.kt)("p",null,"In practice, the end-to-end delivery of a production-grade application typically involves more than provisioning the computing resource and bootstrapping the workload. It also includes managing a variety of dependent resources the application workload depends on, such as networking, storage, database, middleware, monitoring and alerting, etc."),(0,i.kt)("p",null,"AppConfiguration proposes an application-centric approach, where the dependencies of an application can be kept together along with any operational (Day2) expectations. Everything the application needs to be production-available is captured inside a single, declarative source of truth centered around the AppConfiguration model. AppConfiguration should serve as the consistent and comprehensive abstraction of the application needs through its entire lifecycle."),(0,i.kt)("h4",{id:"platform-agnostic"},"Platform Agnostic"),(0,i.kt)("p",null,"AppConfiguration should avoid locking into any specific tooling, technology stack or infrastructure providers. Kusion is built with the philosophy that benefits from an open and diverse ecosystem, where any infrastructure provider can be included in the form of plugins."),(0,i.kt)("p",null,'The design of AppConfiguration should emphasize separation of concern between the roles that write application business logic and those that manage platform level configurations. In the context of using public cloud, the AppConfiguration model should support multi-cloud deployment out-of-the-box. The configurations should be "Write Once Deploy Everywhere".'),(0,i.kt)("h3",{id:"model-architecture"},"Model Architecture"),(0,i.kt)("p",null,"The AppConfiguration model consolidates all the necessary components and their dependent accessories for the application deployment, along with any workflow, policy and operational requirements into one standardized, infrastructure-independent declarative specification. This declarative specification represents the intuitive user intent for the application, which drives a standardized and efficient application delivery and operation process in a hybrid environment. This enables application developers the ability to self-service based on concepts and semantics that are intuitive and self-explanatory."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"appconfig.png",src:n(57091).Z,width:"2486",height:"1767"})),(0,i.kt)("p",null,"AppConfiguration consists of five core concepts, namely ",(0,i.kt)("inlineCode",{parentName:"p"},"Components"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency"),". We will walk through these concepts one by one."),(0,i.kt)("h3",{id:"core-concepts"},"Core Concepts"),(0,i.kt)("h4",{id:"component"},"Component"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components")," defines the foundation of any application configuration. Generally speaking, we believe that a comprehensive application description should at least consist of a core deployable workload that is frequently iterated and a collection of any other core services that the workload depends on, such as databases, caches or any other cloud services."),(0,i.kt)("p",null,"Components are conceptually split into two categories, ",(0,i.kt)("inlineCode",{parentName:"p"},"Workload")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories"),". The former revolves around the configuration for the computing resource. The latter represents any third-party runtime capabilities and operational requirements that the application needs. Each AppConfiguration consists of exactly one workload and any number of accessories."),(0,i.kt)("p",null,"Simply put, we can define ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," with the following expression:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components = Workload + Accessories")),(0,i.kt)("p",null,"The concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories")," itself is implicit when ",(0,i.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"authoring the configuration files"),". You can define the workload and any type of accessories (such as database or monitoring) directly under the AppConfiguration model."),(0,i.kt)("p",null,"From a collaboration perspective, platform developers and SREs are responsible for continuously adding any new schema (as abstractions for the underlying infrastructure) and implementations that can be used out-of-the-box. Application developers SREs should be able to leverage the corresponding schemas to cover the evolving application needs. This helps software organizations achieve separation of concern, so that different roles can focus on the subject matter they are an expert of."),(0,i.kt)("h4",{id:"pipeline"},"Pipeline"),(0,i.kt)("p",null,"In most of the cases, the platform is capable of providing a consistent application delivery process that can meet most application needs. In the case that an application warrants any customization in the delivery workflow, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline")," section in AppConfiguration provides an approach to extend the workflow as needed. "),(0,i.kt)("p",null,"A typical delivery workflow is made of several stages, each corresponds to some logic that needs to be executed, such as manual approval, data transfer, coordinated multi-cluster release, notification, etc. Implementation-wise, the execution of each stage should be carried out with a plugin, developed and managed by the platform owners."),(0,i.kt)("h4",{id:"topologies"},"Topologies"),(0,i.kt)("p",null,"In reality, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets including different clouds, regions, availability zones or runtimes for availability/cost/regulation/performance or disaster recovery related reasons. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies")," section in AppConfiguration highlights the different deployment targets in the application delivery and provides a single pane of glass that overlooks the entire deployment topology."),(0,i.kt)("h4",{id:"policysets"},"PolicySets"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets")," section is responsible for defining the set of rules and procedures that should be followed in the application delivery process. They generally represent the guidelines with the purpose of minimizing any technical, security or compliance risks. Some of examples include release strategies, risk management policies, and self-healing strategies. The collections of policies are expected to be managed as a joint effort from all the stakeholders, including platform owners, infrastructure owners, and security and compliance stakeholders. Some policy sets (usually security and compliance related) are expected to be mandatory. Some can be switched on and off by the application owner (self-healing strategy for instance) depending on their specific needs."),(0,i.kt)("h4",{id:"dependency"},"Dependency"),(0,i.kt)("p",null,"In a production-scale environment, there are usually intricate dependencies between multiple applications. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency")," section is responsible for describing the dependencies between multiple applications."),(0,i.kt)("h2",{id:"references"},"References"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Score - ",(0,i.kt)("a",{parentName:"li",href:"https://docs.score.dev/docs/overview/"},"https://docs.score.dev/docs/overview/")),(0,i.kt)("li",{parentName:"ol"},"Acornfile - ",(0,i.kt)("a",{parentName:"li",href:"https://docs.acorn.io/authoring/overview"},"https://docs.acorn.io/authoring/overview")),(0,i.kt)("li",{parentName:"ol"},"KubeVela - ",(0,i.kt)("a",{parentName:"li",href:"https://kubevela.io/docs/getting-started/core-concept"},"https://kubevela.io/docs/getting-started/core-concept"))))}d.isMDXComponent=!0},57091:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/appconfig-6dd90bd8ff9307dc4e5f9b1553a52b29.png"}}]); \ No newline at end of file diff --git a/assets/js/ee59e712.f41b3cd0.js b/assets/js/ee59e712.f41b3cd0.js new file mode 100644 index 00000000000..a51164b4890 --- /dev/null +++ b/assets/js/ee59e712.f41b3cd0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2846],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var o=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=i,f=u["".concat(l,".").concat(h)]||u[h]||d[h]||a;return n?o.createElement(f,r(r({ref:t},c),{},{components:n})):o.createElement(f,r({ref:t},c))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,r=new Array(a);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var o=n(87462),i=(n(67294),n(3905));const a={sidebar_position:4,sidebar_label:"AppConfiguration"},r="Declarative Application Configuration Model - AppConfiguration",s={unversionedId:"kusion/concepts/appconfiguration",id:"version-v0.9/kusion/concepts/appconfiguration",title:"Declarative Application Configuration Model - AppConfiguration",description:"Abstract",source:"@site/versioned_docs/version-v0.9/kusion/concepts/appconfiguration.md",sourceDirName:"kusion/concepts",slug:"/kusion/concepts/appconfiguration",permalink:"/docs/v0.9/kusion/concepts/appconfiguration",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/concepts/appconfiguration.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4,sidebar_label:"AppConfiguration"},sidebar:"kusion",previous:{title:"How Kusion Works",permalink:"/docs/v0.9/kusion/concepts/kusion"},next:{title:"Intent",permalink:"/docs/v0.9/kusion/concepts/intent"}},l={},p=[{value:"Abstract",id:"abstract",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design",id:"design",level:2},{value:"Core Principles",id:"core-principles",level:3},{value:"Developer First",id:"developer-first",level:4},{value:"Application-Centric",id:"application-centric",level:4},{value:"Platform Agnostic",id:"platform-agnostic",level:4},{value:"Model Architecture",id:"model-architecture",level:3},{value:"Core Concepts",id:"core-concepts",level:3},{value:"Component",id:"component",level:4},{value:"Pipeline",id:"pipeline",level:4},{value:"Topologies",id:"topologies",level:4},{value:"PolicySets",id:"policysets",level:4},{value:"Dependency",id:"dependency",level:4},{value:"References",id:"references",level:2}],c={toc:p};function d(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,o.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"declarative-application-configuration-model---appconfiguration"},"Declarative Application Configuration Model - AppConfiguration"),(0,i.kt)("h2",{id:"abstract"},"Abstract"),(0,i.kt)("p",null,"Kusion consumes the declarative configuration that describes the application, and delivers intent to the target runtime including Kubernetes, clouds, or on-prem infrastructure. In order to do that, we need a declarative model that can best describe the intent for a given application."),(0,i.kt)("p",null,"This design document elaborates on the core design considerations and a high-level architecture of the next-generation declarative application configuration model. The AppConfiguration model is expected to continuously iterate over time, with the purpose to better encapsulate the application configuration needs declaratively in its full lifecycle and reduce cognitive complexity as much as possible for the developers."),(0,i.kt)("p",null,"AppConfiguration consists of multiple elements that each represents a significant portion in the application lifecycle, either the application workload itself, its dependencies, relevant deployment workflows or operational expectations."),(0,i.kt)("h2",{id:"motivation"},"Motivation"),(0,i.kt)("p",null,"In AntGroup, we have heavily invested in the efforts to enable application delivery on a massive scale. What we have observed in the past few years is a trend of continuous evolution of infrastructure complexity over time, as a result of the increasing business needs."),(0,i.kt)("p",null,"We are motivated to find a new paradigm that highlights collaborations between different parts of the software organizations and enables self-service ability as much as possible to get to a mature level of standardization and efficiency in application delivery."),(0,i.kt)("p",null,"The centerpiece of this paradigm is a consistent, comprehensive and declarative application model that captures the application needs in an intuitive and self-explanatory way."),(0,i.kt)("p",null,"This paradigm will also require a core workflow that KusionStack advocates, an effort of retrofitting that workflow based on different organizational needs, a golden path that represents industry best practices, and a shift in organizational culture. We won't go into those details in this document."),(0,i.kt)("h2",{id:"design"},"Design"),(0,i.kt)("h3",{id:"core-principles"},"Core Principles"),(0,i.kt)("h4",{id:"developer-first"},"Developer First"),(0,i.kt)("p",null,"The AppConfiguration model serves as the interface for the application developers. The model design should favor the perspective of application developers, rather than platform or infrastructure developers. The primary purpose of a unified and abstract application delivery model is to be able to define an application with concepts and semantics that are intuitive and easy for developers to understand, without the need for any advanced knowledge on infrastructure. The goal is to reduce the cognitive burden of application developers by hiding the increasing complexity of the underlying infrastructure, be it different clouds, runtimes, or product offerings."),(0,i.kt)("p",null,'Developers should be able to describe an application as simple as "I want a database of type X and version Y to go along my application".'),(0,i.kt)("h4",{id:"application-centric"},"Application-Centric"),(0,i.kt)("p",null,"In practice, the end-to-end delivery of a production-grade application typically involves more than provisioning the computing resource and bootstrapping the workload. It also includes managing a variety of dependent resources the application workload depends on, such as networking, storage, database, middleware, monitoring and alerting, etc."),(0,i.kt)("p",null,"AppConfiguration proposes an application-centric approach, where the dependencies of an application can be kept together along with any operational (Day2) expectations. Everything the application needs to be production-available is captured inside a single, declarative source of truth centered around the AppConfiguration model. AppConfiguration should serve as the consistent and comprehensive abstraction of the application needs through its entire lifecycle."),(0,i.kt)("h4",{id:"platform-agnostic"},"Platform Agnostic"),(0,i.kt)("p",null,"AppConfiguration should avoid locking into any specific tooling, technology stack or infrastructure providers. Kusion is built with the philosophy that benefits from an open and diverse ecosystem, where any infrastructure provider can be included in the form of plugins."),(0,i.kt)("p",null,'The design of AppConfiguration should emphasize separation of concern between the roles that write application business logic and those that manage platform level configurations. In the context of using public cloud, the AppConfiguration model should support multi-cloud deployment out-of-the-box. The configurations should be "Write Once Deploy Everywhere".'),(0,i.kt)("h3",{id:"model-architecture"},"Model Architecture"),(0,i.kt)("p",null,"The AppConfiguration model consolidates all the necessary components and their dependent accessories for the application deployment, along with any workflow, policy and operational requirements into one standardized, infrastructure-independent declarative specification. This declarative specification represents the intuitive user intent for the application, which drives a standardized and efficient application delivery and operation process in a hybrid environment. This enables application developers the ability to self-service based on concepts and semantics that are intuitive and self-explanatory."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"appconfig.png",src:n(57091).Z,width:"2486",height:"1767"})),(0,i.kt)("p",null,"AppConfiguration consists of five core concepts, namely ",(0,i.kt)("inlineCode",{parentName:"p"},"Components"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets"),", and ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency"),". We will walk through these concepts one by one."),(0,i.kt)("h3",{id:"core-concepts"},"Core Concepts"),(0,i.kt)("h4",{id:"component"},"Component"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components")," defines the foundation of any application configuration. Generally speaking, we believe that a comprehensive application description should at least consist of a core deployable workload that is frequently iterated and a collection of any other core services that the workload depends on, such as databases, caches or any other cloud services."),(0,i.kt)("p",null,"Components are conceptually split into two categories, ",(0,i.kt)("inlineCode",{parentName:"p"},"Workload")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories"),". The former revolves around the configuration for the computing resource. The latter represents any third-party runtime capabilities and operational requirements that the application needs. Each AppConfiguration consists of exactly one workload and any number of accessories."),(0,i.kt)("p",null,"Simply put, we can define ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," with the following expression:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"Components = Workload + Accessories")),(0,i.kt)("p",null,"The concept of ",(0,i.kt)("inlineCode",{parentName:"p"},"Components")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"Accessories")," itself is implicit when ",(0,i.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"authoring the configuration files"),". You can define the workload and any type of accessories (such as database or monitoring) directly under the AppConfiguration model."),(0,i.kt)("p",null,"From a collaboration perspective, platform developers and SREs are responsible for continuously adding any new schema (as abstractions for the underlying infrastructure) and implementations that can be used out-of-the-box. Application developers SREs should be able to leverage the corresponding schemas to cover the evolving application needs. This helps software organizations achieve separation of concern, so that different roles can focus on the subject matter they are an expert of."),(0,i.kt)("h4",{id:"pipeline"},"Pipeline"),(0,i.kt)("p",null,"In most of the cases, the platform is capable of providing a consistent application delivery process that can meet most application needs. In the case that an application warrants any customization in the delivery workflow, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Pipeline")," section in AppConfiguration provides an approach to extend the workflow as needed. "),(0,i.kt)("p",null,"A typical delivery workflow is made of several stages, each corresponds to some logic that needs to be executed, such as manual approval, data transfer, coordinated multi-cluster release, notification, etc. Implementation-wise, the execution of each stage should be carried out with a plugin, developed and managed by the platform owners."),(0,i.kt)("h4",{id:"topologies"},"Topologies"),(0,i.kt)("p",null,"In reality, what we have observed for production-grade applications is that they usually need to be deployed to a wide range of different targets including different clouds, regions, availability zones or runtimes for availability/cost/regulation/performance or disaster recovery related reasons. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Topologies")," section in AppConfiguration highlights the different deployment targets in the application delivery and provides a single pane of glass that overlooks the entire deployment topology."),(0,i.kt)("h4",{id:"policysets"},"PolicySets"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"PolicySets")," section is responsible for defining the set of rules and procedures that should be followed in the application delivery process. They generally represent the guidelines with the purpose of minimizing any technical, security or compliance risks. Some of examples include release strategies, risk management policies, and self-healing strategies. The collections of policies are expected to be managed as a joint effort from all the stakeholders, including platform owners, infrastructure owners, and security and compliance stakeholders. Some policy sets (usually security and compliance related) are expected to be mandatory. Some can be switched on and off by the application owner (self-healing strategy for instance) depending on their specific needs."),(0,i.kt)("h4",{id:"dependency"},"Dependency"),(0,i.kt)("p",null,"In a production-scale environment, there are usually intricate dependencies between multiple applications. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Dependency")," section is responsible for describing the dependencies between multiple applications."),(0,i.kt)("h2",{id:"references"},"References"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Score - ",(0,i.kt)("a",{parentName:"li",href:"https://docs.score.dev/docs/overview/"},"https://docs.score.dev/docs/overview/")),(0,i.kt)("li",{parentName:"ol"},"Acornfile - ",(0,i.kt)("a",{parentName:"li",href:"https://docs.acorn.io/authoring/overview"},"https://docs.acorn.io/authoring/overview")),(0,i.kt)("li",{parentName:"ol"},"KubeVela - ",(0,i.kt)("a",{parentName:"li",href:"https://kubevela.io/docs/getting-started/core-concept"},"https://kubevela.io/docs/getting-started/core-concept"))))}d.isMDXComponent=!0},57091:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/appconfig-6dd90bd8ff9307dc4e5f9b1553a52b29.png"}}]); \ No newline at end of file diff --git a/assets/js/ee68f9c5.3e3baacd.js b/assets/js/ee68f9c5.3e3baacd.js deleted file mode 100644 index 34d3751b6f6..00000000000 --- a/assets/js/ee68f9c5.3e3baacd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1094],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=r,f=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const o={sidebar_position:9},i="Operational Rules",l={unversionedId:"kusion/config-walkthrough/operational_rules",id:"version-v0.9/kusion/config-walkthrough/operational_rules",title:"Operational Rules",description:"The opsRule attribute in the AppConfiguration instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/operational_rules.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/operational_rules",permalink:"/docs/v0.9/kusion/config-walkthrough/operational_rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/operational_rules.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{sidebar_position:9},sidebar:"kusion",previous:{title:"Application Monitoring",permalink:"/docs/v0.9/kusion/config-walkthrough/monitoring"},next:{title:"User Guide",permalink:"/docs/v0.9/kusion/guides/"}},p={},s=[{value:"Import",id:"import",level:2},{value:"Max Unavailable Replicas",id:"max-unavailable-replicas",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"operational-rules"},"Operational Rules"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"opsRule")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"opsRules")," attribute requires the target cluster to have installed the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"KusionStack-operating")," controllers properly.")),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport models.schema.v1.trait as t\n")),(0,r.kt)("h2",{id:"max-unavailable-replicas"},"Max Unavailable Replicas"),(0,r.kt)("p",null,"Currently, ",(0,r.kt)("inlineCode",{parentName:"p"},"OpsRule")," supports setting a ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," parameter, which specifies the maximum number of pods that can be rendered unavailable at any time. It can be either a fraction of the total pods for the current application or a fixed number. This operational rule is particularly helpful against unexpected changes or deletes to the workloads. It can also prevents too many workloads from going down during an application upgrade."),(0,r.kt)("p",null,"More rules will be available in future versions of Kusion."),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a percentage of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a fixed number of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n opsRule: t.OpsRule {\n maxUnavailable: 2\n }\n}\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ee68f9c5.f701e4a5.js b/assets/js/ee68f9c5.f701e4a5.js new file mode 100644 index 00000000000..b96d8722840 --- /dev/null +++ b/assets/js/ee68f9c5.f701e4a5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1094],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=r,f=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const o={sidebar_position:9},i="Operational Rules",l={unversionedId:"kusion/config-walkthrough/operational_rules",id:"version-v0.9/kusion/config-walkthrough/operational_rules",title:"Operational Rules",description:"The opsRule attribute in the AppConfiguration instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/operational_rules.md",sourceDirName:"kusion/config-walkthrough",slug:"/kusion/config-walkthrough/operational_rules",permalink:"/docs/v0.9/kusion/config-walkthrough/operational_rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/config-walkthrough/operational_rules.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{sidebar_position:9},sidebar:"kusion",previous:{title:"Application Monitoring",permalink:"/docs/v0.9/kusion/config-walkthrough/monitoring"},next:{title:"User Guide",permalink:"/docs/v0.9/kusion/guides/"}},p={},s=[{value:"Import",id:"import",level:2},{value:"Max Unavailable Replicas",id:"max-unavailable-replicas",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"operational-rules"},"Operational Rules"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"opsRule")," attribute in the ",(0,r.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," instance is used to describe the specification for the collection of operational rule requirements for the application. Operational rules are used as a preemptive measure to police and stop any unwanted changes."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"opsRules")," attribute requires the target cluster to have installed the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"KusionStack-operating")," controllers properly.")),(0,r.kt)("h2",{id:"import"},"Import"),(0,r.kt)("p",null,"In the examples below, we are using schemas defined in the ",(0,r.kt)("inlineCode",{parentName:"p"},"catalog")," package. For more details on KCL package import, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"../config-walkthrough/overview"},"Configuration File Overview"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," statements needed for the following walkthrough:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport models.schema.v1.trait as t\n")),(0,r.kt)("h2",{id:"max-unavailable-replicas"},"Max Unavailable Replicas"),(0,r.kt)("p",null,"Currently, ",(0,r.kt)("inlineCode",{parentName:"p"},"OpsRule")," supports setting a ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," parameter, which specifies the maximum number of pods that can be rendered unavailable at any time. It can be either a fraction of the total pods for the current application or a fixed number. This operational rule is particularly helpful against unexpected changes or deletes to the workloads. It can also prevents too many workloads from going down during an application upgrade."),(0,r.kt)("p",null,"More rules will be available in future versions of Kusion."),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a percentage of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'myapp: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n # ...\n }\n }\n opsRule: t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,r.kt)("p",null,"To set ",(0,r.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," to a fixed number of pods:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"myapp: ac.AppConfiguration {\n workload: wl.Service {\n # ...\n }\n opsRule: t.OpsRule {\n maxUnavailable: 2\n }\n}\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ee6d0512.ab908c81.js b/assets/js/ee6d0512.1bc64518.js similarity index 81% rename from assets/js/ee6d0512.ab908c81.js rename to assets/js/ee6d0512.1bc64518.js index 4f92575bcc5..c3b337b81a1 100644 --- a/assets/js/ee6d0512.ab908c81.js +++ b/assets/js/ee6d0512.1bc64518.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2121],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),d=o,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},i="KCL",c={unversionedId:"kusion/faq/kcl",id:"kusion/faq/kcl",title:"KCL",description:"Visit the KCL website for more documents.",source:"@site/docs/kusion/7-faq/2-kcl.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/kcl",permalink:"/docs/next/kusion/faq/kcl",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/7-faq/2-kcl.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Installation",permalink:"/docs/next/kusion/faq/install-error"}},s={},l=[],u={toc:l};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kcl"},"KCL"),(0,o.kt)("p",null,"Visit the ",(0,o.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website")," for more documents."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2121],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=l(r),d=o,m=f["".concat(s,".").concat(d)]||f[d]||p[d]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:2},i="KCL",c={unversionedId:"kusion/faq/kcl",id:"kusion/faq/kcl",title:"KCL",description:"Visit the KCL website for more documents.",source:"@site/docs/kusion/7-faq/2-kcl.md",sourceDirName:"kusion/7-faq",slug:"/kusion/faq/kcl",permalink:"/docs/next/kusion/faq/kcl",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/7-faq/2-kcl.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"kusion",previous:{title:"Installation",permalink:"/docs/next/kusion/faq/install-error"}},s={},l=[],u={toc:l};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kcl"},"KCL"),(0,o.kt)("p",null,"Visit the ",(0,o.kt)("a",{parentName:"p",href:"https://kcl-lang.io/docs/user_docs/support/faq-kcl"},"KCL website")," for more documents."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f058aa3c.3e6113b2.js b/assets/js/f058aa3c.3e6113b2.js new file mode 100644 index 00000000000..63c45a8e9c4 --- /dev/null +++ b/assets/js/f058aa3c.3e6113b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5107],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},m=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),u=p(r),d=a,h=u["".concat(s,".").concat(d)]||u[d]||c[d]||o;return r?n.createElement(h,l(l({ref:t},m),{},{components:r})):n.createElement(h,l({ref:t},m))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=r(87462),a=(r(67294),r(3905));const o={},l="prometheus",i={unversionedId:"kusion/reference/model/catalog_models/monitoring/doc_prometheus",id:"version-v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus",title:"prometheus",description:"Schema Prometheus",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus.md",sourceDirName:"kusion/reference/model/catalog_models/monitoring",slug:"/kusion/reference/model/catalog_models/monitoring/doc_prometheus",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"database",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database"},next:{title:"opsrule",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule"}},s={},p=[{value:"Schema Prometheus",id:"schema-prometheus",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],m={toc:p};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prometheus"},"prometheus"),(0,a.kt)("h2",{id:"schema-prometheus"},"Schema Prometheus"),(0,a.kt)("p",null,"Prometheus can be used to define monitoring requirements"),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"interval"),(0,a.kt)("br",null),"The time interval which Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,a.kt)("br",null),"When operator mode is set to false, the scraping interval can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Prometheus global scraping interval, which should be 1m if not explicitly set"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"timeout"),(0,a.kt)("br",null),"The timeout when Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,a.kt)("br",null),"When operator mode is set to false, the scraping timeout can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Prometheus global scraping timeout, which should be 10s if not explicitly set"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"path"),(0,a.kt)("br",null),"The path to scrape metrics from."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Prometheus global scraping path, which should be /metrics if not explicitly set"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The port to scrape metrics from. When using Prometheus operator, this needs to be the port NAME. Otherwise, this can be a port name or a number."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Container ports when scraping pod (monitorType is pod); Service port when scraping service (monitorType is service)"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"scheme"),(0,a.kt)("br",null),"The scheme to scrape metrics from. Possible values are http and https."),(0,a.kt)("td",{parentName:"tr",align:null},'"http" ',"|",' "https"'),(0,a.kt)("td",{parentName:"tr",align:null},"http"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.monitoring as m\n\nmonitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f058aa3c.8ea5185c.js b/assets/js/f058aa3c.8ea5185c.js deleted file mode 100644 index 3343103e908..00000000000 --- a/assets/js/f058aa3c.8ea5185c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5107],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},m=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),u=p(r),d=a,h=u["".concat(s,".").concat(d)]||u[d]||c[d]||o;return r?n.createElement(h,l(l({ref:t},m),{},{components:r})):n.createElement(h,l({ref:t},m))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=u;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=r(87462),a=(r(67294),r(3905));const o={},l="prometheus",i={unversionedId:"kusion/reference/model/catalog_models/monitoring/doc_prometheus",id:"version-v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus",title:"prometheus",description:"Schema Prometheus",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus.md",sourceDirName:"kusion/reference/model/catalog_models/monitoring",slug:"/kusion/reference/model/catalog_models/monitoring/doc_prometheus",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"database",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database"},next:{title:"opsrule",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule"}},s={},p=[{value:"Schema Prometheus",id:"schema-prometheus",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],m={toc:p};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prometheus"},"prometheus"),(0,a.kt)("h2",{id:"schema-prometheus"},"Schema Prometheus"),(0,a.kt)("p",null,"Prometheus can be used to define monitoring requirements"),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"interval"),(0,a.kt)("br",null),"The time interval which Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,a.kt)("br",null),"When operator mode is set to false, the scraping interval can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Prometheus global scraping interval, which should be 1m if not explicitly set"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"timeout"),(0,a.kt)("br",null),"The timeout when Prometheus scrapes metrics data. Only applicable when operator mode is set to true.",(0,a.kt)("br",null),"When operator mode is set to false, the scraping timeout can only be set in the scraping job configuration, which kusion does not have permission to manage directly."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Prometheus global scraping timeout, which should be 10s if not explicitly set"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"path"),(0,a.kt)("br",null),"The path to scrape metrics from."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Prometheus global scraping path, which should be /metrics if not explicitly set"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"port"),(0,a.kt)("br",null),"The port to scrape metrics from. When using Prometheus operator, this needs to be the port NAME. Otherwise, this can be a port name or a number."),(0,a.kt)("td",{parentName:"tr",align:null},"str"),(0,a.kt)("td",{parentName:"tr",align:null},"Container ports when scraping pod (monitorType is pod); Service port when scraping service (monitorType is service)"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"scheme"),(0,a.kt)("br",null),"The scheme to scrape metrics from. Possible values are http and https."),(0,a.kt)("td",{parentName:"tr",align:null},'"http" ',"|",' "https"'),(0,a.kt)("td",{parentName:"tr",align:null},"http"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.monitoring as m\n\nmonitoring: m.Prometheus{\n interval: "30s"\n timeout: "15s"\n path: "/metrics"\n port: "web"\n scheme: "http"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f1e404ac.3e9d65b1.js b/assets/js/f1e404ac.481de01c.js similarity index 60% rename from assets/js/f1e404ac.3e9d65b1.js rename to assets/js/f1e404ac.481de01c.js index 2022abbb86e..7416d1582a6 100644 --- a/assets/js/f1e404ac.3e9d65b1.js +++ b/assets/js/f1e404ac.481de01c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1327],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),u=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=u(r),d=a,f=m["".concat(i,".").concat(d)]||m[d]||c[d]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,l[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",s={unversionedId:"kusion/reference/modules/catalog-models/trait/opsrule",id:"version-v0.10/kusion/reference/modules/catalog-models/trait/opsrule",title:"opsrule",description:"Schema OpsRule",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/trait",slug:"/kusion/reference/modules/catalog-models/trait/opsrule",permalink:"/docs/kusion/reference/modules/catalog-models/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"prometheus",permalink:"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus"},next:{title:"job",permalink:"/docs/kusion/reference/modules/catalog-models/workload/job"}},i={},u=[{value:"Schema OpsRule",id:"schema-opsrule",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("h2",{id:"schema-opsrule"},"Schema OpsRule"),(0,a.kt)("p",null,"OpsRule describes operation rules for various Day-2 Operations. Once declared, these",(0,a.kt)("br",null),"operation rules will be checked before any Day-2 operations."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},'"25%"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.trait as t\n\nopsRule : t.OpsRule {\n maxUnavailable: "30%"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1327],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),u=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=u(r),d=a,f=m["".concat(i,".").concat(d)]||m[d]||c[d]||o;return r?n.createElement(f,l(l({ref:t},p),{},{components:r})):n.createElement(f,l({ref:t},p))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,l[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={},l="opsrule",s={unversionedId:"kusion/reference/modules/catalog-models/trait/opsrule",id:"version-v0.10/kusion/reference/modules/catalog-models/trait/opsrule",title:"opsrule",description:"Schema OpsRule",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",sourceDirName:"kusion/6-reference/2-modules/1-catalog-models/trait",slug:"/kusion/reference/modules/catalog-models/trait/opsrule",permalink:"/docs/kusion/reference/modules/catalog-models/trait/opsrule",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"prometheus",permalink:"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus"},next:{title:"job",permalink:"/docs/kusion/reference/modules/catalog-models/workload/job"}},i={},u=[{value:"Schema OpsRule",id:"schema-opsrule",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"opsrule"},"opsrule"),(0,a.kt)("h2",{id:"schema-opsrule"},"Schema OpsRule"),(0,a.kt)("p",null,"OpsRule describes operation rules for various Day-2 Operations. Once declared, these",(0,a.kt)("br",null),"operation rules will be checked before any Day-2 operations."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"maxUnavailable"),(0,a.kt)("br",null),"The maximum percentage of the total pod instances in the component that can be",(0,a.kt)("br",null),"simultaneously unhealthy."),(0,a.kt)("td",{parentName:"tr",align:null},"int ","|"," str"),(0,a.kt)("td",{parentName:"tr",align:null},'"25%"'),(0,a.kt)("td",{parentName:"tr",align:null},"optional")))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.trait as t\n\nopsRule : t.OpsRule {\n maxUnavailable: "30%"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f34acb22.955acd7b.js b/assets/js/f34acb22.6b18f013.js similarity index 65% rename from assets/js/f34acb22.955acd7b.js rename to assets/js/f34acb22.6b18f013.js index 3b0f3bba4b4..cc6e73d2de0 100644 --- a/assets/js/f34acb22.955acd7b.js +++ b/assets/js/f34acb22.6b18f013.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1650],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>k});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},u=function(e){var n=c(e.components);return r.createElement(l.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=c(t),k=o,f=d["".concat(l,".").concat(k)]||d[k]||p[k]||i;return t?r.createElement(f,s(s({ref:n},u),{},{components:t})):r.createElement(f,s({ref:n},u))}));function k(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=d;var a={};for(var l in n)hasOwnProperty.call(n,l)&&(a[l]=n[l]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var r=t(87462),o=(t(67294),t(3905));const i={},s="kusion compile",a={unversionedId:"kusion/reference/cli/kusion/kusion_compile",id:"version-v0.9/kusion/reference/cli/kusion/kusion_compile",title:"kusion compile",description:"Deprecated: Use 'kusion build' to generate the Intent instead",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_compile.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_compile",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_compile.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion build",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_build"},next:{title:"kusion destroy",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy"}},l={},c=[{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 30-Nov-2023",id:"auto-generated-by-spf13cobra-on-30-nov-2023",level:6}],u={toc:c};function p(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-compile"},"kusion compile"),(0,o.kt)("p",null,"Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion compile [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," Deprecated\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for compile\n")),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-30-nov-2023"},"Auto generated by spf13/cobra on 30-Nov-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1650],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>k});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},u=function(e){var n=c(e.components);return r.createElement(l.Provider,{value:n},e.children)},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=c(t),k=o,f=d["".concat(l,".").concat(k)]||d[k]||p[k]||i;return t?r.createElement(f,s(s({ref:n},u),{},{components:t})):r.createElement(f,s({ref:n},u))}));function k(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=d;var a={};for(var l in n)hasOwnProperty.call(n,l)&&(a[l]=n[l]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var r=t(87462),o=(t(67294),t(3905));const i={},s="kusion compile",a={unversionedId:"kusion/reference/cli/kusion/kusion_compile",id:"version-v0.9/kusion/reference/cli/kusion/kusion_compile",title:"kusion compile",description:"Deprecated: Use 'kusion build' to generate the Intent instead",source:"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_compile.md",sourceDirName:"kusion/reference/cli/kusion",slug:"/kusion/reference/cli/kusion/kusion_compile",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_compile.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"kusion build",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_build"},next:{title:"kusion destroy",permalink:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy"}},l={},c=[{value:"Examples",id:"examples",level:3},{value:"Options",id:"options",level:3},{value:"SEE ALSO",id:"see-also",level:3},{value:"Auto generated by spf13/cobra on 30-Nov-2023",id:"auto-generated-by-spf13cobra-on-30-nov-2023",level:6}],u={toc:c};function p(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"kusion-compile"},"kusion compile"),(0,o.kt)("p",null,"Deprecated: Use 'kusion build' to generate the Intent instead"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"kusion compile [flags]\n")),(0,o.kt)("h3",{id:"examples"},"Examples"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," Deprecated\n")),(0,o.kt)("h3",{id:"options"},"Options"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}," -h, --help help for compile\n")),(0,o.kt)("h3",{id:"see-also"},"SEE ALSO"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v0.9/kusion/reference/cli/kusion/"},"kusion"),"\t - Kusion is the platform engineering engine of KusionStack")),(0,o.kt)("h6",{id:"auto-generated-by-spf13cobra-on-30-nov-2023"},"Auto generated by spf13/cobra on 30-Nov-2023"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f35beff3.291f9bb5.js b/assets/js/f35beff3.291f9bb5.js deleted file mode 100644 index a772268af00..00000000000 --- a/assets/js/f35beff3.291f9bb5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8039],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=i,k=d["".concat(p,".").concat(m)]||d[m]||c[m]||r;return n?a.createElement(k,o(o({ref:t},u),{},{components:n})):a.createElement(k,o({ref:t},u))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var a=n(87462),i=(n(67294),n(3905));const r={},o="Set up Operational Rules",l={unversionedId:"kusion/user-guides/working-with-k8s/set-up-operational-rules",id:"version-v0.10/kusion/user-guides/working-with-k8s/set-up-operational-rules",title:"Set up Operational Rules",description:"You can set up operational rules in the AppConfiguration model via the opsRule field and corresponding platform configurations in the workspace directory. The opsRule is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/set-up-operational-rules",permalink:"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Resource Specification",permalink:"/docs/kusion/user-guides/working-with-k8s/resource-spec"},next:{title:"Schedule a Job",permalink:"/docs/kusion/user-guides/working-with-k8s/job"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"set-up-operational-rules"},"Set up Operational Rules"),(0,i.kt)("p",null,"You can set up operational rules in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," field and corresponding platform configurations in the workspace directory. The ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the opsRule to standardize the behavior of applications, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"If the platform engineers have set the default workload to ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"Kusion Operation")," and installed the Kusion Operation controllers properly, the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRules")," module will generate a ",(0,i.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/podtransitionrule"},"PodTransitionRule")," instead of updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," value in the deployment")),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"Add the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," snippet to the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," in ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.trait as t\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n ...\n }\n # Configure the maxUnavailable rule\n opsRule = t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the application deployment strategy now has the updated attributes ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable: 30%")," in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl get deployment -n simple-service -o yaml\n...\napiVersion: apps/v1\n kind: Deployment\n...\n spec:\n strategy:\n rollingUpdate:\n maxUnavailable: 30%\n type: RollingUpdate\n\n...\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f35beff3.6d7affb8.js b/assets/js/f35beff3.6d7affb8.js new file mode 100644 index 00000000000..42fd832dc8c --- /dev/null +++ b/assets/js/f35beff3.6d7affb8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8039],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=i,k=d["".concat(p,".").concat(m)]||d[m]||c[m]||r;return n?a.createElement(k,o(o({ref:t},u),{},{components:n})):a.createElement(k,o({ref:t},u))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var a=n(87462),i=(n(67294),n(3905));const r={},o="Set up Operational Rules",l={unversionedId:"kusion/user-guides/working-with-k8s/set-up-operational-rules",id:"version-v0.10/kusion/user-guides/working-with-k8s/set-up-operational-rules",title:"Set up Operational Rules",description:"You can set up operational rules in the AppConfiguration model via the opsRule field and corresponding platform configurations in the workspace directory. The opsRule is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes.",source:"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",sourceDirName:"kusion/5-user-guides/2-working-with-k8s",slug:"/kusion/user-guides/working-with-k8s/set-up-operational-rules",permalink:"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:6,frontMatter:{},sidebar:"kusion",previous:{title:"Configure Resource Specification",permalink:"/docs/kusion/user-guides/working-with-k8s/resource-spec"},next:{title:"Schedule a Job",permalink:"/docs/kusion/user-guides/working-with-k8s/job"}},p={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Managing Workspace Configuration",id:"managing-workspace-configuration",level:2},{value:"Example",id:"example",level:2},{value:"Applying",id:"applying",level:2},{value:"Validation",id:"validation",level:2}],u={toc:s};function c(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"set-up-operational-rules"},"Set up Operational Rules"),(0,i.kt)("p",null,"You can set up operational rules in the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," model via the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," field and corresponding platform configurations in the workspace directory. The ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," is the collection of operational rule requirements for the application that are used as a preemptive measure to police and stop any unwanted changes."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"Please refer to the ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#prerequisites"},"prerequisites")," in the guide for deploying an application."),(0,i.kt)("p",null,"The example below also requires you to have ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing"},"initialized the project")," using the ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion workspace create")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"kusion init")," command, which will create a workspace and also generate a ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#kclmod"},(0,i.kt)("inlineCode",{parentName:"a"},"kcl.mod")," file")," under the stack directory."),(0,i.kt)("h2",{id:"managing-workspace-configuration"},"Managing Workspace Configuration"),(0,i.kt)("p",null,"In the first guide in this series, we introduced a step to ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#initializing-workspace-configuration"},"initialize a workspace")," with an empty configuration. The same empty configuration will still work in this guide, no changes are required there."),(0,i.kt)("p",null,"However, if you (or the platform team) would like to set default values for the opsRule to standardize the behavior of applications, you can do so by updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"~/dev.yaml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'modules:\n opsRule:\n default:\n maxUnavailable: "40%"\n')),(0,i.kt)("p",null,"Please note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," in the workspace configuration only works as a default value and will be overridden by the value set in the application configuration."),(0,i.kt)("p",null,"The workspace configuration need to be updated with the command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"kusion workspace update dev -f ~/dev.yaml\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"If the platform engineers have set the default workload to ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/operating"},"Kusion Operation")," and installed the Kusion Operation controllers properly, the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRules")," module will generate a ",(0,i.kt)("a",{parentName:"p",href:"https://www.kusionstack.io/docs/operating/manuals/podtransitionrule"},"PodTransitionRule")," instead of updating the ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable")," value in the deployment")),(0,i.kt)("h2",{id:"example"},"Example"),(0,i.kt)("p",null,"Add the ",(0,i.kt)("inlineCode",{parentName:"p"},"opsRule")," snippet to the ",(0,i.kt)("inlineCode",{parentName:"p"},"AppConfiguration")," in ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-service/dev/main.k"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-py"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.trait as t\n\nhelloworld: ac.AppConfiguration {\n workload: wl.Service {\n ...\n }\n # Configure the maxUnavailable rule\n opsRule = t.OpsRule {\n maxUnavailable: "30%"\n }\n}\n')),(0,i.kt)("h2",{id:"applying"},"Applying"),(0,i.kt)("p",null,"Re-run steps in ",(0,i.kt)("a",{parentName:"p",href:"deploy-application#applying"},"Applying"),", resource scaling is completed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"$ kusion apply\n\u2714\ufe0e Generating Intent in the Stack dev... \nStack: dev ID Action\n* \u251c\u2500 v1:Namespace:simple-service UnChanged\n* \u251c\u2500 v1:Service:simple-service:simple-service-dev-helloworld-private UnChanged\n* \u2514\u2500 apps/v1:Deployment:simple-service:simple-service-dev-helloworld Update\n\n\n? Do you want to apply these diffs? yes\nStart applying diffs ...\n SUCCESS UnChanged v1:Namespace:simple-service, skip \n SUCCESS UnChanged v1:Service:simple-service:simple-service-dev-helloworld-private, skip \n SUCCESS Update apps/v1:Deployment:simple-service:simple-service-dev-helloworld success \nUpdate apps/v1:Deployment:simple-service:simple-service-dev-helloworld success [3/3] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 100% | 0s\nApply complete! Resources: 0 created, 1 updated, 0 deleted.\n")),(0,i.kt)("h2",{id:"validation"},"Validation"),(0,i.kt)("p",null,"We can verify the application deployment strategy now has the updated attributes ",(0,i.kt)("inlineCode",{parentName:"p"},"maxUnavailable: 30%")," in the container configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-shell"},"kubectl get deployment -n simple-service -o yaml\n...\napiVersion: apps/v1\n kind: Deployment\n...\n spec:\n strategy:\n rollingUpdate:\n maxUnavailable: 30%\n type: RollingUpdate\n\n...\n")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f4eeafd2.4a8b45c3.js b/assets/js/f4eeafd2.fb43806c.js similarity index 82% rename from assets/js/f4eeafd2.4a8b45c3.js rename to assets/js/f4eeafd2.fb43806c.js index aef3f82ca5f..0a17e692fe0 100644 --- a/assets/js/f4eeafd2.4a8b45c3.js +++ b/assets/js/f4eeafd2.fb43806c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[588],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),u=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=u(n),f=o,g=d["".concat(c,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},l),{},{components:n})):r.createElement(g,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var r=n(87462),o=(n(67294),n(3905));const i={},a="Get Started",s={unversionedId:"kusion/getting-started/getting-started",id:"version-v0.9/kusion/getting-started/getting-started",title:"Get Started",description:"This section includes a quick overview of KusionStack and how to deploy a cloud-native app with it.",source:"@site/versioned_docs/version-v0.9/kusion/getting-started/getting-started.md",sourceDirName:"kusion/getting-started",slug:"/kusion/getting-started/",permalink:"/docs/v0.9/kusion/getting-started/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/getting-started/getting-started.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion vs. Other Software",permalink:"/docs/v0.9/kusion/intro/kusion-vs-x"},next:{title:"Install Kusion",permalink:"/docs/v0.9/kusion/getting-started/install-kusion"}},c={},u=[],l={toc:u};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"get-started"},"Get Started"),(0,o.kt)("p",null,"This section includes a quick overview of KusionStack and how to deploy a cloud-native app with it."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[588],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),u=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=u(n),f=o,g=d["".concat(c,".").concat(f)]||d[f]||p[f]||i;return n?r.createElement(g,a(a({ref:t},l),{},{components:n})):r.createElement(g,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,a[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var r=n(87462),o=(n(67294),n(3905));const i={},a="Get Started",s={unversionedId:"kusion/getting-started/getting-started",id:"version-v0.9/kusion/getting-started/getting-started",title:"Get Started",description:"This section includes a quick overview of KusionStack and how to deploy a cloud-native app with it.",source:"@site/versioned_docs/version-v0.9/kusion/getting-started/getting-started.md",sourceDirName:"kusion/getting-started",slug:"/kusion/getting-started/",permalink:"/docs/v0.9/kusion/getting-started/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/getting-started/getting-started.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"Kusion vs. Other Software",permalink:"/docs/v0.9/kusion/intro/kusion-vs-x"},next:{title:"Install Kusion",permalink:"/docs/v0.9/kusion/getting-started/install-kusion"}},c={},u=[],l={toc:u};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"get-started"},"Get Started"),(0,o.kt)("p",null,"This section includes a quick overview of KusionStack and how to deploy a cloud-native app with it."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f655a87f.5fbe324e.js b/assets/js/f655a87f.c0d72261.js similarity index 85% rename from assets/js/f655a87f.5fbe324e.js rename to assets/js/f655a87f.c0d72261.js index fabc1f94c10..d82e701a205 100644 --- a/assets/js/f655a87f.5fbe324e.js +++ b/assets/js/f655a87f.c0d72261.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8444],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=o,d=u["".concat(s,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,i(i({ref:t},p),{},{components:r})):n.createElement(d,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:1},i="FAQ",c={unversionedId:"ctrlmesh/faq/faq",id:"version-v0.9/ctrlmesh/faq/faq",title:"FAQ",description:"",source:"@site/versioned_docs/version-v0.9/ctrlmesh/faq/faq.md",sourceDirName:"ctrlmesh/faq",slug:"/ctrlmesh/faq/",permalink:"/docs/v0.9/ctrlmesh/faq/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/faq/faq.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Try a Sample",permalink:"/docs/v0.9/ctrlmesh/started/try"}},s={},l=[],p={toc:l};function f(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8444],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=o,d=u["".concat(s,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,i(i({ref:t},p),{},{components:r})):n.createElement(d,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={sidebar_position:1},i="FAQ",c={unversionedId:"ctrlmesh/faq/faq",id:"version-v0.9/ctrlmesh/faq/faq",title:"FAQ",description:"",source:"@site/versioned_docs/version-v0.9/ctrlmesh/faq/faq.md",sourceDirName:"ctrlmesh/faq",slug:"/ctrlmesh/faq/",permalink:"/docs/v0.9/ctrlmesh/faq/",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/ctrlmesh/faq/faq.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"ctrlmesh",previous:{title:"Try a Sample",permalink:"/docs/v0.9/ctrlmesh/started/try"}},s={},l=[],p={toc:l};function f(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"faq"},"FAQ"))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f7f2164e.081d3b09.js b/assets/js/f7f2164e.081d3b09.js deleted file mode 100644 index 39486caa827..00000000000 --- a/assets/js/f7f2164e.081d3b09.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9095],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=o.createContext({}),p=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=p(e.components);return o.createElement(l.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=p(t),m=a,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||r;return t?o.createElement(f,i(i({ref:n},u),{},{components:t})):o.createElement(f,i({ref:n},u))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,i=new Array(r);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var o=t(87462),a=(t(67294),t(3905));const r={id:"how-kusion-works",sidebar_label:"How Kusion Works?"},i="How Kusion Works?",s={unversionedId:"kusion/concepts/how-kusion-works",id:"kusion/concepts/how-kusion-works",title:"How Kusion Works?",description:"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Modules defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.",source:"@site/docs/kusion/3-concepts/9-how-kusion-works.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/how-kusion-works",permalink:"/docs/next/kusion/concepts/how-kusion-works",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/9-how-kusion-works.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{id:"how-kusion-works",sidebar_label:"How Kusion Works?"},sidebar:"kusion",previous:{title:"Configuration",permalink:"/docs/next/kusion/concepts/configuration"},next:{title:"Configuration File Overview",permalink:"/docs/next/kusion/configuration-walkthrough/overview"}},l={},p=[{value:"Overview",id:"overview",level:2},{value:"Platform Developer\u2019s Workflow",id:"platform-developers-workflow",level:2},{value:"Design Kusion Modules",id:"design-kusion-modules",level:3},{value:"Instantiate and Set Up Workspaces",id:"instantiate-and-set-up-workspaces",level:3},{value:"Application Developer\u2019s Workflow",id:"application-developers-workflow",level:2},{value:"Instantiate AppConfiguration and Apply",id:"instantiate-appconfiguration-and-apply",level:3}],u={toc:p};function c(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"how-kusion-works"},"How Kusion Works?"),(0,a.kt)("p",null,"Kusion is the platform engineering engine of ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack"},"KusionStack"),". It delivers intentions described with Kusion Modules defined in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," to Kubernetes, Clouds and On-Prem infrastructures."),(0,a.kt)("p",null,(0,a.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,a.kt)("h2",{id:"overview"},"Overview"),(0,a.kt)("p",null,"The workflow of KusionStack is illustrated in the diagram above, and it consists of three steps. The first step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Write"),", where platform engineers provide Kusion Modules and application developers write AppConfigurations based on the Kusion Modules to describe their operational intent."),(0,a.kt)("p",null,"The second step is the ",(0,a.kt)("inlineCode",{parentName:"p"},"Build")," process, which results in the creation of the SSoT (Single Source of Truth), also known as the ",(0,a.kt)("a",{parentName:"p",href:"intent"},"Intent")," of the current operational task. If you need version management of the SSoT, we recommend you manage the Intent with a VCS (Version Control System) tool like git."),(0,a.kt)("p",null,"The third step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Apply")," which makes the Intent effective. Kusion parses the operational intent based on the Intent produced in the previous step. Before applying the intent, Kusion will execute the Preview command (you can also execute this command manually) which will use a three-way diff algorithm to preview changes and prompt users to make sure all changes meet expectations; the Apply command will then actualize the operational intent onto various infrastructure platforms. Currently, it supports three runtimes: Terraform, Kubernetes, and on-prem infrastructures."),(0,a.kt)("p",null,"As a user of Kusion, if you prefer not to be conscious of so many steps, you can simply use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),", and Kusion will automatically execute all the aforementioned steps for you."),(0,a.kt)("h2",{id:"platform-developers-workflow"},"Platform Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"design-kusion-modules"},"Design Kusion Modules"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"kusion-module"},"Kusion Module")," is a reusable building block designed by platform engineers and contains two components: an application developer-oriented schema and a Kusion module generator. When platform engineers have developed a Kusion module, they can push it to a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," repository to make it into a KCL package."),(0,a.kt)("p",null,"Given a database Kusion module as an example, the schema definition is shown below and the generator logic can be found ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/pkg/modules/generators/accessories/database_generator.go"},"here"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'schema MySQL: \n """ MySQL describes the attributes to locally deploy or create a cloud provider\n managed mysql database instance for the workload. \n\n Attributes\n ----------\n type: "local" | "cloud", defaults to Undefined, required. \n Type defines whether the mysql database is deployed locally or provided by \n cloud vendor. \n version: str, defaults to Undefined, required. \n Version defines the mysql version to use. \n\n Examples\n --------\n Instantiate a local mysql database with version of 5.7. \n\n import models.schema.v1.accessories.mysql\n\n mysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n }\n """\n\n # The deployment mode of the mysql database. \n type: "local" | "cloud"\n\n # The mysql database version to use. \n version: str\n')),(0,a.kt)("h3",{id:"instantiate-and-set-up-workspaces"},"Instantiate and Set Up Workspaces"),(0,a.kt)("p",null,"Each ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," includes a corresponding Platform config file maintained by platform engineers.\nPlatform engineers should instantiate all workspaces and fulfill all fields with platform default values. Kusion will merge the workspace configuration with AppConfiguration in the Stack of the same name. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n # your kubeconfig file path\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n # metadat of used terraform providers\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\nmodules: \n # platform configuration of AWS RDS MySQL\n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," block represents a Kusion module. The fields inside are parts of the inputs for the Kusion module generator. For more details about the workspace, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," section."),(0,a.kt)("h2",{id:"application-developers-workflow"},"Application Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"instantiate-appconfiguration-and-apply"},"Instantiate AppConfiguration and Apply"),(0,a.kt)("p",null,"Application developers choose Kusion modules they need and instantiate them in the AppConfiguration to describe their operation intentions. We have built some built-in Kusion modules in the repository ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," and we warmly welcome you to join us in building this ecosystem together."),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," is the ",(0,a.kt)("strong",{parentName:"p"},"only")," configuration maintained by application developers and schemas in this file are defined from the application developer's perspective to reduce their cognitive load. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-pthyon"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n ......\n }\n }\n ......\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"workload")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"database")," are both Kusion modules provided by platform engineers and Kusion will convert them into actual infrastructure API calls eventually."),(0,a.kt)("p",null,"Finally, application developers can deliver their operational intent to infrastructures with one command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f7f2164e.9737060e.js b/assets/js/f7f2164e.9737060e.js new file mode 100644 index 00000000000..ebcaafe4e3c --- /dev/null +++ b/assets/js/f7f2164e.9737060e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9095],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>m});var o=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=o.createContext({}),p=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=p(e.components);return o.createElement(l.Provider,{value:n},e.children)},c={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=p(t),m=a,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||r;return t?o.createElement(f,i(i({ref:n},u),{},{components:t})):o.createElement(f,i({ref:n},u))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,i=new Array(r);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var p=2;p{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var o=t(87462),a=(t(67294),t(3905));const r={id:"how-kusion-works",sidebar_label:"How Kusion Works?"},i="How Kusion Works?",s={unversionedId:"kusion/concepts/how-kusion-works",id:"kusion/concepts/how-kusion-works",title:"How Kusion Works?",description:"Kusion is the platform engineering engine of KusionStack. It delivers intentions described with Kusion Modules defined in Catalog to Kubernetes, Clouds and On-Prem infrastructures.",source:"@site/docs/kusion/3-concepts/9-how-kusion-works.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/how-kusion-works",permalink:"/docs/next/kusion/concepts/how-kusion-works",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/9-how-kusion-works.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:9,frontMatter:{id:"how-kusion-works",sidebar_label:"How Kusion Works?"},sidebar:"kusion",previous:{title:"Configuration",permalink:"/docs/next/kusion/concepts/configuration"},next:{title:"Configuration File Overview",permalink:"/docs/next/kusion/configuration-walkthrough/overview"}},l={},p=[{value:"Overview",id:"overview",level:2},{value:"Platform Developer\u2019s Workflow",id:"platform-developers-workflow",level:2},{value:"Design Kusion Modules",id:"design-kusion-modules",level:3},{value:"Instantiate and Set Up Workspaces",id:"instantiate-and-set-up-workspaces",level:3},{value:"Application Developer\u2019s Workflow",id:"application-developers-workflow",level:2},{value:"Instantiate AppConfiguration and Apply",id:"instantiate-appconfiguration-and-apply",level:3}],u={toc:p};function c(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"how-kusion-works"},"How Kusion Works?"),(0,a.kt)("p",null,"Kusion is the platform engineering engine of ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack"},"KusionStack"),". It delivers intentions described with Kusion Modules defined in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," to Kubernetes, Clouds and On-Prem infrastructures."),(0,a.kt)("p",null,(0,a.kt)("img",{parentName:"p",src:"https://raw.githubusercontent.com/KusionStack/kusion/main/docs/workflow.png",alt:"arch"})),(0,a.kt)("h2",{id:"overview"},"Overview"),(0,a.kt)("p",null,"The workflow of KusionStack is illustrated in the diagram above, and it consists of three steps. The first step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Write"),", where platform engineers provide Kusion Modules and application developers write AppConfigurations based on the Kusion Modules to describe their operational intent."),(0,a.kt)("p",null,"The second step is the ",(0,a.kt)("inlineCode",{parentName:"p"},"Build")," process, which results in the creation of the SSoT (Single Source of Truth), also known as the ",(0,a.kt)("a",{parentName:"p",href:"intent"},"Intent")," of the current operational task. If you need version management of the SSoT, we recommend you manage the Intent with a VCS (Version Control System) tool like git."),(0,a.kt)("p",null,"The third step is ",(0,a.kt)("inlineCode",{parentName:"p"},"Apply")," which makes the Intent effective. Kusion parses the operational intent based on the Intent produced in the previous step. Before applying the intent, Kusion will execute the Preview command (you can also execute this command manually) which will use a three-way diff algorithm to preview changes and prompt users to make sure all changes meet expectations; the Apply command will then actualize the operational intent onto various infrastructure platforms. Currently, it supports three runtimes: Terraform, Kubernetes, and on-prem infrastructures."),(0,a.kt)("p",null,"As a user of Kusion, if you prefer not to be conscious of so many steps, you can simply use ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),", and Kusion will automatically execute all the aforementioned steps for you."),(0,a.kt)("h2",{id:"platform-developers-workflow"},"Platform Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"design-kusion-modules"},"Design Kusion Modules"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"kusion-module"},"Kusion Module")," is a reusable building block designed by platform engineers and contains two components: an application developer-oriented schema and a Kusion module generator. When platform engineers have developed a Kusion module, they can push it to a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"catalog")," repository to make it into a KCL package."),(0,a.kt)("p",null,"Given a database Kusion module as an example, the schema definition is shown below and the generator logic can be found ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/kusion/blob/main/pkg/modules/generators/accessories/database_generator.go"},"here"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'schema MySQL: \n """ MySQL describes the attributes to locally deploy or create a cloud provider\n managed mysql database instance for the workload. \n\n Attributes\n ----------\n type: "local" | "cloud", defaults to Undefined, required. \n Type defines whether the mysql database is deployed locally or provided by \n cloud vendor. \n version: str, defaults to Undefined, required. \n Version defines the mysql version to use. \n\n Examples\n --------\n Instantiate a local mysql database with version of 5.7. \n\n import models.schema.v1.accessories.mysql\n\n mysql: mysql.MySQL {\n type: "local"\n version: "5.7"\n }\n """\n\n # The deployment mode of the mysql database. \n type: "local" | "cloud"\n\n # The mysql database version to use. \n version: str\n')),(0,a.kt)("h3",{id:"instantiate-and-set-up-workspaces"},"Instantiate and Set Up Workspaces"),(0,a.kt)("p",null,"Each ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," includes a corresponding Platform config file maintained by platform engineers.\nPlatform engineers should instantiate all workspaces and fulfill all fields with platform default values. Kusion will merge the workspace configuration with AppConfiguration in the Stack of the same name. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'runtimes: \n # your kubeconfig file path\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n # metadat of used terraform providers\n terraform: \n random: \n version: 3.5.1\n source: hashicorp/random\n aws: \n version: 5.0.1\n source: hashicorp/aws\n region: us-east-1\n\nmodules: \n # platform configuration of AWS RDS MySQL\n mysql: \n default: \n cloud: aws\n size: 20\n instanceType: db.t3.micro\n privateRouting: false\n suffix: "-mysql"\n')),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"mysql")," block represents a Kusion module. The fields inside are parts of the inputs for the Kusion module generator. For more details about the workspace, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"workspace"},"workspace")," section."),(0,a.kt)("h2",{id:"application-developers-workflow"},"Application Developer\u2019s Workflow"),(0,a.kt)("h3",{id:"instantiate-appconfiguration-and-apply"},"Instantiate AppConfiguration and Apply"),(0,a.kt)("p",null,"Application developers choose Kusion modules they need and instantiate them in the AppConfiguration to describe their operation intentions. We have built some built-in Kusion modules in the repository ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/catalog"},"Catalog")," and we warmly welcome you to join us in building this ecosystem together."),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"main.k")," is the ",(0,a.kt)("strong",{parentName:"p"},"only")," configuration maintained by application developers and schemas in this file are defined from the application developer's perspective to reduce their cognitive load. An example is as follows."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-pthyon"},'import catalog.models.schema.v1 as ac\nimport catalog.models.schema.v1.workload as wl\nimport catalog.models.schema.v1.workload.container as c\nimport catalog.models.schema.v1.workload.network as n\nimport catalog.models.schema.v1.accessories.mysql\n\n# main.k declares customized configurations for dev stacks.\nwordpress: ac.AppConfiguration {\n workload: wl.Service {\n containers: {\n wordpress: c.Container {\n image: "wordpress:6.3"\n env: {\n "WORDPRESS_DB_HOST": "$(KUSION_DB_HOST_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_USER": "$(KUSION_DB_USERNAME_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_PASSWORD": "$(KUSION_DB_PASSWORD_WORDPRESS_MYSQL)"\n "WORDPRESS_DB_NAME": "mysql"\n }\n ......\n }\n }\n ......\n }\n database: {\n wordpress: mysql.MySQL {\n type: "cloud"\n version: "8.0"\n }\n }\n}\n')),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"workload")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"database")," are both Kusion modules provided by platform engineers and Kusion will convert them into actual infrastructure API calls eventually."),(0,a.kt)("p",null,"Finally, application developers can deliver their operational intent to infrastructures with one command ",(0,a.kt)("inlineCode",{parentName:"p"},"kusion apply"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f9476b7a.049b6102.js b/assets/js/f9476b7a.049b6102.js new file mode 100644 index 00000000000..68e07a4b3f1 --- /dev/null +++ b/assets/js/f9476b7a.049b6102.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8996],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=a.createContext({}),s=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return a.createElement(d.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,d=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=s(n),u=r,k=m["".concat(d,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,i(i({ref:t},p),{},{components:n})):a.createElement(k,i({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var s=2;s{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>c,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={},i="container",o={unversionedId:"kusion/reference/model/catalog_models/internal/container/doc_container",id:"version-v0.9/kusion/reference/model/catalog_models/internal/container/doc_container",title:"container",description:"Schema Container",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/doc_container.md",sourceDirName:"kusion/reference/model/catalog_models/internal/container",slug:"/kusion/reference/model/catalog_models/internal/container/doc_container",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/doc_container.md",tags:[],version:"v0.9",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule"},next:{title:"lifecycle",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle"}},d={},s=[{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3}],p={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"container"},"container"),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"probe/doc_probe#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"probe/doc_probe#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"probe/doc_probe#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"lifecycle/doc_lifecycle#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f9476b7a.add3b000.js b/assets/js/f9476b7a.add3b000.js deleted file mode 100644 index 758677d17bd..00000000000 --- a/assets/js/f9476b7a.add3b000.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8996],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=a.createContext({}),s=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return a.createElement(d.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,d=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=s(n),u=r,k=m["".concat(d,".").concat(u)]||m[u]||c[u]||l;return n?a.createElement(k,i(i({ref:t},p),{},{components:n})):a.createElement(k,i({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var s=2;s{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>c,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const l={},i="container",o={unversionedId:"kusion/reference/model/catalog_models/internal/container/doc_container",id:"version-v0.9/kusion/reference/model/catalog_models/internal/container/doc_container",title:"container",description:"Schema Container",source:"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/doc_container.md",sourceDirName:"kusion/reference/model/catalog_models/internal/container",slug:"/kusion/reference/model/catalog_models/internal/container/doc_container",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/doc_container.md",tags:[],version:"v0.9",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"opsrule",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule"},next:{title:"lifecycle",permalink:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle"}},d={},s=[{value:"Schema Container",id:"schema-container",level:2},{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3},{value:"Schema FileSpec",id:"schema-filespec",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"Examples",id:"examples-1",level:3}],p={toc:s};function c(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"container"},"container"),(0,r.kt)("h2",{id:"schema-container"},"Schema Container"),(0,r.kt)("p",null,"Container describes how the Application's tasks are expected to be run. Depending on",(0,r.kt)("br",null),"the replicas parameter 1 or more containers can be created from each template."),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"image"),(0,r.kt)("br",null),"Image refers to the Docker image name to run for this container.",(0,r.kt)("br",null),"More info: ",(0,r.kt)("a",{parentName:"td",href:"https://kubernetes.io/docs/concepts/containers/images"},"https://kubernetes.io/docs/concepts/containers/images")),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"command"),(0,r.kt)("br",null),"Entrypoint array. Not executed within a shell.",(0,r.kt)("br",null),"Command will overwrite the ENTRYPOINT value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's ENTRYPOINT is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"args"),(0,r.kt)("br",null),"Arguments to the entrypoint.",(0,r.kt)("br",null),"Args will overwrite the CMD value set in the Dockfile, otherwise the Docker",(0,r.kt)("br",null),"image's CMD is used if this is not provided."),(0,r.kt)("td",{parentName:"tr",align:null},"[str]"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"env"),(0,r.kt)("br",null),"List of environment variables to set in the container.",(0,r.kt)("br",null),"The value of the environment variable may be static text or a value from a secret."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"workingDir"),(0,r.kt)("br",null),"The working directory of the running process defined in entrypoint.",(0,r.kt)("br",null),"Default container runtime will be used if this is not specified."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"resources"),(0,r.kt)("br",null),"Map of resource requirements the container should run with.",(0,r.kt)("br",null),"The resources parameter is a dict with the key being the resource name and the value being",(0,r.kt)("br",null),"the resource value."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"files"),(0,r.kt)("br",null),"List of files to create in the container.",(0,r.kt)("br",null),"The files parameter is a dict with the key being the file name in the container and the value",(0,r.kt)("br",null),"being the target file specification."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: ",(0,r.kt)("a",{parentName:"td",href:"#schema-filespec"},"container.FileSpec"),"}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"dirs"),(0,r.kt)("br",null),"Collection of volumes mount into the container's filesystem.",(0,r.kt)("br",null),"The dirs parameter is a dict with the key being the folder name in the container and the value",(0,r.kt)("br",null),"being the referenced volume."),(0,r.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"livenessProbe"),(0,r.kt)("br",null),"LivenessProbe indicates if a running process is healthy.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"probe/doc_probe#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"readinessProbe"),(0,r.kt)("br",null),"ReadinessProbe indicates whether an application is available to handle requests."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"probe/doc_probe#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"startupProbe"),(0,r.kt)("br",null),"StartupProbe indicates that the container has started for the first time.",(0,r.kt)("br",null),"Container will be restarted if the probe fails."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"probe/doc_probe#schema-probe"},"p.Probe")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"lifecycle"),(0,r.kt)("br",null),"Lifecycle refers to actions that the management system should take in response to container lifecycle events."),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"lifecycle/doc_lifecycle#schema-lifecycle"},"lc.Lifecycle")),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\nweb = c.Container {\n image: "nginx:latest"\n command: ["/bin/sh", "-c", "echo hi"]\n env: {\n "name": "value"\n }\n resources: {\n "cpu": "2"\n "memory": "4Gi"\n }\n}\n')),(0,r.kt)("h2",{id:"schema-filespec"},"Schema FileSpec"),(0,r.kt)("p",null,"FileSpec defines the target file in a Container."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,r.kt)("th",{parentName:"tr",align:null},"Required"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"content"),(0,r.kt)("br",null),"File content in plain text."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"contentFrom"),(0,r.kt)("br",null),"Source for the file content, reference to a secret of configmap value."),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},"optional")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"mode"),(0,r.kt)("br",null),"Mode bits used to set permissions on this file, must be an octal value",(0,r.kt)("br",null),"between 0000 and 0777 or a decimal value between 0 and 511"),(0,r.kt)("td",{parentName:"tr",align:null},"str"),(0,r.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"td"},"required"))))),(0,r.kt)("h3",{id:"examples-1"},"Examples"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'import catalog.models.schema.v1.workload.container as c\n\ntmpFile = c.FileSpec {\n content: "some file contents"\n mode: "0777"\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fa47a47e.097ed95e.js b/assets/js/fa47a47e.097ed95e.js deleted file mode 100644 index 8f4567ab0e1..00000000000 --- a/assets/js/fa47a47e.097ed95e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1758],{3905:(e,n,a)=>{a.d(n,{Zo:()=>c,kt:()=>k});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function s(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var i=t.createContext({}),p=function(e){var n=t.useContext(i),a=n;return e&&(a="function"==typeof e?e(n):s(s({},n),e)),a},c=function(e){var n=p(e.components);return t.createElement(i.Provider,{value:n},e.children)},m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(a),k=o,d=u["".concat(i,".").concat(k)]||u[k]||m[k]||r;return a?t.createElement(d,s(s({ref:n},c),{},{components:a})):t.createElement(d,s({ref:n},c))}));function k(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=a.length,s=new Array(r);s[0]=u;var l={};for(var i in n)hasOwnProperty.call(n,i)&&(l[i]=n[i]);l.originalType=e,l.mdxType="string"==typeof e?e:o,s[1]=l;for(var p=2;p{a.r(n),a.d(n,{Highlight:()=>c,assets:()=>i,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),o=(a(67294),a(3905));const r={sidebar_position:4},s="Try a Sample",l={unversionedId:"ctrlmesh/started/try",id:"version-v0.10/ctrlmesh/started/try",title:"Try a Sample",description:"This guide lets you quickly evaluate KusionStack Controller Mesh.",source:"@site/versioned_docs/version-v0.10/ctrlmesh/started/try.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/try",permalink:"/docs/ctrlmesh/started/try",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/started/try.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"ctrlmesh",previous:{title:"Installation",permalink:"/docs/ctrlmesh/started/install"},next:{title:"FAQ",permalink:"/docs/ctrlmesh/faq/"}},i={},p=[{value:"Install Controller Mesh Manager",id:"install-controller-mesh-manager",level:2},{value:"Try with sample-operator",id:"try-with-sample-operator",level:2},{value:"Get and deploy sample-operator v0",id:"get-and-deploy-sample-operator-v0",level:3},{value:"Play with ShardingConfig",id:"play-with-shardingconfig",level:3},{value:"Clear sample resources",id:"clear-sample-resources",level:3},{value:"Try with Operating",id:"try-with-operating",level:2}],c=e=>{let{children:n,color:a}=e;return(0,o.kt)("span",{style:{backgroundColor:a,borderRadius:"5px",color:"#fff",padding:"0.1rem"}},n)},m={toc:p,Highlight:c};function u(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},m,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"try-a-sample"},"Try a Sample"),(0,o.kt)("p",null,"This guide lets you quickly evaluate KusionStack Controller Mesh. "),(0,o.kt)("h2",{id:"install-controller-mesh-manager"},"Install Controller Mesh Manager"),(0,o.kt)("p",null,"Controller Mesh requires ",(0,o.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Install with helm")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Firstly add KusionStack charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Wait manager ready\n$ kubectl -n ctrlmesh get po\nNAME READY STATUS RESTARTS AGE\nctrlmesh-57d6b4df57-mdslc 1/1 Running 0 40s\nctrlmesh-57d6b4df57-mtv2s 1/1 Running 0 40s\n")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"/docs/ctrlmesh/started/install"},"Install manager with more options")),(0,o.kt)("h2",{id:"try-with-sample-operator"},"Try with sample-operator"),(0,o.kt)("p",null,"Here is an example of a ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," enabling sharding."),(0,o.kt)("h3",{id:"get-and-deploy-sample-operator-v0"},"Get and deploy sample-operator v0"),(0,o.kt)("p",null,"\ud83d\udc49 ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/tree/sample-operator"},"sample-operator repo")," "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Clone and checkout branch sample-operator.\n$ git clone -b sample-operator https://github.com/KusionStack/controller-mesh.git\n$ cd sample\n\n# Make sure you have kind or test cluster, and kubectl is available.\n\n# Deploy default sample-operator v0.\n$ IMAGE_TAG=v0.1.0 make deploy\n\nnamespace/kusionstack-sample created\nserviceaccount/kusionstack-controller-manager created\nrole.rbac.authorization.k8s.io/kusionstack-leader-election-role created\nclusterrole.rbac.authorization.k8s.io/kusionstack-manager-role created\nrolebinding.rbac.authorization.k8s.io/kusionstack-leader-election-rolebinding created\nclusterrolebinding.rbac.authorization.k8s.io/kusionstack-sample-manager-rolebinding created\ndeployment.apps/kusionstack-sample-operator-v0 created\n\n# kusionstack-sample-operator-v0 is created.\n$ kubectl get deploy -n kusionstack-sample \nNAME READY UP-TO-DATE AVAILABLE AGE\nkusionstack-sample-operator-v0 2/2 2 2 14s\n\n$ kubectl get po -n kusionstack-sample \nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-66f7595c7b-n4c47 1/1 Running 0 50s\nkusionstack-sample-operator-v0-66f7595c7b-wxwtv 1/1 Running 0 50s\n\n# sample-operator uses leader-election. Only one leader pod reconciling.\n$ kubectl -n kusionstack-sample get lease \nNAME HOLDER AGE\nsample-operator-leader kusionstack-sample-operator-v0-66f7595c7b-wxwtv_c0ed684d-f332-47f6-890c-dd7e489486f2 53\n")),(0,o.kt)("h3",{id:"play-with-shardingconfig"},"Play with ShardingConfig"),(0,o.kt)("p",null,"By configuring ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig")," appropriately, you can achieve canary and sharding deploy."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Isolate canary namespaces")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Create some test namespaces([foo-01, foo-02, ..., foo-31]).\n$ chmod +x ./scripts/create-ns-foo.sh && ./scripts/create-ns-foo.sh\n\n# All namespaces are controlled by sample-operator v0.\n$ kubectl get ns -l sample.kusionstack.io/control-by=kusionstack-sample-operator-v0-66f7595c7b-wxwtv \nNAME STATUS AGE\ndefault Active 12d\nfoo-01 Active 78s\nfoo-02 Active 78s\nfoo-03 Active 78s\n... ... ...\nfoo-32 Active 78s\n\n# There are more details in leader pod log.\n$ kubectl logs kusionstack-sample-operator-v0-66f7595c7b-wxwtv -n kusionstack-sample | grep "hold namespaces"\nI0110 09:32:50.950535 1 runner.go:101] hold namespaces [ctrlmesh default foo-01 foo-02 foo-03 foo-04 foo-05 foo-06 foo-07 foo-08 foo-09 foo-10 foo-11 foo-12 foo-13 foo-14 foo-15 foo-16 foo-17 foo-18 foo-19 foo-20 foo-21 foo-22 foo-23 foo-24 foo-25 foo-26 foo-27 foo-28 foo-29 foo-30 foo-31 foo-32 kusionstack-sample kusionstack-system local-path-storage]\n\n# Apply sample ShardingConfigs\n$ ./bin/kustomize build config/shardingconfig/canary | kubectl apply -f -\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-0-canary created\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-1-normal created\n')),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-canary.yaml"},"kusionstack-sample-operator-0-canary")," has restricted the scope of namespaces ",(0,o.kt)(c,{color:"#A3B1A8",mdxType:"Highlight"},"[foo-01, foo-02, foo-03]")," reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v1"),".\nAnd ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-normal.yaml"},"kusionstack-sample-operator-1-normal")," decided that other namespaces will be reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Patch labels to pod template to inject sidecar and ShardingConfig\n$ kubectl -n kusionstack-sample patch deployment kusionstack-sample-operator-v0 --type=strategic --patch \\\n \'spec:\n template:\n metadata:\n labels:\n ctrlmesh.kusionstack.io/enable-proxy: "true"\n ctrlmesh.kusionstack.io/watching: "true"\'\n\n# Mesh proxy container was injected\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 30s\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 41s\n\n# Find current leader\n# sharding lease format: ${leader-election-name}---${shardingconfig-name}\n$ kubectl get lease -n kusionstack-sample\nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 32s\n\n# Namespaces [foo-1, foo-2, foo-3] are no longer under v0 control.\n$ kubectl logs kusionstack-sample-operator-v0-6944bb4bf5-lfwdb -c manager -n kusionstack-sample | grep "namespaces"\n ... hold namespaces [default foo-04 foo-05 ... foo-32]\n\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Deploy canary sample-operator v1")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Apply sample operator v1 which deployment already labeled\n$ ./bin/kustomize build config/manager-v1 | kubectl apply -f - \ndeployment.apps/kusionstack-sample-operator-v1 created\n\n# Two pods created\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 4m\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 4m\nkusionstack-sample-operator-v1-7b6bbb49c8-kbgww 0/2 ContainerCreating 0 3s\nkusionstack-sample-operator-v1-7b6bbb49c8-qbzjj 0/2 ContainerCreating 0 3s\n\n# The canary shard uses a separate lease\n$ kubectl get lease -n kusionstack-sample \nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-0-canary kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj_64272983-c59a-4574-933d-7d5fea7a1e35 15s\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 4m\n\n# Only foo-01, foo-02, foo-03 controlled by v1\n$ kubectl get ns -l sample.kusionstack.io/control-by=v1 -n kusionstack-sample\nNAME STATUS AGE\nfoo-01 Active 4m\nfoo-02 Active 4m\nfoo-03 Active 4m\n\n$ kubectl logs kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj -c manager -c kusionstack-sample| grep namespaces\n ... hold namespaces [foo-01 foo-02 foo-03]\n")),(0,o.kt)("p",null,"Similarly, if you want to have more shards, you need to do the following steps: "),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Extract a portion of the namespace from the existing ShardingConfigs."),(0,o.kt)("li",{parentName:"ol"},"Configure a new ShardingConfig and apply it."),(0,o.kt)("li",{parentName:"ol"},"Recreate or restart the existing pods to make the new ShardingConfig take effect."),(0,o.kt)("li",{parentName:"ol"},"Scale out the Pods for the new ShardingConfig.")),(0,o.kt)("h3",{id:"clear-sample-resources"},"Clear sample resources"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ chmod +x ./scripts/clear.sh && ./scripts/clear.sh\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("strong",{parentName:"p"},"Beta"),": ",(0,o.kt)("em",{parentName:"p"},"We try to support automatic sharding strategy. With automatic sharding configuration, there is no need to manually configure each shard's configuration. It manages multiple sub-shardingconfigs automatically through a root configuration."))),(0,o.kt)("h2",{id:"try-with-operating"},"Try with Operating"),(0,o.kt)("p",null,"For ",(0,o.kt)("inlineCode",{parentName:"p"},"StatefulSet")," case, you can use the ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("a",{parentName:"strong",href:"https://kusionstack.io/docs/operating/introduction/"},"Operating v0.1.1"))," available here."),(0,o.kt)("p",null,"Deploy the sample operator with ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm repo update\n$ helm install sample-operating kusionstack/operating \\\n --version v0.2.0 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true\n\n$ kubectl -n kusionstack-system get sts\nNAME READY AGE\nkusionstack-operating 5/5 1m45s\n\n# The proxy container will be automatically injected into the pod\n$ kubectl -n kusionstack-system get po\nNAME READY STATUS RESTARTS AGE\nkusionstack-operating-0 2/2 Running 0 42s\nkusionstack-operating-1 2/2 Running 0 32s\nkusionstack-operating-2 2/2 Running 0 21s\nkusionstack-operating-3 2/2 Running 0 12s\nkusionstack-operating-4 0/2 ContainerCreating 0 1s\n\n# Now we have three shards with three lease.\n# operating-0-canary -> [kusionstack-operating-0]\n# operating-1-normal -> [kusionstack-operating-1, kusionstack-operating-2]\n# operating-2-normal -> [kusionstack-operating-3, kusionstack-operating-4]\n$ kubectl -n kusionstack-system get lease\nNAME HOLDER AGE\nkusionstack-controller-manager---operating-0-canary kusionstack-operating-0_81b5bbae-be63-45ed-a939-e67e0c3d6326 12m\nkusionstack-controller-manager---operating-1-normal kusionstack-operating-1_e4bbad49-e6ec-42fa-8ffd-caae82156a3e 12m\nkusionstack-controller-manager---operating-2-normal kusionstack-operating-3_94f7f81a-f9e6-47d6-b72b-e16da479e9be 12m\n")),(0,o.kt)("p",null," Show the sample ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm template sample-operating kusionstack/operating \\\n --version v0.1.1 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true \\\n --show-only templates/shardingconfig.yaml\n")),(0,o.kt)("p",null,"Here is a sample ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="operating/templates/shardingconfig.yaml"',title:'"operating/templates/shardingconfig.yaml"'},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-root\n namespace: kusionstack-system\nspec:\n # Auto sharding config\n root:\n prefix: operating\n targetStatefulSet: kusionstack-operating\n canary:\n replicas: 1\n inNamespaces:\n - kusionstack-system\n auto:\n everyShardReplicas: 2\n shardingSize: 2\n resourceSelector:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - configmaps\n - pods\n - endpoints\n - services\n - replicasets\n - apiGroups:\n - apps.kusionstack.io\n resources:\n - '*'\n controller:\n leaderElectionName: kusionstack-controller-manager\n")),(0,o.kt)("p",null,"You can configure the ShardingConfig according to your requirements."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In order to enable the ShardingConfig, you also need to add the following label to the pod template.",(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/watching: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/enable-proxy: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n","We plan to deprecate it in future versions.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fa47a47e.c61f88d3.js b/assets/js/fa47a47e.c61f88d3.js new file mode 100644 index 00000000000..1d32e57fabd --- /dev/null +++ b/assets/js/fa47a47e.c61f88d3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1758],{3905:(e,n,a)=>{a.d(n,{Zo:()=>c,kt:()=>k});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function s(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var i=t.createContext({}),p=function(e){var n=t.useContext(i),a=n;return e&&(a="function"==typeof e?e(n):s(s({},n),e)),a},c=function(e){var n=p(e.components);return t.createElement(i.Provider,{value:n},e.children)},m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(a),k=o,d=u["".concat(i,".").concat(k)]||u[k]||m[k]||r;return a?t.createElement(d,s(s({ref:n},c),{},{components:a})):t.createElement(d,s({ref:n},c))}));function k(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=a.length,s=new Array(r);s[0]=u;var l={};for(var i in n)hasOwnProperty.call(n,i)&&(l[i]=n[i]);l.originalType=e,l.mdxType="string"==typeof e?e:o,s[1]=l;for(var p=2;p{a.r(n),a.d(n,{Highlight:()=>c,assets:()=>i,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var t=a(87462),o=(a(67294),a(3905));const r={sidebar_position:4},s="Try a Sample",l={unversionedId:"ctrlmesh/started/try",id:"version-v0.10/ctrlmesh/started/try",title:"Try a Sample",description:"This guide lets you quickly evaluate KusionStack Controller Mesh.",source:"@site/versioned_docs/version-v0.10/ctrlmesh/started/try.md",sourceDirName:"ctrlmesh/started",slug:"/ctrlmesh/started/try",permalink:"/docs/ctrlmesh/started/try",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/ctrlmesh/started/try.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"ctrlmesh",previous:{title:"Installation",permalink:"/docs/ctrlmesh/started/install"},next:{title:"FAQ",permalink:"/docs/ctrlmesh/faq/"}},i={},p=[{value:"Install Controller Mesh Manager",id:"install-controller-mesh-manager",level:2},{value:"Try with sample-operator",id:"try-with-sample-operator",level:2},{value:"Get and deploy sample-operator v0",id:"get-and-deploy-sample-operator-v0",level:3},{value:"Play with ShardingConfig",id:"play-with-shardingconfig",level:3},{value:"Clear sample resources",id:"clear-sample-resources",level:3},{value:"Try with Operating",id:"try-with-operating",level:2}],c=e=>{let{children:n,color:a}=e;return(0,o.kt)("span",{style:{backgroundColor:a,borderRadius:"5px",color:"#fff",padding:"0.1rem"}},n)},m={toc:p,Highlight:c};function u(e){let{components:n,...a}=e;return(0,o.kt)("wrapper",(0,t.Z)({},m,a,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"try-a-sample"},"Try a Sample"),(0,o.kt)("p",null,"This guide lets you quickly evaluate KusionStack Controller Mesh. "),(0,o.kt)("h2",{id:"install-controller-mesh-manager"},"Install Controller Mesh Manager"),(0,o.kt)("p",null,"Controller Mesh requires ",(0,o.kt)("strong",{parentName:"p"},"Kubernetes version >= 1.18")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Install with helm")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Firstly add KusionStack charts repository if you haven't do this.\n$ helm repo add kusionstack https://kusionstack.github.io/charts\n\n# To update the kusionstack repo.\n$ helm repo update kusionstack\n\n# Install the latest version.\n$ helm install ctrlmesh kusionstack/ctrlmesh\n\n# Wait manager ready\n$ kubectl -n ctrlmesh get po\nNAME READY STATUS RESTARTS AGE\nctrlmesh-57d6b4df57-mdslc 1/1 Running 0 40s\nctrlmesh-57d6b4df57-mtv2s 1/1 Running 0 40s\n")),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"/docs/ctrlmesh/started/install"},"Install manager with more options")),(0,o.kt)("h2",{id:"try-with-sample-operator"},"Try with sample-operator"),(0,o.kt)("p",null,"Here is an example of a ",(0,o.kt)("inlineCode",{parentName:"p"},"Deployment")," enabling sharding."),(0,o.kt)("h3",{id:"get-and-deploy-sample-operator-v0"},"Get and deploy sample-operator v0"),(0,o.kt)("p",null,"\ud83d\udc49 ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/tree/sample-operator"},"sample-operator repo")," "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Clone and checkout branch sample-operator.\n$ git clone -b sample-operator https://github.com/KusionStack/controller-mesh.git\n$ cd sample\n\n# Make sure you have kind or test cluster, and kubectl is available.\n\n# Deploy default sample-operator v0.\n$ IMAGE_TAG=v0.1.0 make deploy\n\nnamespace/kusionstack-sample created\nserviceaccount/kusionstack-controller-manager created\nrole.rbac.authorization.k8s.io/kusionstack-leader-election-role created\nclusterrole.rbac.authorization.k8s.io/kusionstack-manager-role created\nrolebinding.rbac.authorization.k8s.io/kusionstack-leader-election-rolebinding created\nclusterrolebinding.rbac.authorization.k8s.io/kusionstack-sample-manager-rolebinding created\ndeployment.apps/kusionstack-sample-operator-v0 created\n\n# kusionstack-sample-operator-v0 is created.\n$ kubectl get deploy -n kusionstack-sample \nNAME READY UP-TO-DATE AVAILABLE AGE\nkusionstack-sample-operator-v0 2/2 2 2 14s\n\n$ kubectl get po -n kusionstack-sample \nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-66f7595c7b-n4c47 1/1 Running 0 50s\nkusionstack-sample-operator-v0-66f7595c7b-wxwtv 1/1 Running 0 50s\n\n# sample-operator uses leader-election. Only one leader pod reconciling.\n$ kubectl -n kusionstack-sample get lease \nNAME HOLDER AGE\nsample-operator-leader kusionstack-sample-operator-v0-66f7595c7b-wxwtv_c0ed684d-f332-47f6-890c-dd7e489486f2 53\n")),(0,o.kt)("h3",{id:"play-with-shardingconfig"},"Play with ShardingConfig"),(0,o.kt)("p",null,"By configuring ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig")," appropriately, you can achieve canary and sharding deploy."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Isolate canary namespaces")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Create some test namespaces([foo-01, foo-02, ..., foo-31]).\n$ chmod +x ./scripts/create-ns-foo.sh && ./scripts/create-ns-foo.sh\n\n# All namespaces are controlled by sample-operator v0.\n$ kubectl get ns -l sample.kusionstack.io/control-by=kusionstack-sample-operator-v0-66f7595c7b-wxwtv \nNAME STATUS AGE\ndefault Active 12d\nfoo-01 Active 78s\nfoo-02 Active 78s\nfoo-03 Active 78s\n... ... ...\nfoo-32 Active 78s\n\n# There are more details in leader pod log.\n$ kubectl logs kusionstack-sample-operator-v0-66f7595c7b-wxwtv -n kusionstack-sample | grep "hold namespaces"\nI0110 09:32:50.950535 1 runner.go:101] hold namespaces [ctrlmesh default foo-01 foo-02 foo-03 foo-04 foo-05 foo-06 foo-07 foo-08 foo-09 foo-10 foo-11 foo-12 foo-13 foo-14 foo-15 foo-16 foo-17 foo-18 foo-19 foo-20 foo-21 foo-22 foo-23 foo-24 foo-25 foo-26 foo-27 foo-28 foo-29 foo-30 foo-31 foo-32 kusionstack-sample kusionstack-system local-path-storage]\n\n# Apply sample ShardingConfigs\n$ ./bin/kustomize build config/shardingconfig/canary | kubectl apply -f -\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-0-canary created\nshardingconfig.ctrlmesh.kusionstack.io/kusionstack-sample-operator-1-normal created\n')),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-canary.yaml"},"kusionstack-sample-operator-0-canary")," has restricted the scope of namespaces ",(0,o.kt)(c,{color:"#A3B1A8",mdxType:"Highlight"},"[foo-01, foo-02, foo-03]")," reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v1"),".\nAnd ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/KusionStack/controller-mesh/blob/sample-operator/sample/config/shardingconfig/canary/shardingconfig-normal.yaml"},"kusionstack-sample-operator-1-normal")," decided that other namespaces will be reconciled by version ",(0,o.kt)("inlineCode",{parentName:"p"},"v0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'# Patch labels to pod template to inject sidecar and ShardingConfig\n$ kubectl -n kusionstack-sample patch deployment kusionstack-sample-operator-v0 --type=strategic --patch \\\n \'spec:\n template:\n metadata:\n labels:\n ctrlmesh.kusionstack.io/enable-proxy: "true"\n ctrlmesh.kusionstack.io/watching: "true"\'\n\n# Mesh proxy container was injected\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 30s\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 41s\n\n# Find current leader\n# sharding lease format: ${leader-election-name}---${shardingconfig-name}\n$ kubectl get lease -n kusionstack-sample\nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 32s\n\n# Namespaces [foo-1, foo-2, foo-3] are no longer under v0 control.\n$ kubectl logs kusionstack-sample-operator-v0-6944bb4bf5-lfwdb -c manager -n kusionstack-sample | grep "namespaces"\n ... hold namespaces [default foo-04 foo-05 ... foo-32]\n\n')),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Deploy canary sample-operator v1")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"# Apply sample operator v1 which deployment already labeled\n$ ./bin/kustomize build config/manager-v1 | kubectl apply -f - \ndeployment.apps/kusionstack-sample-operator-v1 created\n\n# Two pods created\n$ kubectl get po -n kusionstack-sample\nNAME READY STATUS RESTARTS AGE\nkusionstack-sample-operator-v0-6944bb4bf5-gclqq 2/2 Running 0 4m\nkusionstack-sample-operator-v0-6944bb4bf5-lfwdb 2/2 Running 0 4m\nkusionstack-sample-operator-v1-7b6bbb49c8-kbgww 0/2 ContainerCreating 0 3s\nkusionstack-sample-operator-v1-7b6bbb49c8-qbzjj 0/2 ContainerCreating 0 3s\n\n# The canary shard uses a separate lease\n$ kubectl get lease -n kusionstack-sample \nNAME HOLDER AGE\nsample-operator-leader---kusionstack-sample-operator-0-canary kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj_64272983-c59a-4574-933d-7d5fea7a1e35 15s\nsample-operator-leader---kusionstack-sample-operator-1-normal kusionstack-sample-operator-v0-6944bb4bf5-lfwdb_497a7962-a5f1-465e-b8ef-6e35660c63f4 4m\n\n# Only foo-01, foo-02, foo-03 controlled by v1\n$ kubectl get ns -l sample.kusionstack.io/control-by=v1 -n kusionstack-sample\nNAME STATUS AGE\nfoo-01 Active 4m\nfoo-02 Active 4m\nfoo-03 Active 4m\n\n$ kubectl logs kusionstack-sample-operator-v1-7b6bbb49c8-qbzjj -c manager -c kusionstack-sample| grep namespaces\n ... hold namespaces [foo-01 foo-02 foo-03]\n")),(0,o.kt)("p",null,"Similarly, if you want to have more shards, you need to do the following steps: "),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Extract a portion of the namespace from the existing ShardingConfigs."),(0,o.kt)("li",{parentName:"ol"},"Configure a new ShardingConfig and apply it."),(0,o.kt)("li",{parentName:"ol"},"Recreate or restart the existing pods to make the new ShardingConfig take effect."),(0,o.kt)("li",{parentName:"ol"},"Scale out the Pods for the new ShardingConfig.")),(0,o.kt)("h3",{id:"clear-sample-resources"},"Clear sample resources"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ chmod +x ./scripts/clear.sh && ./scripts/clear.sh\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},(0,o.kt)("strong",{parentName:"p"},"Beta"),": ",(0,o.kt)("em",{parentName:"p"},"We try to support automatic sharding strategy. With automatic sharding configuration, there is no need to manually configure each shard's configuration. It manages multiple sub-shardingconfigs automatically through a root configuration."))),(0,o.kt)("h2",{id:"try-with-operating"},"Try with Operating"),(0,o.kt)("p",null,"For ",(0,o.kt)("inlineCode",{parentName:"p"},"StatefulSet")," case, you can use the ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("a",{parentName:"strong",href:"https://kusionstack.io/docs/operating/introduction/"},"Operating v0.1.1"))," available here."),(0,o.kt)("p",null,"Deploy the sample operator with ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm repo update\n$ helm install sample-operating kusionstack/operating \\\n --version v0.2.0 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true\n\n$ kubectl -n kusionstack-system get sts\nNAME READY AGE\nkusionstack-operating 5/5 1m45s\n\n# The proxy container will be automatically injected into the pod\n$ kubectl -n kusionstack-system get po\nNAME READY STATUS RESTARTS AGE\nkusionstack-operating-0 2/2 Running 0 42s\nkusionstack-operating-1 2/2 Running 0 32s\nkusionstack-operating-2 2/2 Running 0 21s\nkusionstack-operating-3 2/2 Running 0 12s\nkusionstack-operating-4 0/2 ContainerCreating 0 1s\n\n# Now we have three shards with three lease.\n# operating-0-canary -> [kusionstack-operating-0]\n# operating-1-normal -> [kusionstack-operating-1, kusionstack-operating-2]\n# operating-2-normal -> [kusionstack-operating-3, kusionstack-operating-4]\n$ kubectl -n kusionstack-system get lease\nNAME HOLDER AGE\nkusionstack-controller-manager---operating-0-canary kusionstack-operating-0_81b5bbae-be63-45ed-a939-e67e0c3d6326 12m\nkusionstack-controller-manager---operating-1-normal kusionstack-operating-1_e4bbad49-e6ec-42fa-8ffd-caae82156a3e 12m\nkusionstack-controller-manager---operating-2-normal kusionstack-operating-3_94f7f81a-f9e6-47d6-b72b-e16da479e9be 12m\n")),(0,o.kt)("p",null," Show the sample ShardingConfig:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"$ helm template sample-operating kusionstack/operating \\\n --version v0.1.1 \\\n --set sharding.enabled=true \\\n --set sharding.isDemo=true \\\n --show-only templates/shardingconfig.yaml\n")),(0,o.kt)("p",null,"Here is a sample ",(0,o.kt)("inlineCode",{parentName:"p"},"ShardingConfig"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="operating/templates/shardingconfig.yaml"',title:'"operating/templates/shardingconfig.yaml"'},"apiVersion: ctrlmesh.kusionstack.io/v1alpha1\nkind: ShardingConfig\nmetadata:\n name: sharding-root\n namespace: kusionstack-system\nspec:\n # Auto sharding config\n root:\n prefix: operating\n targetStatefulSet: kusionstack-operating\n canary:\n replicas: 1\n inNamespaces:\n - kusionstack-system\n auto:\n everyShardReplicas: 2\n shardingSize: 2\n resourceSelector:\n - relateResources:\n - apiGroups:\n - '*'\n resources:\n - configmaps\n - pods\n - endpoints\n - services\n - replicasets\n - apiGroups:\n - apps.kusionstack.io\n resources:\n - '*'\n controller:\n leaderElectionName: kusionstack-controller-manager\n")),(0,o.kt)("p",null,"You can configure the ShardingConfig according to your requirements."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In order to enable the ShardingConfig, you also need to add the following label to the pod template.",(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/watching: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("inlineCode",{parentName:"p"},"ctrlmesh.kusionstack.io/enable-proxy: 'true'"),(0,o.kt)("br",{parentName:"p"}),"\n","We plan to deprecate it in future versions.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fd1fdd14.01b0b155.js b/assets/js/fd1fdd14.01b0b155.js new file mode 100644 index 00000000000..1b31cca2fd7 --- /dev/null +++ b/assets/js/fd1fdd14.01b0b155.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3438],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(t),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(f,i(i({ref:n},p),{},{components:t})):a.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=t.length,i=new Array(r);i[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var a=t(87462),o=(t(67294),t(3905));const r={},i="Workspace",s={unversionedId:"kusion/concepts/workspace",id:"kusion/concepts/workspace",title:"Workspace",description:"Definition",source:"@site/docs/kusion/3-concepts/4-workspace.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/workspace",permalink:"/docs/next/kusion/concepts/workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/4-workspace.md",tags:[],version:"current",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Module",permalink:"/docs/next/kusion/concepts/kusion-module"},next:{title:"AppConfiguration",permalink:"/docs/next/kusion/concepts/app-configuration"}},l={},c=[{value:"Definition",id:"definition",level:2},{value:"Structure",id:"structure",level:2},{value:"Workflow",id:"workflow",level:2}],p={toc:c};function d(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"workspace"},"Workspace"),(0,o.kt)("h2",{id:"definition"},"Definition"),(0,o.kt)("p",null,"A workspace is a logical concept that represents a target environment for deploying a stack. It contains platform configurations, including a set of configurations, Kubeconfig, and provider authentication information, all of which can be reused by multiple stacks. We recommend organizing workspaces by SDLC (Software Development Life Cycle) phases or by cloud vendors. For example, workspaces could be named ",(0,o.kt)("inlineCode",{parentName:"p"},"dev"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"staging"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"prod"),", or according to cloud vendors such as ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Azure"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"Alibaba Cloud"),"."),(0,o.kt)("p",null,"For clarity, workspace data is categorized into two types: configuration and secret. The configuration data is non-sensitive and is stored locally in YAML files, including module inputs, runtime configurations, and backend configurations. The secret data is sensitive and should be stored as workspace variables. For example, when using AWS, users must set the correct workspace variables for ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_ACCESS_KEY_ID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_SECRET_ACCESS_KEY"),"."),(0,o.kt)("p",null,"If a set of data items serves the same target and contains one or more sensitive data items, then the entire set should be managed using environment variables. This approach ensures a consistent and seamless user experience."),(0,o.kt)("p",null,"Each stack must be associated with a single workspace, and ",(0,o.kt)("strong",{parentName:"p"},"the stack's name must be the same as the workspace it will be deployed to"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"workspace-project-stack",src:t(27137).Z,width:"587",height:"362"})),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In product design, Kusion does not support deploying to multiple clouds or multiple regions within a single workspace. While users can technically define a module that provisions resources across multiple clouds or regions, Kusion does not recommend this practice and will not provide technical support for such configurations. If a platform team needs to manage resources across multiple clouds or regions, they should create separate workspaces.")),(0,o.kt)("h2",{id:"structure"},"Structure"),(0,o.kt)("p",null,"The configuration of a workspace is stored in a single YAML file, which consists of three components: ",(0,o.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"backends"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"module")," configuration comprises default configs and several patchers, where the name of each patcher must not be ",(0,o.kt)("strong",{parentName:"p"},"default"),". Configurations in the ",(0,o.kt)("inlineCode",{parentName:"p"},"default")," block will be applied to all applications in this workspace and configurations in the patcher block will only be applied to projects in the ",(0,o.kt)("inlineCode",{parentName:"p"},"projectSelector"),". Values in patchers will override default configs with the same field name.\nFor the default configuration or a specific patcher, field keys must be the same as module input field names defined by the module. Module configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/modules"},"Kusion Modules")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime")," configuration currently supports Kubernetes and Terraform, where the former includes the field ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeConfig")," to specify the path of Kube Config, and the latter contains data for Terraform providers, which vary across different providers. For Terraform providers, sensitive data should be stored in environment variables."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"backend")," configuration currently supports local, oss, s3, database, and http. This defines the backend for state, intent, and other Kusion data that may require storage in the future. This format requires that all Kusion data share the same backend. As with sensitive data in the runtime configuration, these details should also be stored in environment variables. Backend configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"backend"},"Backend")),(0,o.kt)("p",null,"An example is shown as below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# Module input, each with the format standard\uff1a\n# # :\n# # default: # default configurations, applied to all projects\n# # : \n# # : \n# # ...\n# # : #patcher configurations, applied to the projects assigned in projectSelector\n# # : \n# # ...\n# # projectSelector:\n# # - \n# # ...\nmodules:\n database:\n default:\n provider: aws\n size: 20\n instanceClass: db.t3.micro\n securityIPs:\n - 10.0.0.0/18\n smallClass:\n size: 50\n instanceClass: db.t3.small\n projectSelector:\n - foo\n - bar\n largeClass:\n instanceClass: db.t3.large\n projectSelector:\n - baz\n \n# A set of runtime configs, each with the format standard:\n# # :\n# # : \n# # : \n# # ...\nruntimes:\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n terraform:\n aws:\n version: 1.0.4\n source: hashicorp/aws\n region: us-east-1\n \n# A set of backend configs, each with the following format standard:\n# # :\n# # : \n# # : \n# # ...\nbackends:\n s3: \n bucket: kusion\n region: us-east-1\n")),(0,o.kt)("h2",{id:"workflow"},"Workflow"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Write the ",(0,o.kt)("inlineCode",{parentName:"li"},"workspace.yaml")," with the format shown above and fulfill all necessary fields."),(0,o.kt)("li",{parentName:"ol"},"Create a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce create -f "),"\nA new workspace configuration file named ",(0,o.kt)("inlineCode",{parentName:"li"},".yaml")," will be created under the path ",(0,o.kt)("inlineCode",{parentName:"li"},"$KUSION_PATH/.workspace"),", and the validation will be done before the creation."),(0,o.kt)("li",{parentName:"ol"},"Update a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce update -f "),"\nThe workspace will be updated with the latest values."),(0,o.kt)("li",{parentName:"ol"},"Delete a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion workspace delete ")," if you don't need it anymore.")),(0,o.kt)("p",null,"More workspace commands can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands/kusion-workspace"},"reference"),"."))}d.isMDXComponent=!0},27137:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/workspace-project-stack-35aa4e25ab80fe4a1a6bbfbbe024e127.png"}}]); \ No newline at end of file diff --git a/assets/js/fd1fdd14.915e24d2.js b/assets/js/fd1fdd14.915e24d2.js deleted file mode 100644 index d5252039699..00000000000 --- a/assets/js/fd1fdd14.915e24d2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3438],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(t),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||r;return t?a.createElement(f,i(i({ref:n},p),{},{components:t})):a.createElement(f,i({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=t.length,i=new Array(r);i[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var a=t(87462),o=(t(67294),t(3905));const r={},i="Workspace",s={unversionedId:"kusion/concepts/workspace",id:"kusion/concepts/workspace",title:"Workspace",description:"Definition",source:"@site/docs/kusion/3-concepts/4-workspace.md",sourceDirName:"kusion/3-concepts",slug:"/kusion/concepts/workspace",permalink:"/docs/next/kusion/concepts/workspace",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/docs/kusion/3-concepts/4-workspace.md",tags:[],version:"current",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",sidebarPosition:4,frontMatter:{},sidebar:"kusion",previous:{title:"Kusion Module",permalink:"/docs/next/kusion/concepts/kusion-module"},next:{title:"AppConfiguration",permalink:"/docs/next/kusion/concepts/app-configuration"}},l={},c=[{value:"Definition",id:"definition",level:2},{value:"Structure",id:"structure",level:2},{value:"Workflow",id:"workflow",level:2}],p={toc:c};function d(e){let{components:n,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"workspace"},"Workspace"),(0,o.kt)("h2",{id:"definition"},"Definition"),(0,o.kt)("p",null,"A workspace is a logical concept that represents a target environment for deploying a stack. It contains platform configurations, including a set of configurations, Kubeconfig, and provider authentication information, all of which can be reused by multiple stacks. We recommend organizing workspaces by SDLC (Software Development Life Cycle) phases or by cloud vendors. For example, workspaces could be named ",(0,o.kt)("inlineCode",{parentName:"p"},"dev"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"staging"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"prod"),", or according to cloud vendors such as ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Azure"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"Alibaba Cloud"),"."),(0,o.kt)("p",null,"For clarity, workspace data is categorized into two types: configuration and secret. The configuration data is non-sensitive and is stored locally in YAML files, including module inputs, runtime configurations, and backend configurations. The secret data is sensitive and should be stored as workspace variables. For example, when using AWS, users must set the correct workspace variables for ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_ACCESS_KEY_ID")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"AWS_SECRET_ACCESS_KEY"),"."),(0,o.kt)("p",null,"If a set of data items serves the same target and contains one or more sensitive data items, then the entire set should be managed using environment variables. This approach ensures a consistent and seamless user experience."),(0,o.kt)("p",null,"Each stack must be associated with a single workspace, and ",(0,o.kt)("strong",{parentName:"p"},"the stack's name must be the same as the workspace it will be deployed to"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"workspace-project-stack",src:t(27137).Z,width:"587",height:"362"})),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In product design, Kusion does not support deploying to multiple clouds or multiple regions within a single workspace. While users can technically define a module that provisions resources across multiple clouds or regions, Kusion does not recommend this practice and will not provide technical support for such configurations. If a platform team needs to manage resources across multiple clouds or regions, they should create separate workspaces.")),(0,o.kt)("h2",{id:"structure"},"Structure"),(0,o.kt)("p",null,"The configuration of a workspace is stored in a single YAML file, which consists of three components: ",(0,o.kt)("inlineCode",{parentName:"p"},"modules"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"runtimes"),", and ",(0,o.kt)("inlineCode",{parentName:"p"},"backends"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"module")," configuration comprises default configs and several patchers, where the name of each patcher must not be ",(0,o.kt)("strong",{parentName:"p"},"default"),". Configurations in the ",(0,o.kt)("inlineCode",{parentName:"p"},"default")," block will be applied to all applications in this workspace and configurations in the patcher block will only be applied to projects in the ",(0,o.kt)("inlineCode",{parentName:"p"},"projectSelector"),". Values in patchers will override default configs with the same field name.\nFor the default configuration or a specific patcher, field keys must be the same as module input field names defined by the module. Module configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/modules"},"Kusion Modules")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"runtime")," configuration currently supports Kubernetes and Terraform, where the former includes the field ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeConfig")," to specify the path of Kube Config, and the latter contains data for Terraform providers, which vary across different providers. For Terraform providers, sensitive data should be stored in environment variables."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"backend")," configuration currently supports local, oss, s3, database, and http. This defines the backend for state, intent, and other Kusion data that may require storage in the future. This format requires that all Kusion data share the same backend. As with sensitive data in the runtime configuration, these details should also be stored in environment variables. Backend configurations can be found in the ",(0,o.kt)("a",{parentName:"p",href:"backend-configuration"},"Backend Configuration")),(0,o.kt)("p",null,"An example is shown as below:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yaml"},"# Module input, each with the format standard\uff1a\n# # :\n# # default: # default configurations, applied to all projects\n# # : \n# # : \n# # ...\n# # : #patcher configurations, applied to the projects assigned in projectSelector\n# # : \n# # ...\n# # projectSelector:\n# # - \n# # ...\nmodules:\n database:\n default:\n provider: aws\n size: 20\n instanceClass: db.t3.micro\n securityIPs:\n - 10.0.0.0/18\n smallClass:\n size: 50\n instanceClass: db.t3.small\n projectSelector:\n - foo\n - bar\n largeClass:\n instanceClass: db.t3.large\n projectSelector:\n - baz\n \n# A set of runtime configs, each with the format standard:\n# # :\n# # : \n# # : \n# # ...\nruntimes:\n kubernetes:\n kubeConfig: /etc/kubeconfig.yaml\n terraform:\n aws:\n version: 1.0.4\n source: hashicorp/aws\n region: us-east-1\n \n# A set of backend configs, each with the following format standard:\n# # :\n# # : \n# # : \n# # ...\nbackends:\n s3: \n bucket: kusion\n region: us-east-1\n")),(0,o.kt)("h2",{id:"workflow"},"Workflow"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Write the ",(0,o.kt)("inlineCode",{parentName:"li"},"workspace.yaml")," with the format shown above and fulfill all necessary fields."),(0,o.kt)("li",{parentName:"ol"},"Create a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce create -f "),"\nA new workspace configuration file named ",(0,o.kt)("inlineCode",{parentName:"li"},".yaml")," will be created under the path ",(0,o.kt)("inlineCode",{parentName:"li"},"$KUSION_PATH/.workspace"),", and the validation will be done before the creation."),(0,o.kt)("li",{parentName:"ol"},"Update a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion worksapce update -f "),"\nThe workspace will be updated with the latest values."),(0,o.kt)("li",{parentName:"ol"},"Delete a workspace with ",(0,o.kt)("inlineCode",{parentName:"li"},"kusion workspace delete ")," if you don't need it anymore.")),(0,o.kt)("p",null,"More workspace commands can be found in the ",(0,o.kt)("a",{parentName:"p",href:"../reference/commands/kusion-workspace"},"reference"),"."))}d.isMDXComponent=!0},27137:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/workspace-project-stack-35aa4e25ab80fe4a1a6bbfbbe024e127.png"}}]); \ No newline at end of file diff --git a/assets/js/fdecbe36.4346cf95.js b/assets/js/fdecbe36.0de627fd.js similarity index 50% rename from assets/js/fdecbe36.4346cf95.js rename to assets/js/fdecbe36.0de627fd.js index ba141f0f12f..9494bef7890 100644 --- a/assets/js/fdecbe36.4346cf95.js +++ b/assets/js/fdecbe36.0de627fd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2403],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="service",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/service",id:"version-v0.10/kusion/reference/modules/workspace-configs/workload/service",title:"service",description:"service can be used to define workspace-level service configuration.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/service",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",tags:[],version:"v0.10",lastUpdatedBy:"Forest",lastUpdatedAt:1711596556,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/job"},next:{title:"Resource Naming Conventions",permalink:"/docs/kusion/reference/modules/naming-conventions"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"service"},"service"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"service")," can be used to define workspace-level service configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,a.kt)("br",null),"types, including Deployment and CollaSet."),(0,a.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2403],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,k=d["".concat(s,".").concat(m)]||d[m]||u[m]||o;return n?r.createElement(k,l(l({ref:t},p),{},{components:n})):r.createElement(k,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={},l="service",i={unversionedId:"kusion/reference/modules/workspace-configs/workload/service",id:"version-v0.10/kusion/reference/modules/workspace-configs/workload/service",title:"service",description:"service can be used to define workspace-level service configuration.",source:"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",sourceDirName:"kusion/6-reference/2-modules/2-workspace-configs/workload",slug:"/kusion/reference/modules/workspace-configs/workload/service",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/service",draft:!1,editUrl:"https://github.com/KusionStack/kusionstack.io/blob/main/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",tags:[],version:"v0.10",lastUpdatedBy:"KK",lastUpdatedAt:1711598094,formattedLastUpdatedAt:"Mar 28, 2024",frontMatter:{},sidebar:"kusion",previous:{title:"job",permalink:"/docs/kusion/reference/modules/workspace-configs/workload/job"},next:{title:"Resource Naming Conventions",permalink:"/docs/kusion/reference/modules/naming-conventions"}},s={},c=[{value:"Attributes",id:"attributes",level:3},{value:"Examples",id:"examples",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"service"},"service"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"service")," can be used to define workspace-level service configuration."),(0,a.kt)("h3",{id:"attributes"},"Attributes"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Name and Description"),(0,a.kt)("th",{parentName:"tr",align:null},"Type"),(0,a.kt)("th",{parentName:"tr",align:null},"Default Value"),(0,a.kt)("th",{parentName:"tr",align:null},"Required"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"replicas"),(0,a.kt)("br",null),"Number of container replicas based on this configuration that should be ran."),(0,a.kt)("td",{parentName:"tr",align:null},"int"),(0,a.kt)("td",{parentName:"tr",align:null},"2"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"labels"),(0,a.kt)("br",null),"Labels are key/value pairs that are attached to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"annotations"),(0,a.kt)("br",null),"Annotations are key/value pairs that attach arbitrary non-identifying metadata to the workload."),(0,a.kt)("td",{parentName:"tr",align:null},"{str: str}"),(0,a.kt)("td",{parentName:"tr",align:null},"Undefined"),(0,a.kt)("td",{parentName:"tr",align:null},"optional")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"type"),(0,a.kt)("br",null),"Type represents the type of workload used by this Service. Currently, it supports several",(0,a.kt)("br",null),"types, including Deployment and CollaSet."),(0,a.kt)("td",{parentName:"tr",align:null},'"Deployment" ',"|",' "CollaSet"'),(0,a.kt)("td",{parentName:"tr",align:null},"Deployment"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("strong",{parentName:"td"},"required"))))),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},"modules:\n service:\n default:\n replicas: 3\n labels:\n label-key: label-value\n annotations:\n annotation-key: annotation-value\n type: CollaSet\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.3e823d7e.js b/assets/js/main.3e823d7e.js new file mode 100644 index 00000000000..ebe9f167f79 --- /dev/null +++ b/assets/js/main.3e823d7e.js @@ -0,0 +1,2 @@ +/*! For license information please see main.3e823d7e.js.LICENSE.txt */ +(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[179],{20830:(e,n,t)=>{"use strict";t.d(n,{W:()=>r});var o=t(67294);function r(){return o.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},o.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},38726:(e,n,t)=>{"use strict";function o(e,n){e.prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n}function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n{"use strict";t.d(n,{Z:()=>f});var o=t(67294),r=t(87462),i=t(38726),a=t.n(i),s=t(16887);const c={"00ba420c":[()=>t.e(2170).then(t.t.bind(t,31911,19)),"~blog/default/blog-tags-kusion-page-4-da4-list.json",31911],"01a85c17":[()=>Promise.all([t.e(532),t.e(4013)]).then(t.bind(t,91223)),"@theme/BlogTagsListPage",91223],"03c33ea8":[()=>t.e(8230).then(t.bind(t,84123)),"@site/versioned_docs/version-v0.9/kusion/getting-started/deliver-wordpress.md",84123],"043680c6":[()=>t.e(1753).then(t.bind(t,50404)),"@site/docs/kusion/4-configuration-walkthrough/7-secret.md",50404],"048ed126":[()=>t.e(4368).then(t.bind(t,93778)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",93778],"051b6848":[()=>t.e(1160).then(t.t.bind(t,32936,19)),"~blog/default/blog-tags-kusion-stack-1cb-list.json",32936],"05939e2b":[()=>t.e(1258).then(t.bind(t,42476)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-init.md",42476],"05e2121e":[()=>t.e(1750).then(t.bind(t,56245)),"@site/docs/kusion/6-reference/1-commands/kusion-version.md",56245],"06519e08":[()=>t.e(6910).then(t.bind(t,55248)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",55248],"073cf144":[()=>Promise.all([t.e(532),t.e(7340)]).then(t.bind(t,38087)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/1-database.md",38087],"084f87c9":[()=>t.e(6318).then(t.bind(t,60884)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/1-project/1-overview.md",60884],"091a426a":[()=>Promise.all([t.e(532),t.e(3334)]).then(t.bind(t,45413)),"@site/docs/kusion/5-user-guides/1-cloud-resources/1-database.md",45413],"09b7d7e1":[()=>t.e(3617).then(t.bind(t,23860)),"@site/versioned_docs/version-v0.9/kusion/reference/model/project-stack-config-items.md",23860],"0a185701":[()=>t.e(535).then(t.bind(t,32937)),"@site/docs/kusion/3-concepts/7-backend.md",32937],"0b745da3":[()=>t.e(5498).then(t.bind(t,82429)),"@site/docs/kusion/4-configuration-walkthrough/9-operational-rules.md",82429],"0bf91782":[()=>t.e(4206).then(t.bind(t,41790)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",41790],"0dc90373":[()=>t.e(181).then(t.bind(t,87813)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_job.md",87813],"0e7cda11":[()=>t.e(6852).then(t.bind(t,57994)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/4-workload.md",57994],"0f1fb433":[()=>t.e(1721).then(t.bind(t,58687)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",58687],"0f9ab0f2":[()=>t.e(3129).then(t.bind(t,13781)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/doc_common.md",13781],"104b2cd6":[()=>t.e(2673).then(t.bind(t,34735)),"@site/blog/2021-05-18-kusion-intro/index.md?truncated=true",34735],"1133e639":[()=>t.e(2494).then(t.bind(t,4076)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-apply.md",4076],"11ce4159":[()=>t.e(1531).then(t.t.bind(t,75034,19)),"~blog/default/blog-page-5-c6b.json",75034],"145f4e6a":[()=>t.e(7665).then(t.bind(t,92013)),"@site/blog/2022-12-12-post-cloud-native-era-operation/index.md",92013],"1759e3b3":[()=>t.e(1711).then(t.bind(t,14673)),"@site/versioned_docs/version-v0.10/kusion/1-what-is-kusion/2-kusion-vs-x.md",14673],17896441:[()=>Promise.all([t.e(532),t.e(8718),t.e(7918)]).then(t.bind(t,74458)),"@theme/DocItem",74458],"17b56dd8":[()=>t.e(2687).then(t.bind(t,36213)),"@site/versioned_docs/version-v0.10/ctrlmesh/intro/intro.md",36213],"1835c74b":[()=>t.e(7113).then(t.bind(t,2296)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",2296],"1898401f":[()=>t.e(9366).then(t.bind(t,26292)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/overview.md",26292],"1961a063":[()=>t.e(8025).then(t.bind(t,73161)),"@site/docs/kusion/4-configuration-walkthrough/4-workload.md",73161],"1977b36b":[()=>t.e(5434).then(t.bind(t,45017)),"@site/versioned_docs/version-v0.10/ctrlmesh/started/install.md",45017],"19d6fa9a":[()=>t.e(6987).then(t.bind(t,9875)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",9875],"19fdd558":[()=>t.e(1061).then(t.bind(t,38420)),"@site/versioned_docs/version-v0.9/kusion/support/support.md",38420],"1a4e3797":[()=>Promise.all([t.e(532),t.e(7920)]).then(t.bind(t,39172)),"@theme/SearchPage",39172],"1a5f5579":[()=>t.e(2253).then(t.bind(t,82539)),"@site/versioned_docs/version-v0.9/community/intro/intro.md",82539],"1aa0cc2e":[()=>t.e(38).then(t.bind(t,37242)),"@site/docs/kusion/5-user-guides/2-working-with-k8s/1-deploy-application.md",37242],"1aea322a":[()=>t.e(8686).then(t.bind(t,96305)),"@site/versioned_docs/version-v0.9/operating/started/install.md",96305],"1b99e815":[()=>t.e(9516).then(t.bind(t,11162)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-show.md",11162],"1be78505":[()=>Promise.all([t.e(532),t.e(9514)]).then(t.bind(t,19963)),"@theme/DocPage",19963],"1c549a2d":[()=>t.e(2717).then(t.bind(t,49581)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",49581],"1f391b9e":[()=>Promise.all([t.e(532),t.e(8718),t.e(3085)]).then(t.bind(t,14247)),"@theme/MDXPage",14247],"1fe9451f":[()=>t.e(3897).then(t.bind(t,97145)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",97145],"20d5d8d7":[()=>t.e(5101).then(t.bind(t,71466)),"@site/versioned_docs/version-v0.10/operating/started/demo-graceful-operation.md",71466],"2115f1af":[()=>t.e(8989).then(t.bind(t,93390)),"@site/docs/kusion/6-reference/1-commands/kusion-workspace-update.md",93390],"22cda74c":[()=>t.e(9394).then(t.bind(t,53670)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",53670],"2353ab8e":[()=>t.e(4919).then(t.bind(t,14690)),"@site/versioned_docs/version-v0.10/operating/manuals/podtransitionrule.md",14690],"235dd62f":[()=>t.e(362).then(t.t.bind(t,22042,19)),"~blog/default/blog-tags-kclvm-31a.json",22042],"237b575e":[()=>t.e(4599).then(t.bind(t,68922)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",68922],"23bbb932":[()=>t.e(5856).then(t.bind(t,2019)),"@site/versioned_docs/version-v0.10/kusion/6-reference/3-roadmap.md",2019],"26acf368":[()=>t.e(7858).then(t.t.bind(t,65052,19)),"~blog/default/blog-tags-large-scale-0df.json",65052],"26fe9297":[()=>t.e(192).then(t.bind(t,33943)),"@site/versioned_docs/version-v0.9/kusion/guides/cloud-resources/expose-service.md",33943],"28005ec6":[()=>t.e(858).then(t.bind(t,45091)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/secret/secret.md",45091],"281e8991":[()=>t.e(4960).then(t.bind(t,79157)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/4-workspace.md",79157],"287f5fa1":[()=>t.e(159).then(t.bind(t,34663)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-delete.md",34663],"28de08e8":[()=>t.e(9533).then(t.bind(t,25618)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",25618],"2b4be8fd":[()=>t.e(3449).then(t.bind(t,18768)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/common.md",18768],"2e98070f":[()=>t.e(1164).then(t.bind(t,38330)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/monitoring.md",38330],"2e999f74":[()=>t.e(9470).then(t.bind(t,78406)),"@site/docs/ctrlmesh/started/try.md",78406],"30546e72":[()=>t.e(9809).then(t.bind(t,27838)),"@site/versioned_docs/version-v0.9/ctrlmesh/started/install.md",27838],"305bace7":[()=>t.e(3241).then(t.bind(t,40598)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/1-overview.md",40598],"31b6193b":[()=>t.e(18).then(t.t.bind(t,65139,19)),"~docs/default/version-v-0-10-metadata-prop-b87.json",65139],32000204:[()=>t.e(6138).then(t.bind(t,14589)),"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/1-deploy-application.md",14589],"32956a74":[()=>t.e(2842).then(t.bind(t,55054)),"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/database/mysql.md",55054],"33052e91":[()=>t.e(8901).then(t.bind(t,10547)),"@site/blog/2023-05-26-qcon-guangzhou/index.md",10547],"33c8bfc8":[()=>t.e(3232).then(t.bind(t,64814)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",64814],"34bf352d":[()=>t.e(5391).then(t.bind(t,75626)),"@site/docs/kusion/3-concepts/3-kusion-module.md",75626],"3536e8ef":[()=>t.e(5690).then(t.bind(t,98689)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",98689],"35b126a7":[()=>t.e(1322).then(t.t.bind(t,41888,19)),"~blog/default/blog-tags-kusion-stack-page-4-3a4.json",41888],"3712c5a4":[()=>t.e(6817).then(t.bind(t,49759)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle.md",49759],"3715f14e":[()=>t.e(8742).then(t.bind(t,69272)),"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/trait/opsrule.md",69272],"376ee327":[()=>Promise.all([t.e(532),t.e(4652)]).then(t.bind(t,50655)),"@site/versioned_docs/version-v0.9/kusion/getting-started/install-kusion.md",50655],"37badd01":[()=>t.e(884).then(t.bind(t,8752)),"@site/versioned_docs/version-v0.10/operating/manuals/collaset.md",8752],"393be207":[()=>t.e(7414).then(t.bind(t,53123)),"@site/src/pages/markdown-page.md",53123],"39a759e2":[()=>Promise.all([t.e(532),t.e(6478)]).then(t.bind(t,48514)),"@site/versioned_docs/version-v0.10/kusion/2-getting-started/1-install-kusion.md",48514],"3a980746":[()=>t.e(4371).then(t.bind(t,97540)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/database/mysql.md",97540],"3b1f5c9a":[()=>t.e(9328).then(t.bind(t,83894)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",83894],"3ba9be36":[()=>t.e(3407).then(t.bind(t,57371)),"@site/versioned_docs/version-v0.9/kusion/reference/roadmap.md",57371],"3bda864c":[()=>t.e(93).then(t.bind(t,82816)),"@site/versioned_docs/version-v0.10/operating/started/install.md",82816],"3c3bc024":[()=>t.e(617).then(t.bind(t,30972)),"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",30972],"3d3b6af8":[()=>t.e(9691).then(t.bind(t,51194)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/5-appconfiguration.md",51194],"3de240dc":[()=>t.e(6791).then(t.bind(t,13183)),"@site/docs/ctrlmesh/intro/intro.md",13183],"4032a3e5":[()=>t.e(9450).then(t.bind(t,67100)),"@site/docs/operating/started/install.md",67100],"407e1392":[()=>t.e(8119).then(t.bind(t,54150)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/database/doc_database.md",54150],"434d80d9":[()=>t.e(1132).then(t.bind(t,13703)),"@site/docs/kusion/6-reference/1-commands/kusion-preview.md",13703],"43b9b491":[()=>t.e(9190).then(t.t.bind(t,39784,19)),"~blog/default/blog-tags-kusion-page-3-d9b-list.json",39784],"43d0ee92":[()=>t.e(5466).then(t.bind(t,9992)),"@site/blog/2021-05-18-kusion-intro/index.md",9992],"4406c285":[()=>t.e(4360).then(t.bind(t,61340)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule.md",61340],"44a7a3de":[()=>Promise.all([t.e(532),t.e(5911)]).then(t.bind(t,58748)),"@site/docs/kusion/2-getting-started/1-install-kusion.md",58748],"44deffd7":[()=>t.e(6418).then(t.bind(t,34418)),"@site/blog/2022-05-28-open-day/index.md?truncated=true",34418],"45584c0f":[()=>t.e(7147).then(t.t.bind(t,11027,19)),"~blog/default/blog-tags-kusion-stack-page-2-b1d-list.json",11027],"45bfe338":[()=>t.e(4759).then(t.bind(t,77936)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/app-configuration.md",77936],"47d45151":[()=>t.e(3537).then(t.bind(t,97562)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/7-secret.md",97562],"497c7ba5":[()=>t.e(2364).then(t.bind(t,48666)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/secret.md",48666],"4a6d5a33":[()=>t.e(5612).then(t.bind(t,22755)),"@site/versioned_docs/version-v0.9/operating/concepts/podopslifecycle.md",22755],"4ac8e691":[()=>t.e(3677).then(t.bind(t,67584)),"@site/docs/ctrlmesh/started/install.md",67584],"4b36b697":[()=>t.e(1130).then(t.bind(t,65193)),"@site/docs/kusion/3-concepts/1-project/1-overview.md",65193],"4c493feb":[()=>t.e(9666).then(t.bind(t,92415)),"@site/docs/kusion/5-user-guides/2-working-with-k8s/2-container.md",92415],"4d1b877d":[()=>t.e(6176).then(t.bind(t,43037)),"@site/versioned_docs/version-v0.9/kusion/intro/overview.md",43037],"4df25393":[()=>t.e(1690).then(t.bind(t,85437)),"@site/versioned_docs/version-v0.10/ctrlmesh/concepts/concepts.md",85437],"4e363eb9":[()=>t.e(4588).then(t.bind(t,4992)),"@site/docs/kusion/6-reference/1-commands/kusion-workspace-delete.md",4992],"4f9c62c8":[()=>t.e(6803).then(t.t.bind(t,57719,19)),"~blog/default/blog-tags-kusion-page-2-3fb-list.json",57719],"501d789c":[()=>t.e(2677).then(t.t.bind(t,97985,19)),"~blog/default/blog-tags-platform-engineering-f5a.json",97985],"5078128f":[()=>t.e(4373).then(t.t.bind(t,24469,19)),"/home/runner/work/kusionstack.io/kusionstack.io/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",24469],"50dd26bc":[()=>t.e(8625).then(t.bind(t,93430)),"@site/docs/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",93430],"5114ba79":[()=>t.e(4539).then(t.bind(t,80914)),"@site/docs/community/intro/intro.md",80914],"523e8f76":[()=>t.e(8465).then(t.t.bind(t,50601,19)),"~blog/default/blog-tags-kusion-page-4-da4.json",50601],"5276ed9c":[()=>t.e(1567).then(t.bind(t,79401)),"@site/versioned_docs/version-v0.10/kusion/2-getting-started/2-deliver-wordpress.md",79401],"55141fa2":[()=>t.e(2934).then(t.bind(t,32599)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/doc_app_configuration.md",32599],"551843d2":[()=>t.e(6925).then(t.bind(t,85861)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/7-job.md",85861],"56362d1e":[()=>t.e(9242).then(t.bind(t,86606)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",86606],"566dbdc9":[()=>t.e(7288).then(t.bind(t,80483)),"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/index.md",80483],"5674e156":[()=>t.e(538).then(t.bind(t,51316)),"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/3-service.md",51316],"56d50f7c":[()=>Promise.all([t.e(532),t.e(7360)]).then(t.bind(t,60825)),"@site/versioned_docs/version-v0.9/kusion/guides/cloud-resources/database.md",60825],"58f1477f":[()=>t.e(886).then(t.bind(t,590)),"@site/blog/2023-05-26-qcon-guangzhou/index.md?truncated=true",590],"595d2708":[()=>t.e(1049).then(t.bind(t,61016)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",61016],"5a928bd4":[()=>t.e(5002).then(t.t.bind(t,97134,19)),"~blog/default/blog-tags-platform-engineering-f5a-list.json",97134],"5ad344a5":[()=>t.e(5203).then(t.bind(t,40182)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/index.md",40182],"5b1b6e2c":[()=>t.e(3752).then(t.bind(t,99479)),"@site/docs/kusion/6-reference/1-commands/kusion-init.md",99479],"5b1d6087":[()=>t.e(7930).then(t.t.bind(t,2123,19)),"~blog/default/blog-tags-kusion-stack-page-3-1a9-list.json",2123],"5b5ba27a":[()=>t.e(6349).then(t.t.bind(t,87407,19)),"~blog/default/blog-tags-kcl-17e-list.json",87407],"5e9f5e1a":[()=>Promise.resolve().then(t.bind(t,36809)),"@generated/docusaurus.config",36809],"5ea39018":[()=>t.e(9605).then(t.bind(t,42432)),"@site/versioned_docs/version-v0.10/kusion/7-faq/1-install-error.md",42432],"5ec8c180":[()=>t.e(8828).then(t.bind(t,20906)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/workload/doc_service.md",20906],"5ee164ec":[()=>t.e(2152).then(t.bind(t,68284)),"@site/versioned_docs/version-v0.9/kusion/concepts/kusion.md",68284],"5f456afb":[()=>t.e(2653).then(t.bind(t,18683)),"@site/docs/kusion/2-getting-started/2-deliver-wordpress.md",18683],"5fff1932":[()=>t.e(7206).then(t.bind(t,72479)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/probe/probe.md",72479],"600a00a0":[()=>t.e(5780).then(t.bind(t,81656)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/1-overview.md",81656],"60cc01db":[()=>t.e(9198).then(t.bind(t,20850)),"@site/docs/operating/started/demo-graceful-operation.md",20850],"61f95e53":[()=>t.e(995).then(t.bind(t,60571)),"@site/docs/kusion/6-reference/2-modules/3-naming-conventions.md",60571],"630accb9":[()=>t.e(2235).then(t.bind(t,489)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/index.md",489],"640c7392":[()=>t.e(6566).then(t.bind(t,47669)),"@site/versioned_docs/version-v0.9/kusion/concepts/arch.md",47669],"6875c492":[()=>Promise.all([t.e(532),t.e(8718),t.e(2529),t.e(8610)]).then(t.bind(t,41714)),"@theme/BlogTagsPostsPage",41714],"69e6dfa6":[()=>t.e(4790).then(t.bind(t,44815)),"@site/versioned_docs/version-v0.9/kusion/guides/observability/prometheus.md",44815],"6a034c6e":[()=>t.e(5634).then(t.bind(t,34123)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/5-networking.md",34123],"6b830420":[()=>t.e(992).then(t.bind(t,80847)),"@site/docs/kusion/5-user-guides/3-observability/1-prometheus.md",80847],"6eb5e412":[()=>t.e(7573).then(t.bind(t,5532)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/6-intent.md",5532],"6ece4ae7":[()=>t.e(8873).then(t.bind(t,31840)),"@site/versioned_docs/version-v0.9/kusion/reference/model/index.md",31840],"6fb6dfc9":[()=>t.e(9440).then(t.bind(t,22344)),"@site/docs/kusion/6-reference/1-commands/kusion-apply.md",22344],"7062af80":[()=>Promise.all([t.e(532),t.e(3332)]).then(t.bind(t,47576)),"@site/versioned_docs/version-v0.9/kusion/concepts/index.md",47576],"70dfc3b7":[()=>t.e(2481).then(t.bind(t,82020)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-preview.md",82020],"70fd01e9":[()=>t.e(2291).then(t.bind(t,23956)),"@site/docs/kusion/3-concepts/2-stack/1-overview.md",23956],"72ae1949":[()=>t.e(4215).then(t.bind(t,63070)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-build.md",63070],"72c158da":[()=>t.e(1824).then(t.bind(t,88370)),"@site/docs/operating/introduction/introduction.md",88370],"735b5664":[()=>t.e(2789).then(t.bind(t,93306)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-version.md",93306],"75071e09":[()=>t.e(3485).then(t.bind(t,2398)),"@site/docs/kusion/4-configuration-walkthrough/5-networking.md",2398],"7590d161":[()=>t.e(7550).then(t.bind(t,98287)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_build.md",98287],"76b33887":[()=>t.e(883).then(t.bind(t,4545)),"@site/versioned_docs/version-v0.10/operating/manuals/resourceconsist.md",4545],"77590aba":[()=>t.e(8251).then(t.bind(t,47526)),"@site/blog/2022-12-12-post-cloud-native-era-operation/index.md?truncated=true",47526],"7772ebc2":[()=>t.e(2626).then(t.bind(t,85890)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/3-base-override.md",85890],"77c6b439":[()=>t.e(8527).then(t.bind(t,8221)),"@site/docs/kusion/1-what-is-kusion/1-overview.md",8221],"78ec9a9a":[()=>t.e(9193).then(t.bind(t,56855)),"@site/docs/operating/manuals/collaset.md",56855],"79b30505":[()=>t.e(3038).then(t.bind(t,64906)),"@site/versioned_docs/version-v0.10/operating/introduction/introduction.md",64906],"7b92056b":[()=>t.e(1320).then(t.bind(t,22933)),"@site/docs/kusion/5-user-guides/5-secrets-management/1-using-cloud-secrets.md",22933],"7d19cf58":[()=>t.e(3883).then(t.bind(t,86435)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/9-operational-rules.md",86435],"7d429836":[()=>t.e(2616).then(t.bind(t,92951)),"@site/blog/2022-11-24-kusionstack-application-scale-operation-solution-in-the-post-cloudnative-era/index.md?truncated=true",92951],"7d9726a8":[()=>t.e(7429).then(t.t.bind(t,89494,19)),"~blog/default/blog-page-4-30b.json",89494],"7dad11d2":[()=>t.e(6956).then(t.bind(t,18968)),"@site/docs/kusion/3-concepts/8-configuration.md",18968],"7eff7e60":[()=>t.e(5436).then(t.bind(t,67766)),"@site/blog/2021-08-03-kcl-intro/index.md?truncated=true",67766],"7f5c0070":[()=>t.e(357).then(t.bind(t,75941)),"@site/versioned_docs/version-v0.9/kusion/reference/model/1-overview.md",75941],"814f3328":[()=>t.e(2535).then(t.t.bind(t,45641,19)),"~blog/default/blog-post-list-prop-default.json",45641],82029501:[()=>t.e(5408).then(t.bind(t,3320)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-list.md",3320],"821c5d9e":[()=>t.e(401).then(t.bind(t,61431)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/database.md",61431],"822aa99a":[()=>t.e(223).then(t.t.bind(t,38642,19)),"~docs/default/version-v-0-9-metadata-prop-346.json",38642],"82345ec9":[()=>t.e(6076).then(t.bind(t,47223)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/workload.md",47223],"82e833af":[()=>t.e(9310).then(t.bind(t,25754)),"@site/versioned_docs/version-v0.9/ctrlmesh/started/try.md",25754],83192466:[()=>t.e(1599).then(t.bind(t,12519)),"@site/versioned_docs/version-v0.10/operating/concepts/podopslifecycle.md",12519],"8356d355":[()=>t.e(7706).then(t.t.bind(t,36069,19)),"~blog/default/blog-tags-kusion-page-3-d9b.json",36069],"837fd906":[()=>t.e(1019).then(t.bind(t,56499)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe.md",56499],"83e1f194":[()=>Promise.all([t.e(532),t.e(6447)]).then(t.bind(t,45855)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/6-database.md",45855],"8619d2de":[()=>Promise.all([t.e(532),t.e(2527)]).then(t.bind(t,76433)),"@site/versioned_docs/version-v0.9/kusion/concepts/glossary.md",76433],"86764c80":[()=>t.e(4974).then(t.bind(t,97706)),"@site/versioned_docs/version-v0.9/ctrlmesh/intro/intro.md",97706],"87009dad":[()=>t.e(2499).then(t.t.bind(t,33426,19)),"~blog/default/blog-tags-kusion-faa.json",33426],87668920:[()=>t.e(9243).then(t.bind(t,76854)),"@site/docs/operating/concepts/podopslifecycle.md",76854],"87ed36d5":[()=>t.e(7494).then(t.bind(t,64726)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/kcl_basics.md",64726],"8827e5e6":[()=>t.e(6631).then(t.bind(t,42589)),"@site/versioned_docs/version-v0.9/operating/manuals/podtransitionrule.md",42589],"892abc49":[()=>t.e(3741).then(t.t.bind(t,37951,19)),"~blog/default/blog-tags-kusion-faa-list.json",37951],"8a2c5ffd":[()=>t.e(2634).then(t.bind(t,54759)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace.md",54759],"8b19a93e":[()=>t.e(8622).then(t.bind(t,56317)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/4-image-upgrade.md",56317],"8b810823":[()=>t.e(5160).then(t.bind(t,1080)),"@site/docs/kusion/3-concepts/6-intent.md",1080],"8b914266":[()=>t.e(6183).then(t.t.bind(t,63987,19)),"~blog/default/blog-tags-kusion-stack-page-4-3a4-list.json",63987],"8d59c070":[()=>t.e(7555).then(t.bind(t,90181)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/7-backend-configuration.md",90181],"8e17bf11":[()=>t.e(1974).then(t.bind(t,65773)),"@site/versioned_docs/version-v0.9/operating/manuals/poddecoration.md",65773],"8eb4e46b":[()=>t.e(1).then(t.t.bind(t,82638,19)),"~blog/default/blog-page-2-677.json",82638],"8ebb0243":[()=>t.e(2009).then(t.bind(t,35658)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret.md",35658],"8f5adede":[()=>t.e(5825).then(t.bind(t,14190)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/1-project/2-configuration.md",14190],"8fcded8c":[()=>t.e(9803).then(t.bind(t,93635)),"@site/docs/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",93635],"92999a1c":[()=>t.e(8442).then(t.t.bind(t,15310,19)),"~blog/default/blog-page-3-fd4.json",15310],"92e7585f":[()=>t.e(549).then(t.bind(t,77457)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_destroy.md",77457],"935f2afb":[()=>t.e(53).then(t.t.bind(t,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"9595b411":[()=>t.e(581).then(t.bind(t,60803)),"@site/versioned_docs/version-v0.9/operating/manuals/collaset.md",60803],"9662bf8d":[()=>t.e(8194).then(t.bind(t,78240)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/3-service.md",78240],"977fdfc4":[()=>Promise.all([t.e(532),t.e(135)]).then(t.bind(t,81087)),"@site/docs/kusion/4-configuration-walkthrough/6-database.md",81087],"97d4b178":[()=>t.e(5644).then(t.bind(t,32559)),"@site/docs/kusion/4-configuration-walkthrough/2-kcl-basics.md",32559],99000770:[()=>t.e(920).then(t.bind(t,51183)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/network/doc_port.md",51183],"990e3068":[()=>t.e(4796).then(t.bind(t,43229)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",43229],"99153eb1":[()=>t.e(9010).then(t.bind(t,62454)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/backend/backend-configuration.md",62454],"9aa57586":[()=>t.e(4032).then(t.bind(t,83102)),"@site/versioned_docs/version-v0.9/kusion/intro/kusion-vs-x.md",83102],"9c804087":[()=>t.e(9373).then(t.bind(t,70496)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/index.md",70496],"9d1d9869":[()=>t.e(5763).then(t.bind(t,22813)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/index.md",22813],"9e3571d8":[()=>t.e(6103).then(t.bind(t,78379)),"@site/docs/kusion/3-concepts/1-project/2-configuration.md",78379],"9e4087bc":[()=>t.e(3608).then(t.bind(t,63169)),"@theme/BlogArchivePage",63169],"9f069a65":[()=>t.e(963).then(t.bind(t,61704)),"@site/docs/kusion/4-configuration-walkthrough/8-monitoring.md",61704],"9fc66687":[()=>t.e(7988).then(t.bind(t,9282)),"@site/versioned_docs/version-v0.9/ctrlmesh/concepts/concepts.md",9282],a08f9b67:[()=>t.e(6107).then(t.bind(t,61374)),"@site/docs/kusion/6-reference/1-commands/kusion-workspace.md",61374],a1143e8d:[()=>t.e(6713).then(t.t.bind(t,83769,19)),"/home/runner/work/kusionstack.io/kusionstack.io/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",83769],a121ee0b:[()=>t.e(2180).then(t.bind(t,21599)),"@site/docs/kusion/3-concepts/2-stack/2-configuration.md",21599],a27ca0d9:[()=>t.e(7117).then(t.bind(t,63391)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/3-observability/1-prometheus.md",63391],a28f322c:[()=>t.e(905).then(t.bind(t,52406)),"@site/docs/kusion/6-reference/1-commands/kusion-destroy.md",52406],a5969c3a:[()=>t.e(2933).then(t.bind(t,31648)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_apply.md",31648],a6aa9e1f:[()=>Promise.all([t.e(532),t.e(8718),t.e(2529),t.e(3089)]).then(t.bind(t,80046)),"@theme/BlogListPage",80046],a7023ddc:[()=>t.e(1713).then(t.t.bind(t,53457,19)),"~blog/default/blog-tags-tags-4c2.json",53457],a8f9fa37:[()=>t.e(7092).then(t.bind(t,88576)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/network/port.md",88576],abc4e0a8:[()=>t.e(2204).then(t.bind(t,77098)),"@site/docs/kusion/4-configuration-walkthrough/1-overview.md",77098],ad602bef:[()=>t.e(2222).then(t.bind(t,62619)),"@site/versioned_docs/version-v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions.md",62619],adf149f0:[()=>t.e(5385).then(t.bind(t,18620)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_preview.md",18620],aec48fb4:[()=>t.e(9858).then(t.bind(t,74564)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",74564],af046d03:[()=>t.e(6047).then(t.bind(t,46979)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/internal/container/container.md",46979],af2e79ee:[()=>t.e(7926).then(t.bind(t,91151)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/2-stack/2-configuration.md",91151],b049517a:[()=>t.e(550).then(t.bind(t,93235)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/3-naming-conventions.md",93235],b075c519:[()=>t.e(3464).then(t.bind(t,88223)),"@site/docs/ctrlmesh/concepts/concepts.md",88223],b10c63de:[()=>t.e(7143).then(t.bind(t,73362)),"@site/blog/2022-09-16-learn-from-scale-practice/index.md",73362],b1566ae1:[()=>t.e(9424).then(t.bind(t,74937)),"@site/blog/2022-11-24-kusionstack-application-scale-operation-solution-in-the-post-cloudnative-era/index.md",74937],b21ef2b8:[()=>t.e(7101).then(t.t.bind(t,39149,19)),"~blog/default/blog-tags-kusion-page-2-3fb.json",39149],b2b675dd:[()=>t.e(533).then(t.t.bind(t,28017,19)),"~blog/default/blog-c06.json",28017],b2f45e36:[()=>t.e(9434).then(t.bind(t,49664)),"@site/docs/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",49664],b2f554cd:[()=>t.e(1477).then(t.t.bind(t,30010,19)),"~blog/default/blog-archive-80c.json",30010],b3471d8e:[()=>t.e(3229).then(t.bind(t,21984)),"@site/docs/operating/manuals/poddecoration.md",21984],b34bf6de:[()=>t.e(851).then(t.bind(t,29910)),"@site/docs/operating/manuals/podtransitionrule.md",29910],b44b4ce2:[()=>t.e(1073).then(t.bind(t,78252)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/service.md",78252],b46813dd:[()=>t.e(1115).then(t.bind(t,44732)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",44732],b472ca0f:[()=>t.e(2322).then(t.t.bind(t,61023,19)),"~blog/default/blog-tags-kcl-17e.json",61023],b509c81b:[()=>t.e(3618).then(t.bind(t,1062)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/database/postgres.md",1062],b57a4a2d:[()=>t.e(2708).then(t.bind(t,92542)),"@site/docs/kusion/5-user-guides/2-working-with-k8s/5-resource-spec.md",92542],b5d95ae4:[()=>t.e(413).then(t.bind(t,63205)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/2-container.md",63205],b6cf2faa:[()=>t.e(1725).then(t.bind(t,77095)),"@site/versioned_docs/version-v0.10/kusion/7-faq/2-kcl.md",77095],b6dea0ad:[()=>t.e(8535).then(t.bind(t,86238)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",86238],b70fdfcb:[()=>t.e(5081).then(t.bind(t,58036)),"@site/docs/ctrlmesh/faq/faq.md",58036],b72e870b:[()=>t.e(799).then(t.bind(t,71295)),"@site/docs/kusion/6-reference/1-commands/kusion-workspace-show.md",71295],b7847a20:[()=>t.e(1659).then(t.bind(t,61232)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/internal/container/lifecycle/lifecycle.md",61232],b7fdee58:[()=>t.e(5889).then(t.bind(t,670)),"@site/blog/2022-05-28-open-day/index.md",670],b8caf01f:[()=>t.e(5297).then(t.bind(t,45561)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/3-kusion-module.md",45561],b9b61d04:[()=>t.e(4491).then(t.bind(t,90999)),"@site/docs/kusion/6-reference/2-modules/index.md",90999],ba7ecca1:[()=>t.e(9524).then(t.t.bind(t,15745,19)),"/home/runner/work/kusionstack.io/kusionstack.io/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",15745],baa12f70:[()=>t.e(5641).then(t.bind(t,46770)),"@site/docs/kusion/6-reference/3-roadmap.md",46770],bbff1c36:[()=>t.e(7202).then(t.bind(t,32700)),"@site/versioned_docs/version-v0.10/community/intro/intro.md",32700],bc5f1a80:[()=>t.e(835).then(t.bind(t,73060)),"@site/docs/kusion/7-faq/1-install-error.md",73060],c02a675f:[()=>t.e(800).then(t.bind(t,62222)),"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",62222],c09b0fe7:[()=>t.e(1813).then(t.bind(t,71470)),"@site/docs/kusion/6-reference/1-commands/kusion-workspace-create.md",71470],c15b59ba:[()=>t.e(5731).then(t.bind(t,21085)),"@site/docs/kusion/6-reference/1-commands/kusion-build.md",21085],c1bf8f22:[()=>t.e(2347).then(t.bind(t,90200)),"@site/docs/kusion/5-user-guides/1-cloud-resources/2-expose-service.md",90200],c2884f74:[()=>t.e(9216).then(t.bind(t,84068)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-destroy.md",84068],c311d7f4:[()=>t.e(4446).then(t.bind(t,25154)),"@site/docs/operating/manuals/resourceconsist.md",25154],c31a6c64:[()=>t.e(6721).then(t.bind(t,8388)),"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/2-container.md",8388],c3728e1b:[()=>t.e(2290).then(t.bind(t,49869)),"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/4-image-upgrade.md",49869],c4ba81c3:[()=>t.e(6489).then(t.bind(t,41418)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/database/postgres.md",41418],c4f5d8e4:[()=>Promise.all([t.e(532),t.e(8550),t.e(4195)]).then(t.bind(t,7413)),"@site/src/pages/index.js",7413],c5353c60:[()=>t.e(4855).then(t.bind(t,56777)),"@site/docs/kusion/1-what-is-kusion/2-kusion-vs-x.md",56777],c5a89df7:[()=>t.e(1550).then(t.bind(t,67155)),"@site/versioned_docs/version-v0.10/kusion/3-concepts/8-how-kusion-works.md",67155],c65cb071:[()=>t.e(7830).then(t.bind(t,8335)),"@site/blog/2021-08-03-kcl-intro/index.md",8335],c6ae2a42:[()=>t.e(922).then(t.bind(t,72157)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/2-kcl-basics.md",72157],c7fa01e5:[()=>t.e(5523).then(t.bind(t,14609)),"@site/docs/kusion/5-user-guides/2-working-with-k8s/7-job.md",14609],c9f937b3:[()=>t.e(7598).then(t.bind(t,58168)),"@site/blog/2022-06-07-sense-of-open-day/index.md?truncated=true",58168],ccc49370:[()=>Promise.all([t.e(532),t.e(8718),t.e(2529),t.e(1080)]).then(t.bind(t,65203)),"@theme/BlogPostPage",65203],cd9e621c:[()=>t.e(7744).then(t.bind(t,67241)),"@site/docs/kusion/6-reference/1-commands/kusion-workspace-list.md",67241],cf74b0d6:[()=>t.e(5617).then(t.bind(t,14546)),"@site/blog/2022-09-16-learn-from-scale-practice/index.md?truncated=true",14546],d0375dde:[()=>t.e(2709).then(t.bind(t,70335)),"@site/versioned_docs/version-v0.9/kusion/concepts/intent.md",70335],d05ef132:[()=>t.e(5452).then(t.bind(t,15157)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/base_override.md",15157],d08bdbd3:[()=>t.e(5665).then(t.bind(t,11286)),"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",11286],d107a415:[()=>t.e(6945).then(t.bind(t,99778)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-update.md",99778],d33211a6:[()=>t.e(8786).then(t.t.bind(t,86080,19)),"~blog/default/blog-tags-kclvm-31a-list.json",86080],d33f5cb2:[()=>t.e(1137).then(t.bind(t,90511)),"@site/docs/kusion/6-reference/1-commands/index.md",90511],d398f178:[()=>t.e(654).then(t.bind(t,28107)),"@site/versioned_docs/version-v0.10/kusion/4-configuration-walkthrough/8-monitoring.md",28107],d5b05897:[()=>t.e(7736).then(t.bind(t,37793)),"@site/docs/kusion/4-configuration-walkthrough/3-base-override.md",37793],d5d68d14:[()=>t.e(9093).then(t.bind(t,43850)),"@site/versioned_docs/version-v0.9/kusion/guides/guides.md",43850],d65cad0c:[()=>t.e(2713).then(t.bind(t,17301)),"@site/versioned_docs/version-v0.10/ctrlmesh/faq/faq.md",17301],d7b729b6:[()=>t.e(9756).then(t.bind(t,92839)),"@site/versioned_docs/version-v0.9/kusion/support/install-error.md",92839],d9a047ee:[()=>t.e(795).then(t.bind(t,83286)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/monitoring/prometheus.md",83286],da7786fc:[()=>t.e(3027).then(t.bind(t,9406)),"@site/versioned_docs/version-v0.9/operating/started/demo-graceful-operation.md",9406],db343463:[()=>t.e(8420).then(t.bind(t,51901)),"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/workload/job.md",51901],dbbf606f:[()=>t.e(7705).then(t.bind(t,49250)),"@site/docs/kusion/6-reference/1-commands/kusion-compile.md",49250],dc405d94:[()=>t.e(6305).then(t.bind(t,89122)),"@site/versioned_docs/version-v0.9/kusion/guides/working-with-k8s/5-resource-spec.md",89122],de200a2a:[()=>t.e(3545).then(t.bind(t,41934)),"@site/versioned_docs/version-v0.9/operating/introduction/introduction.md",41934],de7874bb:[()=>t.e(8026).then(t.bind(t,23127)),"@site/docs/kusion/3-concepts/5-appconfiguration.md",23127],dfc7c90d:[()=>t.e(5655).then(t.bind(t,57022)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/workload/job.md",57022],e0ecd429:[()=>t.e(5435).then(t.t.bind(t,84931,19)),"~blog/default/blog-tags-large-scale-0df-list.json",84931],e2111cc5:[()=>t.e(8691).then(t.bind(t,65351)),"@site/blog/2022-06-07-sense-of-open-day/index.md",65351],e381d75c:[()=>t.e(9747).then(t.bind(t,62917)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/4-github-actions/1-deploy-application-via-github-actions.md",62917],e4842d65:[()=>t.e(8276).then(t.t.bind(t,7085,19)),"/home/runner/work/kusionstack.io/kusionstack.io/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],e4f1eb77:[()=>t.e(2636).then(t.bind(t,82091)),"@site/docs/kusion/5-user-guides/2-working-with-k8s/3-service.md",82091],e6798fa1:[()=>t.e(1858).then(t.bind(t,50310)),"@site/versioned_docs/version-v0.9/operating/manuals/resourceconsist.md",50310],e695a9f3:[()=>t.e(216).then(t.bind(t,9574)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-compile.md",9574],e696141c:[()=>t.e(1421).then(t.bind(t,37990)),"@site/docs/kusion/6-reference/2-modules/1-catalog-models/monitoring/prometheus.md",37990],e701010f:[()=>t.e(6531).then(t.bind(t,7326)),"@site/docs/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",7326],e7e8cb25:[()=>t.e(9089).then(t.bind(t,57746)),"@site/versioned_docs/version-v0.10/kusion/1-what-is-kusion/1-overview.md",57746],e8149155:[()=>t.e(2839).then(t.bind(t,92642)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/networking.md",92642],e866e893:[()=>t.e(6485).then(t.t.bind(t,57761,19)),"~blog/default/blog-tags-kusion-stack-1cb.json",57761],e877f19f:[()=>t.e(4605).then(t.bind(t,51346)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_version.md",51346],e89e36c0:[()=>t.e(7816).then(t.bind(t,26027)),"@site/versioned_docs/version-v0.10/operating/manuals/poddecoration.md",26027],ebf27649:[()=>t.e(2136).then(t.bind(t,58338)),"@site/versioned_docs/version-v0.9/kusion/reference/model/naming-conventions.md",58338],ecaa6eee:[()=>t.e(5156).then(t.bind(t,23988)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/networking/port.md",23988],ecbd3f41:[()=>t.e(9529).then(t.bind(t,5366)),"@site/versioned_docs/version-v0.10/kusion/6-reference/1-commands/kusion-workspace-create.md",5366],eccaeac4:[()=>t.e(4995).then(t.bind(t,13109)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_init.md",13109],ed2e9c54:[()=>t.e(9037).then(t.bind(t,79364)),"@site/versioned_docs/version-v0.9/kusion/support/kcl.md",79364],ee59e712:[()=>t.e(2846).then(t.bind(t,67362)),"@site/versioned_docs/version-v0.9/kusion/concepts/appconfiguration.md",67362],ee68f9c5:[()=>t.e(1094).then(t.bind(t,79800)),"@site/versioned_docs/version-v0.9/kusion/config-walkthrough/operational_rules.md",79800],ee6d0512:[()=>t.e(2121).then(t.bind(t,41437)),"@site/docs/kusion/7-faq/2-kcl.md",41437],f058aa3c:[()=>t.e(5107).then(t.bind(t,38947)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus.md",38947],f1e404ac:[()=>t.e(1327).then(t.bind(t,95383)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/1-catalog-models/trait/opsrule.md",95383],f23835f0:[()=>t.e(2664).then(t.t.bind(t,62810,19)),"~blog/default/blog-tags-kusion-stack-page-2-b1d.json",62810],f34acb22:[()=>t.e(1650).then(t.bind(t,33153)),"@site/versioned_docs/version-v0.9/kusion/reference/cli/kusion/kusion_compile.md",33153],f35beff3:[()=>t.e(8039).then(t.bind(t,36349)),"@site/versioned_docs/version-v0.10/kusion/5-user-guides/2-working-with-k8s/6-set-up-operational-rules.md",36349],f4eeafd2:[()=>t.e(588).then(t.bind(t,83191)),"@site/versioned_docs/version-v0.9/kusion/getting-started/getting-started.md",83191],f655a87f:[()=>t.e(8444).then(t.bind(t,54528)),"@site/versioned_docs/version-v0.9/ctrlmesh/faq/faq.md",54528],f7f2164e:[()=>t.e(9095).then(t.bind(t,3483)),"@site/docs/kusion/3-concepts/9-how-kusion-works.md",3483],f9476b7a:[()=>t.e(8996).then(t.bind(t,41760)),"@site/versioned_docs/version-v0.9/kusion/reference/model/catalog_models/internal/container/doc_container.md",41760],fa47a47e:[()=>t.e(1758).then(t.bind(t,74307)),"@site/versioned_docs/version-v0.10/ctrlmesh/started/try.md",74307],fb5bb801:[()=>t.e(7971).then(t.bind(t,2233)),"@site/blog/2022-09-19-origin-present-and-future/index.md",2233],fbcd2cf0:[()=>t.e(8090).then(t.bind(t,20476)),"@site/blog/2022-09-19-origin-present-and-future/index.md?truncated=true",20476],fd1fdd14:[()=>t.e(3438).then(t.bind(t,81426)),"@site/docs/kusion/3-concepts/4-workspace.md",81426],fd5a02a1:[()=>t.e(6624).then(t.t.bind(t,22581,19)),"~blog/default/blog-tags-kusion-stack-page-3-1a9.json",22581],fdecbe36:[()=>t.e(2403).then(t.bind(t,4859)),"@site/versioned_docs/version-v0.10/kusion/6-reference/2-modules/2-workspace-configs/workload/service.md",4859]};function l(e){let{error:n,retry:t,pastDelay:r}=e;return n?o.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},o.createElement("p",null,String(n)),o.createElement("div",null,o.createElement("button",{type:"button",onClick:t},"Retry"))):r?o.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},o.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},o.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},o.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},o.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),o.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},o.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),o.createElement("circle",{cx:"22",cy:"22",r:"8"},o.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=t(99670),d=t(30226);function p(e,n){if("*"===e)return a()({loading:l,loader:()=>t.e(4972).then(t.bind(t,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,n){const t=e.default;return o.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},o.createElement(t,n))}});const i=s[`${e}-${n}`],p={},f=[],m=[],g=(0,u.Z)(i);return Object.entries(g).forEach((e=>{let[n,t]=e;const o=c[t];o&&(p[n]=o[0],f.push(o[1]),m.push(o[2]))})),a().Map({loading:l,loader:p,modules:f,webpack:()=>m,render(n,t){const a=JSON.parse(JSON.stringify(i));Object.entries(n).forEach((n=>{let[t,o]=n;const r=o.default;if(!r)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof r&&"function"!=typeof r||Object.keys(o).filter((e=>"default"!==e)).forEach((e=>{r[e]=o[e]}));let i=a;const s=t.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=r}));const s=a.__comp;delete a.__comp;const c=a.__context;return delete a.__context,o.createElement(d.z,{value:c},o.createElement(s,(0,r.Z)({},a,t)))}})}const f=[{path:"/blog",component:p("/blog","739"),exact:!0},{path:"/blog/2021-kcl-intro",component:p("/blog/2021-kcl-intro","363"),exact:!0},{path:"/blog/2021-kusion-intro",component:p("/blog/2021-kusion-intro","f82"),exact:!0},{path:"/blog/2022-kusionstack-application-scale-operation-solution-in-the-post-cloudnative-era",component:p("/blog/2022-kusionstack-application-scale-operation-solution-in-the-post-cloudnative-era","d44"),exact:!0},{path:"/blog/2022-learn-from-scale-practice",component:p("/blog/2022-learn-from-scale-practice","fc2"),exact:!0},{path:"/blog/2022-open-day",component:p("/blog/2022-open-day","f3d"),exact:!0},{path:"/blog/2022-origin-present-and-future",component:p("/blog/2022-origin-present-and-future","d98"),exact:!0},{path:"/blog/2022-post-cloud-native-era-operation",component:p("/blog/2022-post-cloud-native-era-operation","74f"),exact:!0},{path:"/blog/2022-sense-of-open-day",component:p("/blog/2022-sense-of-open-day","66f"),exact:!0},{path:"/blog/2023-05-26-qcon-guangzhou",component:p("/blog/2023-05-26-qcon-guangzhou","aaf"),exact:!0},{path:"/blog/archive",component:p("/blog/archive","d35"),exact:!0},{path:"/blog/page/2",component:p("/blog/page/2","7b7"),exact:!0},{path:"/blog/page/3",component:p("/blog/page/3","f80"),exact:!0},{path:"/blog/page/4",component:p("/blog/page/4","c94"),exact:!0},{path:"/blog/page/5",component:p("/blog/page/5","6b8"),exact:!0},{path:"/blog/tags",component:p("/blog/tags","468"),exact:!0},{path:"/blog/tags/kcl",component:p("/blog/tags/kcl","3dc"),exact:!0},{path:"/blog/tags/kclvm",component:p("/blog/tags/kclvm","2fa"),exact:!0},{path:"/blog/tags/kusion",component:p("/blog/tags/kusion","e28"),exact:!0},{path:"/blog/tags/kusion-stack",component:p("/blog/tags/kusion-stack","b5f"),exact:!0},{path:"/blog/tags/kusion-stack/page/2",component:p("/blog/tags/kusion-stack/page/2","f5c"),exact:!0},{path:"/blog/tags/kusion-stack/page/3",component:p("/blog/tags/kusion-stack/page/3","3ba"),exact:!0},{path:"/blog/tags/kusion-stack/page/4",component:p("/blog/tags/kusion-stack/page/4","bd3"),exact:!0},{path:"/blog/tags/kusion/page/2",component:p("/blog/tags/kusion/page/2","5f9"),exact:!0},{path:"/blog/tags/kusion/page/3",component:p("/blog/tags/kusion/page/3","e49"),exact:!0},{path:"/blog/tags/kusion/page/4",component:p("/blog/tags/kusion/page/4","18b"),exact:!0},{path:"/blog/tags/large-scale",component:p("/blog/tags/large-scale","645"),exact:!0},{path:"/blog/tags/platform-engineering",component:p("/blog/tags/platform-engineering","309"),exact:!0},{path:"/markdown-page",component:p("/markdown-page","b1e"),exact:!0},{path:"/search",component:p("/search","599"),exact:!0},{path:"/docs/next",component:p("/docs/next","5b2"),routes:[{path:"/docs/next/",component:p("/docs/next/","4f4"),exact:!0,sidebar:"kusion"},{path:"/docs/next/community/intro/",component:p("/docs/next/community/intro/","2bb"),exact:!0,sidebar:"community"},{path:"/docs/next/ctrlmesh/concepts/",component:p("/docs/next/ctrlmesh/concepts/","c6b"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/next/ctrlmesh/faq/",component:p("/docs/next/ctrlmesh/faq/","d59"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/next/ctrlmesh/intro/",component:p("/docs/next/ctrlmesh/intro/","e7b"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/next/ctrlmesh/started/install",component:p("/docs/next/ctrlmesh/started/install","4a5"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/next/ctrlmesh/started/try",component:p("/docs/next/ctrlmesh/started/try","d22"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/next/kusion/concepts/app-configuration",component:p("/docs/next/kusion/concepts/app-configuration","d31"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/backend",component:p("/docs/next/kusion/concepts/backend","8a2"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/configuration",component:p("/docs/next/kusion/concepts/configuration","766"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/how-kusion-works",component:p("/docs/next/kusion/concepts/how-kusion-works","781"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/intent",component:p("/docs/next/kusion/concepts/intent","ed5"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/kusion-module",component:p("/docs/next/kusion/concepts/kusion-module","1a2"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/project/configuration",component:p("/docs/next/kusion/concepts/project/configuration","f1d"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/project/overview",component:p("/docs/next/kusion/concepts/project/overview","e99"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/stack/configuration",component:p("/docs/next/kusion/concepts/stack/configuration","876"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/stack/overview",component:p("/docs/next/kusion/concepts/stack/overview","ea2"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/concepts/workspace",component:p("/docs/next/kusion/concepts/workspace","54b"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/base-override",component:p("/docs/next/kusion/configuration-walkthrough/base-override","a4f"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/databse",component:p("/docs/next/kusion/configuration-walkthrough/databse","b5e"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/kcl-basics",component:p("/docs/next/kusion/configuration-walkthrough/kcl-basics","b4b"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/monitoring",component:p("/docs/next/kusion/configuration-walkthrough/monitoring","d1d"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/networking",component:p("/docs/next/kusion/configuration-walkthrough/networking","d3d"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/operational-rules",component:p("/docs/next/kusion/configuration-walkthrough/operational-rules","85c"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/overview",component:p("/docs/next/kusion/configuration-walkthrough/overview","ead"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/secret",component:p("/docs/next/kusion/configuration-walkthrough/secret","049"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/configuration-walkthrough/workload",component:p("/docs/next/kusion/configuration-walkthrough/workload","563"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/faq/install-error",component:p("/docs/next/kusion/faq/install-error","6e9"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/faq/kcl",component:p("/docs/next/kusion/faq/kcl","7ba"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/getting-started/deliver-wordpress",component:p("/docs/next/kusion/getting-started/deliver-wordpress","9f6"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/getting-started/install-kusion",component:p("/docs/next/kusion/getting-started/install-kusion","d36"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/",component:p("/docs/next/kusion/reference/commands/","a49"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-apply",component:p("/docs/next/kusion/reference/commands/kusion-apply","e84"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-build",component:p("/docs/next/kusion/reference/commands/kusion-build","bab"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-compile",component:p("/docs/next/kusion/reference/commands/kusion-compile","cac"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-destroy",component:p("/docs/next/kusion/reference/commands/kusion-destroy","6a3"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-init",component:p("/docs/next/kusion/reference/commands/kusion-init","dd4"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-preview",component:p("/docs/next/kusion/reference/commands/kusion-preview","66c"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-version",component:p("/docs/next/kusion/reference/commands/kusion-version","b14"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-workspace",component:p("/docs/next/kusion/reference/commands/kusion-workspace","c72"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-workspace-create",component:p("/docs/next/kusion/reference/commands/kusion-workspace-create","27a"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-workspace-delete",component:p("/docs/next/kusion/reference/commands/kusion-workspace-delete","a46"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-workspace-list",component:p("/docs/next/kusion/reference/commands/kusion-workspace-list","109"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-workspace-show",component:p("/docs/next/kusion/reference/commands/kusion-workspace-show","8f4"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/commands/kusion-workspace-update",component:p("/docs/next/kusion/reference/commands/kusion-workspace-update","9bf"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/",component:p("/docs/next/kusion/reference/modules/","591"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/app-configuration",component:p("/docs/next/kusion/reference/modules/catalog-models/app-configuration","864"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/database/mysql",component:p("/docs/next/kusion/reference/modules/catalog-models/database/mysql","0a3"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/database/postgres",component:p("/docs/next/kusion/reference/modules/catalog-models/database/postgres","039"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/internal/common",component:p("/docs/next/kusion/reference/modules/catalog-models/internal/common","132"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/internal/container/",component:p("/docs/next/kusion/reference/modules/catalog-models/internal/container/","6a3"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/",component:p("/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/","c85"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/",component:p("/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/","d88"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/internal/network/port",component:p("/docs/next/kusion/reference/modules/catalog-models/internal/network/port","4ee"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/internal/secret/",component:p("/docs/next/kusion/reference/modules/catalog-models/internal/secret/","898"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus",component:p("/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus","ce2"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule",component:p("/docs/next/kusion/reference/modules/catalog-models/trait/opsrule","38e"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/workload/job",component:p("/docs/next/kusion/reference/modules/catalog-models/workload/job","a13"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/catalog-models/workload/service",component:p("/docs/next/kusion/reference/modules/catalog-models/workload/service","965"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/naming-conventions",component:p("/docs/next/kusion/reference/modules/naming-conventions","d94"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/workspace-configs/database/mysql",component:p("/docs/next/kusion/reference/modules/workspace-configs/database/mysql","e11"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/workspace-configs/database/postgres",component:p("/docs/next/kusion/reference/modules/workspace-configs/database/postgres","4d1"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus",component:p("/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus","25d"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/workspace-configs/networking/port",component:p("/docs/next/kusion/reference/modules/workspace-configs/networking/port","f44"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule",component:p("/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule","03b"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/workspace-configs/workload/job",component:p("/docs/next/kusion/reference/modules/workspace-configs/workload/job","c19"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/modules/workspace-configs/workload/service",component:p("/docs/next/kusion/reference/modules/workspace-configs/workload/service","5bb"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/reference/roadmap",component:p("/docs/next/kusion/reference/roadmap","8f9"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/cloud-resources/database",component:p("/docs/next/kusion/user-guides/cloud-resources/database","4f2"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/cloud-resources/expose-service",component:p("/docs/next/kusion/user-guides/cloud-resources/expose-service","02f"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions",component:p("/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions","526"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/observability/prometheus",component:p("/docs/next/kusion/user-guides/observability/prometheus","54c"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets",component:p("/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets","76e"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/working-with-k8s/container",component:p("/docs/next/kusion/user-guides/working-with-k8s/container","2c7"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/working-with-k8s/deploy-application",component:p("/docs/next/kusion/user-guides/working-with-k8s/deploy-application","c19"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade",component:p("/docs/next/kusion/user-guides/working-with-k8s/image-upgrade","e77"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/working-with-k8s/job",component:p("/docs/next/kusion/user-guides/working-with-k8s/job","117"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/working-with-k8s/resource-spec",component:p("/docs/next/kusion/user-guides/working-with-k8s/resource-spec","825"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/working-with-k8s/service",component:p("/docs/next/kusion/user-guides/working-with-k8s/service","8fd"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules",component:p("/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules","31a"),exact:!0,sidebar:"kusion"},{path:"/docs/next/kusion/what-is-kusion/kusion-vs-x",component:p("/docs/next/kusion/what-is-kusion/kusion-vs-x","0b4"),exact:!0,sidebar:"kusion"},{path:"/docs/next/operating/concepts/podopslifecycle",component:p("/docs/next/operating/concepts/podopslifecycle","4d7"),exact:!0,sidebar:"operating"},{path:"/docs/next/operating/introduction/",component:p("/docs/next/operating/introduction/","792"),exact:!0,sidebar:"operating"},{path:"/docs/next/operating/manuals/collaset",component:p("/docs/next/operating/manuals/collaset","962"),exact:!0,sidebar:"operating"},{path:"/docs/next/operating/manuals/poddecoration",component:p("/docs/next/operating/manuals/poddecoration","408"),exact:!0,sidebar:"operating"},{path:"/docs/next/operating/manuals/podtransitionrule",component:p("/docs/next/operating/manuals/podtransitionrule","f82"),exact:!0,sidebar:"operating"},{path:"/docs/next/operating/manuals/resourceconsist",component:p("/docs/next/operating/manuals/resourceconsist","e68"),exact:!0,sidebar:"operating"},{path:"/docs/next/operating/started/demo-graceful-operation",component:p("/docs/next/operating/started/demo-graceful-operation","3f8"),exact:!0,sidebar:"operating"},{path:"/docs/next/operating/started/install",component:p("/docs/next/operating/started/install","d8f"),exact:!0,sidebar:"operating"}]},{path:"/docs/v0.9",component:p("/docs/v0.9","0d1"),routes:[{path:"/docs/v0.9/",component:p("/docs/v0.9/","168"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/community/intro/",component:p("/docs/v0.9/community/intro/","674"),exact:!0,sidebar:"community"},{path:"/docs/v0.9/ctrlmesh/concepts/",component:p("/docs/v0.9/ctrlmesh/concepts/","e12"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/v0.9/ctrlmesh/faq/",component:p("/docs/v0.9/ctrlmesh/faq/","8b2"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/v0.9/ctrlmesh/intro/",component:p("/docs/v0.9/ctrlmesh/intro/","6cd"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/v0.9/ctrlmesh/started/install",component:p("/docs/v0.9/ctrlmesh/started/install","7d6"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/v0.9/ctrlmesh/started/try",component:p("/docs/v0.9/ctrlmesh/started/try","58c"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/v0.9/kusion/concepts/",component:p("/docs/v0.9/kusion/concepts/","2e4"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/concepts/appconfiguration",component:p("/docs/v0.9/kusion/concepts/appconfiguration","33c"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/concepts/arch",component:p("/docs/v0.9/kusion/concepts/arch","37d"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/concepts/glossary",component:p("/docs/v0.9/kusion/concepts/glossary","bb6"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/concepts/intent",component:p("/docs/v0.9/kusion/concepts/intent","f7a"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/concepts/kusion",component:p("/docs/v0.9/kusion/concepts/kusion","514"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/base_override",component:p("/docs/v0.9/kusion/config-walkthrough/base_override","b59"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/database",component:p("/docs/v0.9/kusion/config-walkthrough/database","930"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/kcl_basics",component:p("/docs/v0.9/kusion/config-walkthrough/kcl_basics","e39"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/monitoring",component:p("/docs/v0.9/kusion/config-walkthrough/monitoring","97d"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/networking",component:p("/docs/v0.9/kusion/config-walkthrough/networking","a7b"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/operational_rules",component:p("/docs/v0.9/kusion/config-walkthrough/operational_rules","d98"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/overview",component:p("/docs/v0.9/kusion/config-walkthrough/overview","32d"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/secret",component:p("/docs/v0.9/kusion/config-walkthrough/secret","50a"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/config-walkthrough/workload",component:p("/docs/v0.9/kusion/config-walkthrough/workload","ade"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/getting-started/",component:p("/docs/v0.9/kusion/getting-started/","980"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/getting-started/deliver-wordpress",component:p("/docs/v0.9/kusion/getting-started/deliver-wordpress","413"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/getting-started/install-kusion",component:p("/docs/v0.9/kusion/getting-started/install-kusion","219"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/",component:p("/docs/v0.9/kusion/guides/","524"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/cloud-resources/database",component:p("/docs/v0.9/kusion/guides/cloud-resources/database","c6f"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/cloud-resources/expose-service",component:p("/docs/v0.9/kusion/guides/cloud-resources/expose-service","634"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions",component:p("/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions","320"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/observability/prometheus",component:p("/docs/v0.9/kusion/guides/observability/prometheus","278"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/working-with-k8s/",component:p("/docs/v0.9/kusion/guides/working-with-k8s/","83a"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/working-with-k8s/container",component:p("/docs/v0.9/kusion/guides/working-with-k8s/container","72b"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application",component:p("/docs/v0.9/kusion/guides/working-with-k8s/deploy-application","ba7"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade",component:p("/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade","bfc"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec",component:p("/docs/v0.9/kusion/guides/working-with-k8s/resource-spec","30c"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/guides/working-with-k8s/service",component:p("/docs/v0.9/kusion/guides/working-with-k8s/service","928"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/intro/kusion-vs-x",component:p("/docs/v0.9/kusion/intro/kusion-vs-x","bd5"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/",component:p("/docs/v0.9/kusion/reference/cli/","523"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/backend/backend-configuration",component:p("/docs/v0.9/kusion/reference/cli/backend/backend-configuration","d38"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/",component:p("/docs/v0.9/kusion/reference/cli/kusion/","f8e"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply",component:p("/docs/v0.9/kusion/reference/cli/kusion/kusion_apply","885"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/kusion_build",component:p("/docs/v0.9/kusion/reference/cli/kusion/kusion_build","3a0"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile",component:p("/docs/v0.9/kusion/reference/cli/kusion/kusion_compile","8bf"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy",component:p("/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy","4e3"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/kusion_init",component:p("/docs/v0.9/kusion/reference/cli/kusion/kusion_init","d8e"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview",component:p("/docs/v0.9/kusion/reference/cli/kusion/kusion_preview","b1c"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/cli/kusion/kusion_version",component:p("/docs/v0.9/kusion/reference/cli/kusion/kusion_version","bfa"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/",component:p("/docs/v0.9/kusion/reference/model/","ca6"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database",component:p("/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database","d38"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration",component:p("/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration","3ba"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container",component:p("/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container","03c"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle",component:p("/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle","c7a"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe",component:p("/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe","855"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common",component:p("/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common","190"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port",component:p("/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port","a7c"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret",component:p("/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret","467"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus",component:p("/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus","8b1"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule",component:p("/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule","3c8"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job",component:p("/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job","e80"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service",component:p("/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service","df4"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/naming-conventions",component:p("/docs/v0.9/kusion/reference/model/naming-conventions","f14"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/overview",component:p("/docs/v0.9/kusion/reference/model/overview","4e8"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/model/project-stack-config-items",component:p("/docs/v0.9/kusion/reference/model/project-stack-config-items","86d"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/reference/roadmap",component:p("/docs/v0.9/kusion/reference/roadmap","b96"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/support/",component:p("/docs/v0.9/kusion/support/","0c4"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/support/install-error",component:p("/docs/v0.9/kusion/support/install-error","7ec"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/kusion/support/kcl",component:p("/docs/v0.9/kusion/support/kcl","e43"),exact:!0,sidebar:"kusion"},{path:"/docs/v0.9/operating/concepts/podopslifecycle",component:p("/docs/v0.9/operating/concepts/podopslifecycle","fa7"),exact:!0,sidebar:"operating"},{path:"/docs/v0.9/operating/introduction/",component:p("/docs/v0.9/operating/introduction/","3ef"),exact:!0,sidebar:"operating"},{path:"/docs/v0.9/operating/manuals/collaset",component:p("/docs/v0.9/operating/manuals/collaset","836"),exact:!0,sidebar:"operating"},{path:"/docs/v0.9/operating/manuals/poddecoration",component:p("/docs/v0.9/operating/manuals/poddecoration","cf6"),exact:!0,sidebar:"operating"},{path:"/docs/v0.9/operating/manuals/podtransitionrule",component:p("/docs/v0.9/operating/manuals/podtransitionrule","e23"),exact:!0,sidebar:"operating"},{path:"/docs/v0.9/operating/manuals/resourceconsist",component:p("/docs/v0.9/operating/manuals/resourceconsist","595"),exact:!0,sidebar:"operating"},{path:"/docs/v0.9/operating/started/demo-graceful-operation",component:p("/docs/v0.9/operating/started/demo-graceful-operation","902"),exact:!0,sidebar:"operating"},{path:"/docs/v0.9/operating/started/install",component:p("/docs/v0.9/operating/started/install","714"),exact:!0,sidebar:"operating"}]},{path:"/docs",component:p("/docs","ceb"),routes:[{path:"/docs/",component:p("/docs/","418"),exact:!0,sidebar:"kusion"},{path:"/docs/community/intro/",component:p("/docs/community/intro/","dd6"),exact:!0,sidebar:"community"},{path:"/docs/ctrlmesh/concepts/",component:p("/docs/ctrlmesh/concepts/","90a"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/ctrlmesh/faq/",component:p("/docs/ctrlmesh/faq/","a2c"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/ctrlmesh/intro/",component:p("/docs/ctrlmesh/intro/","0cb"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/ctrlmesh/started/install",component:p("/docs/ctrlmesh/started/install","114"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/ctrlmesh/started/try",component:p("/docs/ctrlmesh/started/try","045"),exact:!0,sidebar:"ctrlmesh"},{path:"/docs/kusion/concepts/app-configuration",component:p("/docs/kusion/concepts/app-configuration","92e"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/backend-configuration",component:p("/docs/kusion/concepts/backend-configuration","51c"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/how-kusion-works",component:p("/docs/kusion/concepts/how-kusion-works","bc4"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/intent",component:p("/docs/kusion/concepts/intent","d6c"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/kusion-module",component:p("/docs/kusion/concepts/kusion-module","e09"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/project/configuration",component:p("/docs/kusion/concepts/project/configuration","59a"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/project/overview",component:p("/docs/kusion/concepts/project/overview","474"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/stack/configuration",component:p("/docs/kusion/concepts/stack/configuration","51f"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/stack/overview",component:p("/docs/kusion/concepts/stack/overview","98a"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/concepts/workspace",component:p("/docs/kusion/concepts/workspace","4d7"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/base-override",component:p("/docs/kusion/configuration-walkthrough/base-override","ac9"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/databse",component:p("/docs/kusion/configuration-walkthrough/databse","8fa"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/kcl-basics",component:p("/docs/kusion/configuration-walkthrough/kcl-basics","f08"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/monitoring",component:p("/docs/kusion/configuration-walkthrough/monitoring","8c6"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/networking",component:p("/docs/kusion/configuration-walkthrough/networking","371"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/operational-rules",component:p("/docs/kusion/configuration-walkthrough/operational-rules","f51"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/overview",component:p("/docs/kusion/configuration-walkthrough/overview","c07"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/secret",component:p("/docs/kusion/configuration-walkthrough/secret","330"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/configuration-walkthrough/workload",component:p("/docs/kusion/configuration-walkthrough/workload","20d"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/faq/install-error",component:p("/docs/kusion/faq/install-error","1ff"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/faq/kcl",component:p("/docs/kusion/faq/kcl","e1f"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/getting-started/deliver-wordpress",component:p("/docs/kusion/getting-started/deliver-wordpress","4cb"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/getting-started/install-kusion",component:p("/docs/kusion/getting-started/install-kusion","bb0"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/",component:p("/docs/kusion/reference/commands/","e8f"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-apply",component:p("/docs/kusion/reference/commands/kusion-apply","d42"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-build",component:p("/docs/kusion/reference/commands/kusion-build","39e"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-compile",component:p("/docs/kusion/reference/commands/kusion-compile","3f9"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-destroy",component:p("/docs/kusion/reference/commands/kusion-destroy","36e"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-init",component:p("/docs/kusion/reference/commands/kusion-init","d3e"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-preview",component:p("/docs/kusion/reference/commands/kusion-preview","e73"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-version",component:p("/docs/kusion/reference/commands/kusion-version","284"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-workspace",component:p("/docs/kusion/reference/commands/kusion-workspace","4d1"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-workspace-create",component:p("/docs/kusion/reference/commands/kusion-workspace-create","b05"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-workspace-delete",component:p("/docs/kusion/reference/commands/kusion-workspace-delete","96f"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-workspace-list",component:p("/docs/kusion/reference/commands/kusion-workspace-list","4b3"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-workspace-show",component:p("/docs/kusion/reference/commands/kusion-workspace-show","909"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/commands/kusion-workspace-update",component:p("/docs/kusion/reference/commands/kusion-workspace-update","cd3"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/",component:p("/docs/kusion/reference/modules/","5d1"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/app-configuration",component:p("/docs/kusion/reference/modules/catalog-models/app-configuration","948"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/database/mysql",component:p("/docs/kusion/reference/modules/catalog-models/database/mysql","594"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/database/postgres",component:p("/docs/kusion/reference/modules/catalog-models/database/postgres","0de"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/internal/common",component:p("/docs/kusion/reference/modules/catalog-models/internal/common","9f4"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/internal/container/",component:p("/docs/kusion/reference/modules/catalog-models/internal/container/","3ed"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/",component:p("/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/","23f"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/internal/container/probe/",component:p("/docs/kusion/reference/modules/catalog-models/internal/container/probe/","b4d"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/internal/network/port",component:p("/docs/kusion/reference/modules/catalog-models/internal/network/port","ba4"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/internal/secret/",component:p("/docs/kusion/reference/modules/catalog-models/internal/secret/","0bd"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus",component:p("/docs/kusion/reference/modules/catalog-models/monitoring/prometheus","297"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/trait/opsrule",component:p("/docs/kusion/reference/modules/catalog-models/trait/opsrule","d59"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/workload/job",component:p("/docs/kusion/reference/modules/catalog-models/workload/job","f14"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/catalog-models/workload/service",component:p("/docs/kusion/reference/modules/catalog-models/workload/service","168"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/naming-conventions",component:p("/docs/kusion/reference/modules/naming-conventions","3d3"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/workspace-configs/database/mysql",component:p("/docs/kusion/reference/modules/workspace-configs/database/mysql","3d7"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/workspace-configs/database/postgres",component:p("/docs/kusion/reference/modules/workspace-configs/database/postgres","cf2"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus",component:p("/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus","ebf"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/workspace-configs/networking/port",component:p("/docs/kusion/reference/modules/workspace-configs/networking/port","af5"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/workspace-configs/trait/opsrule",component:p("/docs/kusion/reference/modules/workspace-configs/trait/opsrule","945"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/workspace-configs/workload/job",component:p("/docs/kusion/reference/modules/workspace-configs/workload/job","284"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/modules/workspace-configs/workload/service",component:p("/docs/kusion/reference/modules/workspace-configs/workload/service","24b"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/reference/roadmap",component:p("/docs/kusion/reference/roadmap","3b4"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/cloud-resources/database",component:p("/docs/kusion/user-guides/cloud-resources/database","daf"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/cloud-resources/expose-service",component:p("/docs/kusion/user-guides/cloud-resources/expose-service","591"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions",component:p("/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions","77d"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/observability/prometheus",component:p("/docs/kusion/user-guides/observability/prometheus","f25"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/secrets-management/using-cloud-secrets",component:p("/docs/kusion/user-guides/secrets-management/using-cloud-secrets","b75"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/working-with-k8s/container",component:p("/docs/kusion/user-guides/working-with-k8s/container","924"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/working-with-k8s/deploy-application",component:p("/docs/kusion/user-guides/working-with-k8s/deploy-application","6ca"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/working-with-k8s/image-upgrade",component:p("/docs/kusion/user-guides/working-with-k8s/image-upgrade","7f4"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/working-with-k8s/job",component:p("/docs/kusion/user-guides/working-with-k8s/job","e93"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/working-with-k8s/resource-spec",component:p("/docs/kusion/user-guides/working-with-k8s/resource-spec","d22"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/working-with-k8s/service",component:p("/docs/kusion/user-guides/working-with-k8s/service","958"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules",component:p("/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules","c22"),exact:!0,sidebar:"kusion"},{path:"/docs/kusion/what-is-kusion/kusion-vs-x",component:p("/docs/kusion/what-is-kusion/kusion-vs-x","5eb"),exact:!0,sidebar:"kusion"},{path:"/docs/operating/concepts/podopslifecycle",component:p("/docs/operating/concepts/podopslifecycle","87b"),exact:!0,sidebar:"operating"},{path:"/docs/operating/introduction/",component:p("/docs/operating/introduction/","c0a"),exact:!0,sidebar:"operating"},{path:"/docs/operating/manuals/collaset",component:p("/docs/operating/manuals/collaset","e33"),exact:!0,sidebar:"operating"},{path:"/docs/operating/manuals/poddecoration",component:p("/docs/operating/manuals/poddecoration","3c3"),exact:!0,sidebar:"operating"},{path:"/docs/operating/manuals/podtransitionrule",component:p("/docs/operating/manuals/podtransitionrule","8a8"),exact:!0,sidebar:"operating"},{path:"/docs/operating/manuals/resourceconsist",component:p("/docs/operating/manuals/resourceconsist","68f"),exact:!0,sidebar:"operating"},{path:"/docs/operating/started/demo-graceful-operation",component:p("/docs/operating/started/demo-graceful-operation","a88"),exact:!0,sidebar:"operating"},{path:"/docs/operating/started/install",component:p("/docs/operating/started/install","490"),exact:!0,sidebar:"operating"}]},{path:"/",component:p("/","2da"),exact:!0},{path:"*",component:p("*")}]},98934:(e,n,t)=>{"use strict";t.d(n,{_:()=>r,t:()=>i});var o=t(67294);const r=o.createContext(!1);function i(e){let{children:n}=e;const[t,i]=(0,o.useState)(!1);return(0,o.useEffect)((()=>{i(!0)}),[]),o.createElement(r.Provider,{value:t},n)}},49383:(e,n,t)=>{"use strict";var o=t(67294),r=t(73935),i=t(73727),a=t(70405),s=t(10412);const c=[t(56657),t(32497),t(3310),t(18320),t(52295)];var l=t(723),u=t(76775),d=t(18790);function p(e){let{children:n}=e;return o.createElement(o.Fragment,null,n)}var f=t(87462),m=t(35742),g=t(52263),h=t(44996),k=t(86668),b=t(10833),v=t(94711),w=t(19727),y=t(43320),_=t(90197);function x(){const{i18n:{defaultLocale:e,localeConfigs:n}}=(0,g.Z)(),t=(0,v.l)();return o.createElement(m.Z,null,Object.entries(n).map((e=>{let[n,{htmlLang:r}]=e;return o.createElement("link",{key:n,rel:"alternate",href:t.createUrl({locale:n,fullyQualified:!0}),hrefLang:r})})),o.createElement("link",{rel:"alternate",href:t.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function E(e){let{permalink:n}=e;const{siteConfig:{url:t}}=(0,g.Z)(),r=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:n}=(0,u.TH)();return e+(0,h.Z)(n)}(),i=n?`${t}${n}`:r;return o.createElement(m.Z,null,o.createElement("meta",{property:"og:url",content:i}),o.createElement("link",{rel:"canonical",href:i}))}function S(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:n,image:t}=(0,k.L)();return o.createElement(o.Fragment,null,o.createElement(m.Z,null,o.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),o.createElement("body",{className:w.h})),t&&o.createElement(b.d,{image:t}),o.createElement(E,null),o.createElement(x,null),o.createElement(_.Z,{tag:y.HX,locale:e}),o.createElement(m.Z,null,n.map(((e,n)=>o.createElement("meta",(0,f.Z)({key:n},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(l.Z,e.pathname).some((e=>{let{route:n}=e;return!0===n.exact})))return C.set(e.pathname,e.pathname),e;const n=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,n),{...e,pathname:n}}var A=t(98934),L=t(58940);function P(e){for(var n=arguments.length,t=new Array(n>1?n-1:0),o=1;o{var o;const r=(null==(o=n.default)?void 0:o[e])??n[e];return null==r?void 0:r(...t)}));return()=>r.forEach((e=>null==e?void 0:e()))}const R=function(e){let{children:n,location:t,previousLocation:r}=e;return(0,o.useLayoutEffect)((()=>{r!==t&&(!function(e){let{location:n,previousLocation:t}=e;if(!t)return;const o=n.pathname===t.pathname,r=n.hash===t.hash,i=n.search===t.search;if(o&&r&&!i)return;const{hash:a}=n;if(a){const e=decodeURIComponent(a.substring(1)),n=document.getElementById(e);null==n||n.scrollIntoView()}else window.scrollTo(0,0)}({location:t,previousLocation:r}),P("onRouteDidUpdate",{previousLocation:r,location:t}))}),[r,t]),n};function N(e){const n=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(l.Z,e))).flat();return Promise.all(n.map((e=>null==e.route.component.preload?void 0:e.route.component.preload())))}class O extends o.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,n){if(e.location===this.props.location)return n.nextRouteHasLoaded;const t=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:t}),N(t.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:n}=this.props;return o.createElement(R,{previousLocation:this.previousLocation,location:n},o.createElement(u.AW,{location:n,render:()=>e}))}}const I=O,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner-suggestion-container",j="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${j}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${j}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[j]=!1}),[]),o.createElement(o.Fragment,null,!s.Z.canUseDOM&&o.createElement(m.Z,null,o.createElement("script",null,B(e))),o.createElement("div",{id:D}))}function z(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:n}}=(0,g.Z)(),{pathname:t}=(0,u.TH)();return n&&t===e?o.createElement(F,null):null}function U(){const{siteConfig:{favicon:e,title:n,noIndex:t},i18n:{currentLocale:r,localeConfigs:i}}=(0,g.Z)(),a=(0,h.Z)(e),{htmlLang:s,direction:c}=i[r];return o.createElement(m.Z,null,o.createElement("html",{lang:s,dir:c}),o.createElement("title",null,n),o.createElement("meta",{property:"og:title",content:n}),o.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),t&&o.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&o.createElement("link",{rel:"icon",href:a}))}var q=t(44763);function $(){const e=(0,d.H)(l.Z),n=(0,u.TH)();return o.createElement(q.Z,null,o.createElement(L.M,null,o.createElement(A.t,null,o.createElement(p,null,o.createElement(U,null),o.createElement(S,null),o.createElement(z,null),o.createElement(I,{location:T(n)},e)))))}var G=t(16887);const H=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((n,t)=>{var o;if("undefined"==typeof document)return void t();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>n(),r.onerror=()=>t();const i=document.getElementsByTagName("head")[0]??(null==(o=document.getElementsByName("script")[0])?void 0:o.parentNode);null==i||i.appendChild(r)}))}:function(e){return new Promise(((n,t)=>{const o=new XMLHttpRequest;o.open("GET",e,!0),o.withCredentials=!0,o.onload=()=>{200===o.status?n():t()},o.send(null)}))};var Z=t(99670);const V=new Set,W=new Set,K=()=>{var e,n;return(null==(e=navigator.connection)?void 0:e.effectiveType.includes("2g"))||(null==(n=navigator.connection)?void 0:n.saveData)},Y={prefetch(e){if(!(e=>!K()&&!W.has(e)&&!V.has(e))(e))return!1;V.add(e);const n=(0,d.f)(l.Z,e).flatMap((e=>{return n=e.route.path,Object.entries(G).filter((e=>{let[t]=e;return t.replace(/-[^-]+$/,"")===n})).flatMap((e=>{let[,n]=e;return Object.values((0,Z.Z)(n))}));var n}));return Promise.all(n.map((e=>{const n=t.gca(e);return n&&!n.includes("undefined")?H(n).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!W.has(e))(e)&&(W.add(e),N(e))},Q=Object.freeze(Y);if(s.Z.canUseDOM){window.docusaurus=Q;const e=r.hydrate;N(window.location.pathname).then((()=>{e(o.createElement(a.B6,null,o.createElement(i.VK,null,o.createElement($,null))),document.getElementById("__docusaurus"))}))}},58940:(e,n,t)=>{"use strict";t.d(n,{_:()=>u,M:()=>d});var o=t(67294),r=t(36809);const i=JSON.parse('{"docusaurus-plugin-google-gtag":{"default":{"trackingID":["G-XC4Z27TLBR"],"anonymizeIP":false,"id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"v0.11 \ud83d\udea7","isLast":false,"path":"/docs/next","mainDocId":"kusion/what-is-kusion/overview","docs":[{"id":"community/intro/intro","path":"/docs/next/community/intro/","sidebar":"community"},{"id":"ctrlmesh/concepts/concepts","path":"/docs/next/ctrlmesh/concepts/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/faq/faq","path":"/docs/next/ctrlmesh/faq/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/intro/intro","path":"/docs/next/ctrlmesh/intro/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/started/install","path":"/docs/next/ctrlmesh/started/install","sidebar":"ctrlmesh"},{"id":"ctrlmesh/started/try","path":"/docs/next/ctrlmesh/started/try","sidebar":"ctrlmesh"},{"id":"kusion/concepts/app-configuration","path":"/docs/next/kusion/concepts/app-configuration","sidebar":"kusion"},{"id":"kusion/concepts/backend","path":"/docs/next/kusion/concepts/backend","sidebar":"kusion"},{"id":"kusion/concepts/configuration","path":"/docs/next/kusion/concepts/configuration","sidebar":"kusion"},{"id":"kusion/concepts/how-kusion-works","path":"/docs/next/kusion/concepts/how-kusion-works","sidebar":"kusion"},{"id":"kusion/concepts/intent","path":"/docs/next/kusion/concepts/intent","sidebar":"kusion"},{"id":"kusion/concepts/kusion-module","path":"/docs/next/kusion/concepts/kusion-module","sidebar":"kusion"},{"id":"kusion/concepts/project/configuration","path":"/docs/next/kusion/concepts/project/configuration","sidebar":"kusion"},{"id":"kusion/concepts/project/overview","path":"/docs/next/kusion/concepts/project/overview","sidebar":"kusion"},{"id":"kusion/concepts/stack/configuration","path":"/docs/next/kusion/concepts/stack/configuration","sidebar":"kusion"},{"id":"kusion/concepts/stack/overview","path":"/docs/next/kusion/concepts/stack/overview","sidebar":"kusion"},{"id":"kusion/concepts/workspace","path":"/docs/next/kusion/concepts/workspace","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/base-override","path":"/docs/next/kusion/configuration-walkthrough/base-override","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/databse","path":"/docs/next/kusion/configuration-walkthrough/databse","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/kcl-basics","path":"/docs/next/kusion/configuration-walkthrough/kcl-basics","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/monitoring","path":"/docs/next/kusion/configuration-walkthrough/monitoring","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/networking","path":"/docs/next/kusion/configuration-walkthrough/networking","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/operational-rules","path":"/docs/next/kusion/configuration-walkthrough/operational-rules","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/overview","path":"/docs/next/kusion/configuration-walkthrough/overview","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/secret","path":"/docs/next/kusion/configuration-walkthrough/secret","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/workload","path":"/docs/next/kusion/configuration-walkthrough/workload","sidebar":"kusion"},{"id":"kusion/faq/install-error","path":"/docs/next/kusion/faq/install-error","sidebar":"kusion"},{"id":"kusion/faq/kcl","path":"/docs/next/kusion/faq/kcl","sidebar":"kusion"},{"id":"kusion/getting-started/deliver-wordpress","path":"/docs/next/kusion/getting-started/deliver-wordpress","sidebar":"kusion"},{"id":"kusion/getting-started/install-kusion","path":"/docs/next/kusion/getting-started/install-kusion","sidebar":"kusion"},{"id":"kusion/reference/commands/index","path":"/docs/next/kusion/reference/commands/","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-apply","path":"/docs/next/kusion/reference/commands/kusion-apply","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-build","path":"/docs/next/kusion/reference/commands/kusion-build","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-compile","path":"/docs/next/kusion/reference/commands/kusion-compile","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-destroy","path":"/docs/next/kusion/reference/commands/kusion-destroy","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-init","path":"/docs/next/kusion/reference/commands/kusion-init","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-preview","path":"/docs/next/kusion/reference/commands/kusion-preview","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-version","path":"/docs/next/kusion/reference/commands/kusion-version","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace","path":"/docs/next/kusion/reference/commands/kusion-workspace","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-create","path":"/docs/next/kusion/reference/commands/kusion-workspace-create","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-delete","path":"/docs/next/kusion/reference/commands/kusion-workspace-delete","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-list","path":"/docs/next/kusion/reference/commands/kusion-workspace-list","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-show","path":"/docs/next/kusion/reference/commands/kusion-workspace-show","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-update","path":"/docs/next/kusion/reference/commands/kusion-workspace-update","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/app-configuration","path":"/docs/next/kusion/reference/modules/catalog-models/app-configuration","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/database/mysql","path":"/docs/next/kusion/reference/modules/catalog-models/database/mysql","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/database/postgres","path":"/docs/next/kusion/reference/modules/catalog-models/database/postgres","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/common","path":"/docs/next/kusion/reference/modules/catalog-models/internal/common","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/container/container","path":"/docs/next/kusion/reference/modules/catalog-models/internal/container/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle","path":"/docs/next/kusion/reference/modules/catalog-models/internal/container/lifecycle/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/container/probe/probe","path":"/docs/next/kusion/reference/modules/catalog-models/internal/container/probe/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/network/port","path":"/docs/next/kusion/reference/modules/catalog-models/internal/network/port","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/secret/secret","path":"/docs/next/kusion/reference/modules/catalog-models/internal/secret/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/monitoring/prometheus","path":"/docs/next/kusion/reference/modules/catalog-models/monitoring/prometheus","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/trait/opsrule","path":"/docs/next/kusion/reference/modules/catalog-models/trait/opsrule","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/workload/job","path":"/docs/next/kusion/reference/modules/catalog-models/workload/job","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/workload/service","path":"/docs/next/kusion/reference/modules/catalog-models/workload/service","sidebar":"kusion"},{"id":"kusion/reference/modules/index","path":"/docs/next/kusion/reference/modules/","sidebar":"kusion"},{"id":"kusion/reference/modules/naming-conventions","path":"/docs/next/kusion/reference/modules/naming-conventions","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/database/mysql","path":"/docs/next/kusion/reference/modules/workspace-configs/database/mysql","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/database/postgres","path":"/docs/next/kusion/reference/modules/workspace-configs/database/postgres","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/monitoring/prometheus","path":"/docs/next/kusion/reference/modules/workspace-configs/monitoring/prometheus","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/networking/port","path":"/docs/next/kusion/reference/modules/workspace-configs/networking/port","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/trait/opsrule","path":"/docs/next/kusion/reference/modules/workspace-configs/trait/opsrule","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/workload/job","path":"/docs/next/kusion/reference/modules/workspace-configs/workload/job","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/workload/service","path":"/docs/next/kusion/reference/modules/workspace-configs/workload/service","sidebar":"kusion"},{"id":"kusion/reference/roadmap","path":"/docs/next/kusion/reference/roadmap","sidebar":"kusion"},{"id":"kusion/user-guides/cloud-resources/database","path":"/docs/next/kusion/user-guides/cloud-resources/database","sidebar":"kusion"},{"id":"kusion/user-guides/cloud-resources/expose-service","path":"/docs/next/kusion/user-guides/cloud-resources/expose-service","sidebar":"kusion"},{"id":"kusion/user-guides/github-actions/deploy-application-via-github-actions","path":"/docs/next/kusion/user-guides/github-actions/deploy-application-via-github-actions","sidebar":"kusion"},{"id":"kusion/user-guides/observability/prometheus","path":"/docs/next/kusion/user-guides/observability/prometheus","sidebar":"kusion"},{"id":"kusion/user-guides/secrets-management/using-cloud-secrets","path":"/docs/next/kusion/user-guides/secrets-management/using-cloud-secrets","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/container","path":"/docs/next/kusion/user-guides/working-with-k8s/container","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/deploy-application","path":"/docs/next/kusion/user-guides/working-with-k8s/deploy-application","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/image-upgrade","path":"/docs/next/kusion/user-guides/working-with-k8s/image-upgrade","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/job","path":"/docs/next/kusion/user-guides/working-with-k8s/job","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/resource-spec","path":"/docs/next/kusion/user-guides/working-with-k8s/resource-spec","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/service","path":"/docs/next/kusion/user-guides/working-with-k8s/service","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/set-up-operational-rules","path":"/docs/next/kusion/user-guides/working-with-k8s/set-up-operational-rules","sidebar":"kusion"},{"id":"kusion/what-is-kusion/kusion-vs-x","path":"/docs/next/kusion/what-is-kusion/kusion-vs-x","sidebar":"kusion"},{"id":"kusion/what-is-kusion/overview","path":"/docs/next/","sidebar":"kusion"},{"id":"operating/concepts/podopslifecycle","path":"/docs/next/operating/concepts/podopslifecycle","sidebar":"operating"},{"id":"operating/introduction/introduction","path":"/docs/next/operating/introduction/","sidebar":"operating"},{"id":"operating/manuals/collaset","path":"/docs/next/operating/manuals/collaset","sidebar":"operating"},{"id":"operating/manuals/poddecoration","path":"/docs/next/operating/manuals/poddecoration","sidebar":"operating"},{"id":"operating/manuals/podtransitionrule","path":"/docs/next/operating/manuals/podtransitionrule","sidebar":"operating"},{"id":"operating/manuals/resourceconsist","path":"/docs/next/operating/manuals/resourceconsist","sidebar":"operating"},{"id":"operating/started/demo-graceful-operation","path":"/docs/next/operating/started/demo-graceful-operation","sidebar":"operating"},{"id":"operating/started/install","path":"/docs/next/operating/started/install","sidebar":"operating"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/next/community/intro/","label":"Community"}},"kusion":{"link":{"path":"/docs/next/","label":"kusion/what-is-kusion/overview"}},"operating":{"link":{"path":"/docs/next/operating/introduction/","label":"Introduction"}},"community":{"link":{"path":"/docs/next/community/intro/","label":"Community"}},"ctrlmesh":{"link":{"path":"/docs/next/ctrlmesh/intro/","label":"Introduction"}}}},{"name":"v0.10","label":"v0.10","isLast":true,"path":"/docs","mainDocId":"kusion/what-is-kusion/overview","docs":[{"id":"community/intro/intro","path":"/docs/community/intro/","sidebar":"community"},{"id":"ctrlmesh/concepts/concepts","path":"/docs/ctrlmesh/concepts/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/faq/faq","path":"/docs/ctrlmesh/faq/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/intro/intro","path":"/docs/ctrlmesh/intro/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/started/install","path":"/docs/ctrlmesh/started/install","sidebar":"ctrlmesh"},{"id":"ctrlmesh/started/try","path":"/docs/ctrlmesh/started/try","sidebar":"ctrlmesh"},{"id":"kusion/concepts/app-configuration","path":"/docs/kusion/concepts/app-configuration","sidebar":"kusion"},{"id":"kusion/concepts/backend-configuration","path":"/docs/kusion/concepts/backend-configuration","sidebar":"kusion"},{"id":"kusion/concepts/how-kusion-works","path":"/docs/kusion/concepts/how-kusion-works","sidebar":"kusion"},{"id":"kusion/concepts/intent","path":"/docs/kusion/concepts/intent","sidebar":"kusion"},{"id":"kusion/concepts/kusion-module","path":"/docs/kusion/concepts/kusion-module","sidebar":"kusion"},{"id":"kusion/concepts/project/configuration","path":"/docs/kusion/concepts/project/configuration","sidebar":"kusion"},{"id":"kusion/concepts/project/overview","path":"/docs/kusion/concepts/project/overview","sidebar":"kusion"},{"id":"kusion/concepts/stack/configuration","path":"/docs/kusion/concepts/stack/configuration","sidebar":"kusion"},{"id":"kusion/concepts/stack/overview","path":"/docs/kusion/concepts/stack/overview","sidebar":"kusion"},{"id":"kusion/concepts/workspace","path":"/docs/kusion/concepts/workspace","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/base-override","path":"/docs/kusion/configuration-walkthrough/base-override","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/databse","path":"/docs/kusion/configuration-walkthrough/databse","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/kcl-basics","path":"/docs/kusion/configuration-walkthrough/kcl-basics","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/monitoring","path":"/docs/kusion/configuration-walkthrough/monitoring","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/networking","path":"/docs/kusion/configuration-walkthrough/networking","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/operational-rules","path":"/docs/kusion/configuration-walkthrough/operational-rules","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/overview","path":"/docs/kusion/configuration-walkthrough/overview","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/secret","path":"/docs/kusion/configuration-walkthrough/secret","sidebar":"kusion"},{"id":"kusion/configuration-walkthrough/workload","path":"/docs/kusion/configuration-walkthrough/workload","sidebar":"kusion"},{"id":"kusion/faq/install-error","path":"/docs/kusion/faq/install-error","sidebar":"kusion"},{"id":"kusion/faq/kcl","path":"/docs/kusion/faq/kcl","sidebar":"kusion"},{"id":"kusion/getting-started/deliver-wordpress","path":"/docs/kusion/getting-started/deliver-wordpress","sidebar":"kusion"},{"id":"kusion/getting-started/install-kusion","path":"/docs/kusion/getting-started/install-kusion","sidebar":"kusion"},{"id":"kusion/reference/commands/index","path":"/docs/kusion/reference/commands/","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-apply","path":"/docs/kusion/reference/commands/kusion-apply","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-build","path":"/docs/kusion/reference/commands/kusion-build","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-compile","path":"/docs/kusion/reference/commands/kusion-compile","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-destroy","path":"/docs/kusion/reference/commands/kusion-destroy","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-init","path":"/docs/kusion/reference/commands/kusion-init","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-preview","path":"/docs/kusion/reference/commands/kusion-preview","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-version","path":"/docs/kusion/reference/commands/kusion-version","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace","path":"/docs/kusion/reference/commands/kusion-workspace","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-create","path":"/docs/kusion/reference/commands/kusion-workspace-create","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-delete","path":"/docs/kusion/reference/commands/kusion-workspace-delete","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-list","path":"/docs/kusion/reference/commands/kusion-workspace-list","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-show","path":"/docs/kusion/reference/commands/kusion-workspace-show","sidebar":"kusion"},{"id":"kusion/reference/commands/kusion-workspace-update","path":"/docs/kusion/reference/commands/kusion-workspace-update","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/app-configuration","path":"/docs/kusion/reference/modules/catalog-models/app-configuration","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/database/mysql","path":"/docs/kusion/reference/modules/catalog-models/database/mysql","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/database/postgres","path":"/docs/kusion/reference/modules/catalog-models/database/postgres","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/common","path":"/docs/kusion/reference/modules/catalog-models/internal/common","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/container/container","path":"/docs/kusion/reference/modules/catalog-models/internal/container/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/container/lifecycle/lifecycle","path":"/docs/kusion/reference/modules/catalog-models/internal/container/lifecycle/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/container/probe/probe","path":"/docs/kusion/reference/modules/catalog-models/internal/container/probe/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/network/port","path":"/docs/kusion/reference/modules/catalog-models/internal/network/port","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/internal/secret/secret","path":"/docs/kusion/reference/modules/catalog-models/internal/secret/","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/monitoring/prometheus","path":"/docs/kusion/reference/modules/catalog-models/monitoring/prometheus","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/trait/opsrule","path":"/docs/kusion/reference/modules/catalog-models/trait/opsrule","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/workload/job","path":"/docs/kusion/reference/modules/catalog-models/workload/job","sidebar":"kusion"},{"id":"kusion/reference/modules/catalog-models/workload/service","path":"/docs/kusion/reference/modules/catalog-models/workload/service","sidebar":"kusion"},{"id":"kusion/reference/modules/index","path":"/docs/kusion/reference/modules/","sidebar":"kusion"},{"id":"kusion/reference/modules/naming-conventions","path":"/docs/kusion/reference/modules/naming-conventions","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/database/mysql","path":"/docs/kusion/reference/modules/workspace-configs/database/mysql","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/database/postgres","path":"/docs/kusion/reference/modules/workspace-configs/database/postgres","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/monitoring/prometheus","path":"/docs/kusion/reference/modules/workspace-configs/monitoring/prometheus","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/networking/port","path":"/docs/kusion/reference/modules/workspace-configs/networking/port","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/trait/opsrule","path":"/docs/kusion/reference/modules/workspace-configs/trait/opsrule","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/workload/job","path":"/docs/kusion/reference/modules/workspace-configs/workload/job","sidebar":"kusion"},{"id":"kusion/reference/modules/workspace-configs/workload/service","path":"/docs/kusion/reference/modules/workspace-configs/workload/service","sidebar":"kusion"},{"id":"kusion/reference/roadmap","path":"/docs/kusion/reference/roadmap","sidebar":"kusion"},{"id":"kusion/user-guides/cloud-resources/database","path":"/docs/kusion/user-guides/cloud-resources/database","sidebar":"kusion"},{"id":"kusion/user-guides/cloud-resources/expose-service","path":"/docs/kusion/user-guides/cloud-resources/expose-service","sidebar":"kusion"},{"id":"kusion/user-guides/github-actions/deploy-application-via-github-actions","path":"/docs/kusion/user-guides/github-actions/deploy-application-via-github-actions","sidebar":"kusion"},{"id":"kusion/user-guides/observability/prometheus","path":"/docs/kusion/user-guides/observability/prometheus","sidebar":"kusion"},{"id":"kusion/user-guides/secrets-management/using-cloud-secrets","path":"/docs/kusion/user-guides/secrets-management/using-cloud-secrets","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/container","path":"/docs/kusion/user-guides/working-with-k8s/container","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/deploy-application","path":"/docs/kusion/user-guides/working-with-k8s/deploy-application","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/image-upgrade","path":"/docs/kusion/user-guides/working-with-k8s/image-upgrade","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/job","path":"/docs/kusion/user-guides/working-with-k8s/job","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/resource-spec","path":"/docs/kusion/user-guides/working-with-k8s/resource-spec","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/service","path":"/docs/kusion/user-guides/working-with-k8s/service","sidebar":"kusion"},{"id":"kusion/user-guides/working-with-k8s/set-up-operational-rules","path":"/docs/kusion/user-guides/working-with-k8s/set-up-operational-rules","sidebar":"kusion"},{"id":"kusion/what-is-kusion/kusion-vs-x","path":"/docs/kusion/what-is-kusion/kusion-vs-x","sidebar":"kusion"},{"id":"kusion/what-is-kusion/overview","path":"/docs/","sidebar":"kusion"},{"id":"operating/concepts/podopslifecycle","path":"/docs/operating/concepts/podopslifecycle","sidebar":"operating"},{"id":"operating/introduction/introduction","path":"/docs/operating/introduction/","sidebar":"operating"},{"id":"operating/manuals/collaset","path":"/docs/operating/manuals/collaset","sidebar":"operating"},{"id":"operating/manuals/poddecoration","path":"/docs/operating/manuals/poddecoration","sidebar":"operating"},{"id":"operating/manuals/podtransitionrule","path":"/docs/operating/manuals/podtransitionrule","sidebar":"operating"},{"id":"operating/manuals/resourceconsist","path":"/docs/operating/manuals/resourceconsist","sidebar":"operating"},{"id":"operating/started/demo-graceful-operation","path":"/docs/operating/started/demo-graceful-operation","sidebar":"operating"},{"id":"operating/started/install","path":"/docs/operating/started/install","sidebar":"operating"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/community/intro/","label":"Community"}},"kusion":{"link":{"path":"/docs/","label":"version-v0.10/kusion/what-is-kusion/overview"}},"operating":{"link":{"path":"/docs/operating/introduction/","label":"Introduction"}},"community":{"link":{"path":"/docs/community/intro/","label":"Community"}},"ctrlmesh":{"link":{"path":"/docs/ctrlmesh/intro/","label":"Introduction"}}}},{"name":"v0.9","label":"v0.9","isLast":false,"path":"/docs/v0.9","mainDocId":"kusion/intro/overview","docs":[{"id":"community/intro/intro","path":"/docs/v0.9/community/intro/","sidebar":"community"},{"id":"ctrlmesh/concepts/concepts","path":"/docs/v0.9/ctrlmesh/concepts/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/faq/faq","path":"/docs/v0.9/ctrlmesh/faq/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/intro/intro","path":"/docs/v0.9/ctrlmesh/intro/","sidebar":"ctrlmesh"},{"id":"ctrlmesh/started/install","path":"/docs/v0.9/ctrlmesh/started/install","sidebar":"ctrlmesh"},{"id":"ctrlmesh/started/try","path":"/docs/v0.9/ctrlmesh/started/try","sidebar":"ctrlmesh"},{"id":"kusion/concepts/appconfiguration","path":"/docs/v0.9/kusion/concepts/appconfiguration","sidebar":"kusion"},{"id":"kusion/concepts/arch","path":"/docs/v0.9/kusion/concepts/arch","sidebar":"kusion"},{"id":"kusion/concepts/glossary","path":"/docs/v0.9/kusion/concepts/glossary","sidebar":"kusion"},{"id":"kusion/concepts/index","path":"/docs/v0.9/kusion/concepts/","sidebar":"kusion"},{"id":"kusion/concepts/intent","path":"/docs/v0.9/kusion/concepts/intent","sidebar":"kusion"},{"id":"kusion/concepts/kusion","path":"/docs/v0.9/kusion/concepts/kusion","sidebar":"kusion"},{"id":"kusion/config-walkthrough/base_override","path":"/docs/v0.9/kusion/config-walkthrough/base_override","sidebar":"kusion"},{"id":"kusion/config-walkthrough/database","path":"/docs/v0.9/kusion/config-walkthrough/database","sidebar":"kusion"},{"id":"kusion/config-walkthrough/kcl_basics","path":"/docs/v0.9/kusion/config-walkthrough/kcl_basics","sidebar":"kusion"},{"id":"kusion/config-walkthrough/monitoring","path":"/docs/v0.9/kusion/config-walkthrough/monitoring","sidebar":"kusion"},{"id":"kusion/config-walkthrough/networking","path":"/docs/v0.9/kusion/config-walkthrough/networking","sidebar":"kusion"},{"id":"kusion/config-walkthrough/operational_rules","path":"/docs/v0.9/kusion/config-walkthrough/operational_rules","sidebar":"kusion"},{"id":"kusion/config-walkthrough/overview","path":"/docs/v0.9/kusion/config-walkthrough/overview","sidebar":"kusion"},{"id":"kusion/config-walkthrough/secret","path":"/docs/v0.9/kusion/config-walkthrough/secret","sidebar":"kusion"},{"id":"kusion/config-walkthrough/workload","path":"/docs/v0.9/kusion/config-walkthrough/workload","sidebar":"kusion"},{"id":"kusion/getting-started/deliver-wordpress","path":"/docs/v0.9/kusion/getting-started/deliver-wordpress","sidebar":"kusion"},{"id":"kusion/getting-started/getting-started","path":"/docs/v0.9/kusion/getting-started/","sidebar":"kusion"},{"id":"kusion/getting-started/install-kusion","path":"/docs/v0.9/kusion/getting-started/install-kusion","sidebar":"kusion"},{"id":"kusion/guides/cloud-resources/database","path":"/docs/v0.9/kusion/guides/cloud-resources/database","sidebar":"kusion"},{"id":"kusion/guides/cloud-resources/expose-service","path":"/docs/v0.9/kusion/guides/cloud-resources/expose-service","sidebar":"kusion"},{"id":"kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions","path":"/docs/v0.9/kusion/guides/github-actions/deploy-application-securely-and-efficiently-via-github-actions","sidebar":"kusion"},{"id":"kusion/guides/guides","path":"/docs/v0.9/kusion/guides/","sidebar":"kusion"},{"id":"kusion/guides/observability/prometheus","path":"/docs/v0.9/kusion/guides/observability/prometheus","sidebar":"kusion"},{"id":"kusion/guides/working-with-k8s/container","path":"/docs/v0.9/kusion/guides/working-with-k8s/container","sidebar":"kusion"},{"id":"kusion/guides/working-with-k8s/deploy-application","path":"/docs/v0.9/kusion/guides/working-with-k8s/deploy-application","sidebar":"kusion"},{"id":"kusion/guides/working-with-k8s/image-upgrade","path":"/docs/v0.9/kusion/guides/working-with-k8s/image-upgrade","sidebar":"kusion"},{"id":"kusion/guides/working-with-k8s/index","path":"/docs/v0.9/kusion/guides/working-with-k8s/","sidebar":"kusion"},{"id":"kusion/guides/working-with-k8s/resource-spec","path":"/docs/v0.9/kusion/guides/working-with-k8s/resource-spec","sidebar":"kusion"},{"id":"kusion/guides/working-with-k8s/service","path":"/docs/v0.9/kusion/guides/working-with-k8s/service","sidebar":"kusion"},{"id":"kusion/intro/kusion-vs-x","path":"/docs/v0.9/kusion/intro/kusion-vs-x","sidebar":"kusion"},{"id":"kusion/intro/overview","path":"/docs/v0.9/","sidebar":"kusion"},{"id":"kusion/reference/cli/backend/backend-configuration","path":"/docs/v0.9/kusion/reference/cli/backend/backend-configuration","sidebar":"kusion"},{"id":"kusion/reference/cli/index","path":"/docs/v0.9/kusion/reference/cli/","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/index","path":"/docs/v0.9/kusion/reference/cli/kusion/","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/kusion_apply","path":"/docs/v0.9/kusion/reference/cli/kusion/kusion_apply","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/kusion_build","path":"/docs/v0.9/kusion/reference/cli/kusion/kusion_build","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/kusion_compile","path":"/docs/v0.9/kusion/reference/cli/kusion/kusion_compile","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/kusion_destroy","path":"/docs/v0.9/kusion/reference/cli/kusion/kusion_destroy","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/kusion_init","path":"/docs/v0.9/kusion/reference/cli/kusion/kusion_init","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/kusion_preview","path":"/docs/v0.9/kusion/reference/cli/kusion/kusion_preview","sidebar":"kusion"},{"id":"kusion/reference/cli/kusion/kusion_version","path":"/docs/v0.9/kusion/reference/cli/kusion/kusion_version","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/database/doc_database","path":"/docs/v0.9/kusion/reference/model/catalog_models/database/doc_database","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/doc_app_configuration","path":"/docs/v0.9/kusion/reference/model/catalog_models/doc_app_configuration","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/internal/container/doc_container","path":"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/doc_container","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle","path":"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/lifecycle/doc_lifecycle","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/internal/container/probe/doc_probe","path":"/docs/v0.9/kusion/reference/model/catalog_models/internal/container/probe/doc_probe","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/internal/doc_common","path":"/docs/v0.9/kusion/reference/model/catalog_models/internal/doc_common","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/internal/network/doc_port","path":"/docs/v0.9/kusion/reference/model/catalog_models/internal/network/doc_port","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/internal/secret/doc_secret","path":"/docs/v0.9/kusion/reference/model/catalog_models/internal/secret/doc_secret","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/monitoring/doc_prometheus","path":"/docs/v0.9/kusion/reference/model/catalog_models/monitoring/doc_prometheus","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/trait/doc_opsrule","path":"/docs/v0.9/kusion/reference/model/catalog_models/trait/doc_opsrule","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/workload/doc_job","path":"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_job","sidebar":"kusion"},{"id":"kusion/reference/model/catalog_models/workload/doc_service","path":"/docs/v0.9/kusion/reference/model/catalog_models/workload/doc_service","sidebar":"kusion"},{"id":"kusion/reference/model/index","path":"/docs/v0.9/kusion/reference/model/","sidebar":"kusion"},{"id":"kusion/reference/model/naming-conventions","path":"/docs/v0.9/kusion/reference/model/naming-conventions","sidebar":"kusion"},{"id":"kusion/reference/model/overview","path":"/docs/v0.9/kusion/reference/model/overview","sidebar":"kusion"},{"id":"kusion/reference/model/project-stack-config-items","path":"/docs/v0.9/kusion/reference/model/project-stack-config-items","sidebar":"kusion"},{"id":"kusion/reference/roadmap","path":"/docs/v0.9/kusion/reference/roadmap","sidebar":"kusion"},{"id":"kusion/support/install-error","path":"/docs/v0.9/kusion/support/install-error","sidebar":"kusion"},{"id":"kusion/support/kcl","path":"/docs/v0.9/kusion/support/kcl","sidebar":"kusion"},{"id":"kusion/support/support","path":"/docs/v0.9/kusion/support/","sidebar":"kusion"},{"id":"operating/concepts/podopslifecycle","path":"/docs/v0.9/operating/concepts/podopslifecycle","sidebar":"operating"},{"id":"operating/introduction/introduction","path":"/docs/v0.9/operating/introduction/","sidebar":"operating"},{"id":"operating/manuals/collaset","path":"/docs/v0.9/operating/manuals/collaset","sidebar":"operating"},{"id":"operating/manuals/poddecoration","path":"/docs/v0.9/operating/manuals/poddecoration","sidebar":"operating"},{"id":"operating/manuals/podtransitionrule","path":"/docs/v0.9/operating/manuals/podtransitionrule","sidebar":"operating"},{"id":"operating/manuals/resourceconsist","path":"/docs/v0.9/operating/manuals/resourceconsist","sidebar":"operating"},{"id":"operating/started/demo-graceful-operation","path":"/docs/v0.9/operating/started/demo-graceful-operation","sidebar":"operating"},{"id":"operating/started/install","path":"/docs/v0.9/operating/started/install","sidebar":"operating"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/v0.9/community/intro/","label":"Community"}},"kusion":{"link":{"path":"/docs/v0.9/","label":"Overview"}},"operating":{"link":{"path":"/docs/v0.9/operating/introduction/","label":"Introduction"}},"community":{"link":{"path":"/docs/v0.9/community/intro/","label":"Community"}},"ctrlmesh":{"link":{"path":"/docs/v0.9/ctrlmesh/intro/","label":"Introduction"}}}}],"breadcrumbs":true}}}'),a=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=t(57529);const c=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"0.1.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.4.1"}}}'),l={siteConfig:r.default,siteMetadata:c,globalData:i,i18n:a,codeTranslations:s},u=o.createContext(l);function d(e){let{children:n}=e;return o.createElement(u.Provider,{value:l},n)}},44763:(e,n,t)=>{"use strict";t.d(n,{Z:()=>p});var o=t(67294),r=t(10412),i=t(35742),a=t(18780),s=t(49689);function c(e){let{error:n,tryAgain:t}=e;return o.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},o.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),o.createElement("button",{type:"button",onClick:t,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),o.createElement(l,{error:n}))}function l(e){let{error:n}=e;const t=(0,a.getErrorCausalChain)(n).map((e=>e.message)).join("\n\nCause:\n");return o.createElement("p",{style:{whiteSpace:"pre-wrap"}},t)}function u(e){let{error:n,tryAgain:t}=e;return o.createElement(p,{fallback:()=>o.createElement(c,{error:n,tryAgain:t})},o.createElement(i.Z,null,o.createElement("title",null,"Page Error")),o.createElement(s.Z,null,o.createElement(c,{error:n,tryAgain:t})))}const d=e=>o.createElement(u,e);class p extends o.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){r.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:n}=this.state;if(n){const e={error:n,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},10412:(e,n,t)=>{"use strict";t.d(n,{Z:()=>r});const o="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,r={canUseDOM:o,canUseEventListeners:o&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:o&&"IntersectionObserver"in window,canUseViewport:o&&"screen"in window}},35742:(e,n,t)=>{"use strict";t.d(n,{Z:()=>i});var o=t(67294),r=t(70405);function i(e){return o.createElement(r.ql,e)}},39960:(e,n,t)=>{"use strict";t.d(n,{Z:()=>f});var o=t(87462),r=t(67294),i=t(73727),a=t(18780),s=t(52263),c=t(13919),l=t(10412);const u=r.createContext({collectLink:()=>{}});var d=t(44996);function p(e,n){var t;let{isNavLink:p,to:f,href:m,activeClassName:g,isActive:h,"data-noBrokenLinkCheck":k,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:w,baseUrl:y}}=(0,s.Z)(),{withBaseUrl:_}=(0,d.C)(),x=(0,r.useContext)(u),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(n,(()=>E.current));const S=f||m;const C=(0,c.Z)(S),T=null==S?void 0:S.replace("pathname://","");let A=void 0!==T?(L=T,b&&(e=>e.startsWith("/"))(L)?_(L):L):void 0;var L;A&&C&&(A=(0,a.applyTrailingSlash)(A,{trailingSlash:w,baseUrl:y}));const P=(0,r.useRef)(!1),R=p?i.OL:i.rU,N=l.Z.canUseIntersectionObserver,O=(0,r.useRef)(),I=()=>{P.current||null==A||(window.docusaurus.preload(A),P.current=!0)};(0,r.useEffect)((()=>(!N&&C&&null!=A&&window.docusaurus.prefetch(A),()=>{N&&O.current&&O.current.disconnect()})),[O,A,N,C]);const D=(null==(t=A)?void 0:t.startsWith("#"))??!1,M=!A||!C||D;return M||k||x.collectLink(A),M?r.createElement("a",(0,o.Z)({ref:E,href:A},S&&!C&&{target:"_blank",rel:"noopener noreferrer"},v)):r.createElement(R,(0,o.Z)({},v,{onMouseEnter:I,onTouchStart:I,innerRef:e=>{E.current=e,N&&e&&C&&(O.current=new window.IntersectionObserver((n=>{n.forEach((n=>{e===n.target&&(n.isIntersecting||n.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=A&&window.docusaurus.prefetch(A))}))})),O.current.observe(e))},to:A},p&&{isActive:h,activeClassName:g}))}const f=r.forwardRef(p)},95999:(e,n,t)=>{"use strict";t.d(n,{Z:()=>c,I:()=>s});var o=t(67294);function r(e,n){const t=e.split(/(\{\w+\})/).map(((e,t)=>{if(t%2==1){const t=null==n?void 0:n[e.slice(1,-1)];if(void 0!==t)return t}return e}));return t.some((e=>(0,o.isValidElement)(e)))?t.map(((e,n)=>(0,o.isValidElement)(e)?o.cloneElement(e,{key:n}):e)).filter((e=>""!==e)):t.join("")}var i=t(57529);function a(e){let{id:n,message:t}=e;if(void 0===n&&void 0===t)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[n??t]??t??n}function s(e,n){let{message:t,id:o}=e;return r(a({message:t,id:o}),n)}function c(e){let{children:n,id:t,values:i}=e;if(n&&"string"!=typeof n)throw console.warn("Illegal children",n),new Error("The Docusaurus component only accept simple string values");const s=a({message:n,id:t});return o.createElement(o.Fragment,null,r(s,i))}},29935:(e,n,t)=>{"use strict";t.d(n,{m:()=>o});const o="default"},13919:(e,n,t)=>{"use strict";function o(e){return/^(?:\w*:|\/\/)/.test(e)}function r(e){return void 0!==e&&!o(e)}t.d(n,{Z:()=>r,b:()=>o})},44996:(e,n,t)=>{"use strict";t.d(n,{C:()=>a,Z:()=>s});var o=t(67294),r=t(52263),i=t(13919);function a(){const{siteConfig:{baseUrl:e,url:n}}=(0,r.Z)(),t=(0,o.useCallback)(((t,o)=>function(e,n,t,o){let{forcePrependBaseUrl:r=!1,absolute:a=!1}=void 0===o?{}:o;if(!t||t.startsWith("#")||(0,i.b)(t))return t;if(r)return n+t.replace(/^\//,"");if(t===n.replace(/\/$/,""))return n;const s=t.startsWith(n)?t:n+t.replace(/^\//,"");return a?e+s:s}(n,e,t,o)),[n,e]);return{withBaseUrl:t}}function s(e,n){void 0===n&&(n={});const{withBaseUrl:t}=a();return t(e,n)}},52263:(e,n,t)=>{"use strict";t.d(n,{Z:()=>i});var o=t(67294),r=t(58940);function i(){return(0,o.useContext)(r._)}},72389:(e,n,t)=>{"use strict";t.d(n,{Z:()=>i});var o=t(67294),r=t(98934);function i(){return(0,o.useContext)(r._)}},99670:(e,n,t)=>{"use strict";t.d(n,{Z:()=>o});function o(e){const n={};return function e(t,o){Object.entries(t).forEach((t=>{let[r,i]=t;const a=o?`${o}.${r}`:r;var s;"object"==typeof(s=i)&&s&&Object.keys(s).length>0?e(i,a):n[a]=i}))}(e),n}},30226:(e,n,t)=>{"use strict";t.d(n,{_:()=>r,z:()=>i});var o=t(67294);const r=o.createContext(null);function i(e){let{children:n,value:t}=e;const i=o.useContext(r),a=(0,o.useMemo)((()=>function(e){let{parent:n,value:t}=e;if(!n){if(!t)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in t))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return t}const o={...n.data,...null==t?void 0:t.data};return{plugin:n.plugin,data:o}}({parent:i,value:t})),[i,t]);return o.createElement(r.Provider,{value:a},n)}},80143:(e,n,t)=>{"use strict";t.d(n,{Iw:()=>k,gA:()=>f,WS:()=>m,_r:()=>d,Jo:()=>b,zh:()=>p,yW:()=>h,gB:()=>g});var o=t(76775),r=t(52263),i=t(29935);function a(e,n){void 0===n&&(n={});const t=function(){const{globalData:e}=(0,r.Z)();return e}()[e];if(!t&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return t}const s=e=>e.versions.find((e=>e.isLast));function c(e,n){const t=s(e);return[...e.versions.filter((e=>e!==t)),t].find((e=>!!(0,o.LX)(n,{path:e.path,exact:!1,strict:!1})))}function l(e,n){const t=c(e,n),r=null==t?void 0:t.docs.find((e=>!!(0,o.LX)(n,{path:e.path,exact:!0,strict:!1})));return{activeVersion:t,activeDoc:r,alternateDocVersions:r?function(n){const t={};return e.versions.forEach((e=>{e.docs.forEach((o=>{o.id===n&&(t[e.name]=o)}))})),t}(r.id):{}}}const u={},d=()=>a("docusaurus-plugin-content-docs")??u,p=e=>function(e,n,t){void 0===n&&(n=i.m),void 0===t&&(t={});const o=a(e),r=null==o?void 0:o[n];if(!r&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${n}".`);return r}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const n=d(),{pathname:t}=(0,o.TH)();return function(e,n,t){void 0===t&&(t={});const r=Object.entries(e).sort(((e,n)=>n[1].path.localeCompare(e[1].path))).find((e=>{let[,t]=e;return!!(0,o.LX)(n,{path:t.path,exact:!1,strict:!1})})),i=r?{pluginId:r[0],pluginData:r[1]}:void 0;if(!i&&t.failfast)throw new Error(`Can't find active docs plugin for "${n}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return i}(n,t,e)}function m(e){void 0===e&&(e={});const n=f(e),{pathname:t}=(0,o.TH)();if(!n)return;return{activePlugin:n,activeVersion:c(n.pluginData,t)}}function g(e){return p(e).versions}function h(e){const n=p(e);return s(n)}function k(e){const n=p(e),{pathname:t}=(0,o.TH)();return l(n,t)}function b(e){const n=p(e),{pathname:t}=(0,o.TH)();return function(e,n){const t=s(e);return{latestDocSuggestion:l(e,n).alternateDocVersions[t.name],latestVersionSuggestion:t}}(n,t)}},56657:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>o});const o={onRouteDidUpdate(e){let{location:n,previousLocation:t}=e;!t||n.pathname===t.pathname&&n.search===t.search&&n.hash===t.hash||setTimeout((()=>{window.gtag("event","page_view",{page_title:document.title,page_location:window.location.href,page_path:n.pathname+n.search+n.hash})}))}}},18320:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>i});var o=t(74865),r=t.n(o);r().configure({showSpinner:!1});const i={onRouteUpdate(e){let{location:n,previousLocation:t}=e;if(t&&n.pathname!==t.pathname){const e=window.setTimeout((()=>{r().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){r().done()}}},3310:(e,n,t)=>{"use strict";t.r(n);var o=t(87410),r=t(36809);!function(e){const{themeConfig:{prism:n}}=r.default,{additionalLanguages:o}=n;globalThis.Prism=e,o.forEach((e=>{t(6726)(`./prism-${e}`)})),delete globalThis.Prism}(o.Z)},39471:(e,n,t)=>{"use strict";t.d(n,{Z:()=>i});var o=t(67294);const r="iconExternalLink_nPIU";function i(e){let{width:n=13.5,height:t=13.5}=e;return o.createElement("svg",{width:n,height:t,"aria-hidden":"true",viewBox:"0 0 24 24",className:r},o.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},49689:(e,n,t)=>{"use strict";t.d(n,{Z:()=>Dn});var o=t(67294),r=t(86010),i=t(44763),a=t(10833),s=t(87462),c=t(76775),l=t(95999),u=t(85936);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,o.useRef)(null),{action:n}=(0,c.k6)(),t=(0,o.useCallback)((e=>{e.preventDefault();const n=document.querySelector("main:first-of-type")??document.getElementById(d);n&&p(n)}),[]);return(0,u.S)((t=>{let{location:o}=t;e.current&&!o.hash&&"PUSH"===n&&p(e.current)})),{containerRef:e,onClick:t}}const m=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const n=e.children??m,{containerRef:t,onClick:r}=f();return o.createElement("div",{ref:t,role:"region","aria-label":m},o.createElement("a",(0,s.Z)({},e,{href:`#${d}`,onClick:r}),n))}var h=t(35281),k=t(19727);const b="skipToContent_fXgn";function v(){return o.createElement(g,{className:b})}var w=t(86668),y=t(59689);function _(e){let{width:n=21,height:t=21,color:r="currentColor",strokeWidth:i=1.2,className:a,...c}=e;return o.createElement("svg",(0,s.Z)({viewBox:"0 0 15 15",width:n,height:t},c),o.createElement("g",{stroke:r,strokeWidth:i},o.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const x="closeButton_CVFx";function E(e){return o.createElement("button",(0,s.Z)({type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,r.Z)("clean-btn close",x,e.className)}),o.createElement(_,{width:14,height:14,strokeWidth:3.1}))}const S="content_knG7";function C(e){const{announcementBar:n}=(0,w.L)(),{content:t}=n;return o.createElement("div",(0,s.Z)({},e,{className:(0,r.Z)(S,e.className),dangerouslySetInnerHTML:{__html:t}}))}const T="announcementBar_mb4j",A="announcementBarPlaceholder_vyr4",L="announcementBarClose_gvF7",P="announcementBarContent_xLdY";function R(){const{announcementBar:e}=(0,w.L)(),{isActive:n,close:t}=(0,y.nT)();if(!n)return null;const{backgroundColor:r,textColor:i,isCloseable:a}=e;return o.createElement("div",{className:T,style:{backgroundColor:r,color:i},role:"banner"},a&&o.createElement("div",{className:A}),o.createElement(C,{className:P}),a&&o.createElement(E,{onClick:t,className:L}))}var N=t(93163),O=t(12466);var I=t(902),D=t(13102);const M=o.createContext(null);function j(e){let{children:n}=e;const t=function(){const e=(0,N.e)(),n=(0,D.HY)(),[t,r]=(0,o.useState)(!1),i=null!==n.component,a=(0,I.D9)(i);return(0,o.useEffect)((()=>{i&&!a&&r(!0)}),[i,a]),(0,o.useEffect)((()=>{i?e.shown||r(!0):r(!1)}),[e.shown,i]),(0,o.useMemo)((()=>[t,r]),[t])}();return o.createElement(M.Provider,{value:t},n)}function B(e){if(e.component){const n=e.component;return o.createElement(n,e.props)}}function F(){const e=(0,o.useContext)(M);if(!e)throw new I.i6("NavbarSecondaryMenuDisplayProvider");const[n,t]=e,r=(0,o.useCallback)((()=>t(!1)),[t]),i=(0,D.HY)();return(0,o.useMemo)((()=>({shown:n,hide:r,content:B(i)})),[r,i,n])}function z(e){let{header:n,primaryMenu:t,secondaryMenu:i}=e;const{shown:a}=F();return o.createElement("div",{className:"navbar-sidebar"},n,o.createElement("div",{className:(0,r.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a})},o.createElement("div",{className:"navbar-sidebar__item menu"},t),o.createElement("div",{className:"navbar-sidebar__item menu"},i)))}var U=t(92949),q=t(72389);function $(e){return o.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),o.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function G(e){return o.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),o.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const H={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:n,buttonClassName:t,value:i,onChange:a}=e;const s=(0,q.Z)(),c=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===i?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return o.createElement("div",{className:(0,r.Z)(H.toggle,n)},o.createElement("button",{className:(0,r.Z)("clean-btn",H.toggleButton,!s&&H.toggleButtonDisabled,t),type:"button",onClick:()=>a("dark"===i?"light":"dark"),disabled:!s,title:c,"aria-label":c,"aria-live":"polite"},o.createElement($,{className:(0,r.Z)(H.toggleIcon,H.lightToggleIcon)}),o.createElement(G,{className:(0,r.Z)(H.toggleIcon,H.darkToggleIcon)})))}const V=o.memo(Z),W="darkNavbarColorModeToggle_X3D1";function K(e){let{className:n}=e;const t=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:i,setColorMode:a}=(0,U.I)();return r?null:o.createElement(V,{className:n,buttonClassName:"dark"===t?W:void 0,value:i,onChange:a})}var Y=t(21327);function Q(){return o.createElement(Y.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function X(){const e=(0,N.e)();return o.createElement("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},o.createElement(_,{color:"var(--ifm-color-emphasis-600)"}))}function J(){return o.createElement("div",{className:"navbar-sidebar__brand"},o.createElement(Q,null),o.createElement(K,{className:"margin-right--md"}),o.createElement(X,null))}var ee=t(39960),ne=t(44996),te=t(13919),oe=t(98022),re=t(39471);function ie(e){let{activeBasePath:n,activeBaseRegex:t,to:r,href:i,label:a,html:c,isDropdownLink:l,prependBaseUrlToHref:u,...d}=e;const p=(0,ne.Z)(r),f=(0,ne.Z)(n),m=(0,ne.Z)(i,{forcePrependBaseUrl:!0}),g=a&&i&&!(0,te.Z)(i),h=c?{dangerouslySetInnerHTML:{__html:c}}:{children:o.createElement(o.Fragment,null,a,g&&o.createElement(re.Z,l&&{width:12,height:12}))};return i?o.createElement(ee.Z,(0,s.Z)({href:u?m:i},d,h)):o.createElement(ee.Z,(0,s.Z)({to:p,isNavLink:!0},(n||t)&&{isActive:(e,n)=>t?(0,oe.F)(t,n.pathname):n.pathname.startsWith(f)},d,h))}function ae(e){let{className:n,isDropdownItem:t=!1,...i}=e;const a=o.createElement(ie,(0,s.Z)({className:(0,r.Z)(t?"dropdown__link":"navbar__item navbar__link",n),isDropdownLink:t},i));return t?o.createElement("li",null,a):a}function se(e){let{className:n,isDropdownItem:t,...i}=e;return o.createElement("li",{className:"menu__list-item"},o.createElement(ie,(0,s.Z)({className:(0,r.Z)("menu__link",n)},i)))}function ce(e){let{mobile:n=!1,position:t,...r}=e;const i=n?se:ae;return o.createElement(i,(0,s.Z)({},r,{activeClassName:r.activeClassName??(n?"menu__link--active":"navbar__link--active")}))}var le=t(86043),ue=t(48596),de=t(52263);function pe(e,n){return e.some((e=>function(e,n){return!!(0,ue.Mg)(e.to,n)||!!(0,oe.F)(e.activeBaseRegex,n)||!(!e.activeBasePath||!n.startsWith(e.activeBasePath))}(e,n)))}function fe(e){let{items:n,position:t,className:i,onClick:a,...c}=e;const l=(0,o.useRef)(null),[u,d]=(0,o.useState)(!1);return(0,o.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),o.createElement("div",{ref:l,className:(0,r.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===t,"dropdown--show":u})},o.createElement(ie,(0,s.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:c.to?void 0:"#",className:(0,r.Z)("navbar__link",i)},c,{onClick:c.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),c.children??c.label),o.createElement("ul",{className:"dropdown__menu"},n.map(((e,n)=>o.createElement(Ve,(0,s.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:n}))))))}function me(e){let{items:n,className:t,position:i,onClick:a,...l}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,de.Z)(),{pathname:n}=(0,c.TH)();return n.replace(e,"/")}(),d=pe(n,u),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,le.u)({initialState:()=>!d});return(0,o.useEffect)((()=>{d&&m(!d)}),[u,d,m]),o.createElement("li",{className:(0,r.Z)("menu__list-item",{"menu__list-item--collapsed":p})},o.createElement(ie,(0,s.Z)({role:"button",className:(0,r.Z)("menu__link menu__link--sublist menu__link--sublist-caret",t)},l,{onClick:e=>{e.preventDefault(),f()}}),l.children??l.label),o.createElement(le.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},n.map(((e,n)=>o.createElement(Ve,(0,s.Z)({mobile:!0,isDropdownItem:!0,onClick:a,activeClassName:"menu__link--active"},e,{key:n}))))))}function ge(e){let{mobile:n=!1,...t}=e;const r=n?me:fe;return o.createElement(r,t)}var he=t(94711);function ke(e){let{width:n=20,height:t=20,...r}=e;return o.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:n,height:t,"aria-hidden":!0},r),o.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const be="iconLanguage_nlXk";function ve(){return o.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},o.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var we=t(20830),ye=["translations"];function _e(){return _e=Object.assign||function(e){for(var n=1;ne.length)&&(n=e.length);for(var t=0,o=new Array(n);t=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var Ce="Ctrl";var Te=o.forwardRef((function(e,n){var t=e.translations,r=void 0===t?{}:t,i=Se(e,ye),a=r.buttonText,s=void 0===a?"Search":a,c=r.buttonAriaLabel,l=void 0===c?"Search":c,u=xe((0,o.useState)(null),2),d=u[0],p=u[1];return(0,o.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Ce))}),[]),o.createElement("button",_e({type:"button",className:"DocSearch DocSearch-Button","aria-label":l},i,{ref:n}),o.createElement("span",{className:"DocSearch-Button-Container"},o.createElement(we.W,null),o.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),o.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&o.createElement(o.Fragment,null,o.createElement("kbd",{className:"DocSearch-Button-Key"},d===Ce?o.createElement(ve,null):d),o.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Ae=t(35742),Le=t(66177),Pe=t(239),Re=t(43320);var Ne=t(73935);const Oe={button:{buttonText:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,l.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,l.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,l.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,l.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,l.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,l.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,l.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,l.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Ie=null;function De(e){let{hit:n,children:t}=e;return o.createElement(ee.Z,{to:n.url},t)}function Me(e){let{state:n,onClose:t}=e;const r=(0,Le.M)();return o.createElement(ee.Z,{to:r(n.query),onClick:t},o.createElement(l.Z,{id:"theme.SearchBar.seeAll",values:{count:n.context.nbHits}},"See all {count} results"))}function je(e){var n;let{contextualSearch:r,externalUrlRegex:i,...a}=e;const{siteMetadata:l}=(0,de.Z)(),u=(0,Pe.l)(),d=function(){const{locale:e,tags:n}=(0,Re._q)();return[`language:${e}`,n.map((e=>`docusaurus_tag:${e}`))]}(),p=(null==(n=a.searchParameters)?void 0:n.facetFilters)??[],f=r?function(e,n){const t=e=>"string"==typeof e?[e]:e;return[...t(e),...t(n)]}(d,p):p,m={...a.searchParameters,facetFilters:f},g=(0,c.k6)(),h=(0,o.useRef)(null),k=(0,o.useRef)(null),[b,v]=(0,o.useState)(!1),[w,y]=(0,o.useState)(void 0),_=(0,o.useCallback)((()=>Ie?Promise.resolve():Promise.all([t.e(6780).then(t.bind(t,76780)),Promise.all([t.e(532),t.e(3969)]).then(t.bind(t,46945)),Promise.all([t.e(532),t.e(8894)]).then(t.bind(t,18894))]).then((e=>{let[{DocSearchModal:n}]=e;Ie=n}))),[]),x=(0,o.useCallback)((()=>{_().then((()=>{h.current=document.createElement("div"),document.body.insertBefore(h.current,document.body.firstChild),v(!0)}))}),[_,v]),E=(0,o.useCallback)((()=>{var e;v(!1),null==(e=h.current)||e.remove()}),[v]),S=(0,o.useCallback)((e=>{_().then((()=>{v(!0),y(e.key)}))}),[_,v,y]),C=(0,o.useRef)({navigate(e){let{itemUrl:n}=e;(0,oe.F)(i,n)?window.location.href=n:g.push(n)}}).current,T=(0,o.useRef)((e=>a.transformItems?a.transformItems(e):e.map((e=>({...e,url:u(e.url)}))))).current,A=(0,o.useMemo)((()=>e=>o.createElement(Me,(0,s.Z)({},e,{onClose:E}))),[E]),L=(0,o.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",l.docusaurusVersion),e)),[l.docusaurusVersion]);return function(e){var n=e.isOpen,t=e.onOpen,r=e.onClose,i=e.onInput,a=e.searchButtonRef;o.useEffect((function(){function e(e){(27===e.keyCode&&n||"k"===e.key&&(e.metaKey||e.ctrlKey)||!function(e){var n=e.target,t=n.tagName;return n.isContentEditable||"INPUT"===t||"SELECT"===t||"TEXTAREA"===t}(e)&&"/"===e.key&&!n)&&(e.preventDefault(),n?r():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||t()),a&&a.current===document.activeElement&&i&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&i(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[n,t,r,i,a])}({isOpen:b,onOpen:x,onClose:E,onInput:S,searchButtonRef:k}),o.createElement(o.Fragment,null,o.createElement(Ae.Z,null,o.createElement("link",{rel:"preconnect",href:`https://${a.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})),o.createElement(Te,{onTouchStart:_,onFocus:_,onMouseOver:_,onClick:x,ref:k,translations:Oe.button}),b&&Ie&&h.current&&(0,Ne.createPortal)(o.createElement(Ie,(0,s.Z)({onClose:E,initialScrollY:window.scrollY,initialQuery:w,navigator:C,transformItems:T,hitComponent:De,transformSearchClient:L},a.searchPagePath&&{resultsFooterComponent:A},a,{searchParameters:m,placeholder:Oe.placeholder,translations:Oe.modal})),h.current))}function Be(){const{siteConfig:e}=(0,de.Z)();return o.createElement(je,e.themeConfig.algolia)}function Fe(e){return o.createElement(o.Fragment,null,o.createElement(Be,e))}const ze="searchBox_ZlJk";function Ue(e){let{children:n,className:t}=e;return o.createElement("div",{className:(0,r.Z)(t,ze)},n)}var qe=t(80143),$e=t(53438);var Ge=t(60373);const He=e=>e.docs.find((n=>n.id===e.mainDocId));const Ze={default:ce,localeDropdown:function(e){let{mobile:n,dropdownItemsBefore:t,dropdownItemsAfter:r,...i}=e;const{i18n:{currentLocale:a,locales:u,localeConfigs:d}}=(0,de.Z)(),p=(0,he.l)(),{search:f,hash:m}=(0,c.TH)(),g=[...t,...u.map((e=>{const t=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:t,target:"_self",autoAddBaseUrl:!1,className:e===a?n?"menu__link--active":"dropdown__link--active":""}})),...r],h=n?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[a].label;return o.createElement(ge,(0,s.Z)({},i,{mobile:n,label:o.createElement(o.Fragment,null,o.createElement(ke,{className:be}),h),items:g}))},search:function(e){let{mobile:n,className:t}=e;return n?null:o.createElement(Ue,{className:t},o.createElement(Fe,null))},dropdown:ge,html:function(e){let{value:n,className:t,mobile:i=!1,isDropdownItem:a=!1}=e;const s=a?"li":"div";return o.createElement(s,{className:(0,r.Z)({navbar__item:!i&&!a,"menu__list-item":i},t),dangerouslySetInnerHTML:{__html:n}})},doc:function(e){let{docId:n,label:t,docsPluginId:r,...i}=e;const{activeDoc:a}=(0,qe.Iw)(r),c=(0,$e.vY)(n,r);return null===c?null:o.createElement(ce,(0,s.Z)({exact:!0},i,{isActive:()=>(null==a?void 0:a.path)===c.path||!(null==a||!a.sidebar)&&a.sidebar===c.sidebar,label:t??c.id,to:c.path}))},docSidebar:function(e){let{sidebarId:n,label:t,docsPluginId:r,...i}=e;const{activeDoc:a}=(0,qe.Iw)(r),c=(0,$e.oz)(n,r).link;if(!c)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${n}" doesn't have anything to be linked to.`);return o.createElement(ce,(0,s.Z)({exact:!0},i,{isActive:()=>(null==a?void 0:a.sidebar)===n,label:t??c.label,to:c.path}))},docsVersion:function(e){let{label:n,to:t,docsPluginId:r,...i}=e;const a=(0,$e.lO)(r)[0],c=n??a.label,l=t??(e=>e.docs.find((n=>n.id===e.mainDocId)))(a).path;return o.createElement(ce,(0,s.Z)({},i,{label:c,to:l}))},docsVersionDropdown:function(e){let{mobile:n,docsPluginId:t,dropdownActiveClassDisabled:r,dropdownItemsBefore:i,dropdownItemsAfter:a,...u}=e;const{search:d,hash:p}=(0,c.TH)(),f=(0,qe.Iw)(t),m=(0,qe.gB)(t),{savePreferredVersionName:g}=(0,Ge.J)(t),h=[...i,...m.map((e=>{const n=f.alternateDocVersions[e.name]??He(e);return{label:e.label,to:`${n.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>g(e.name)}})),...a],k=(0,$e.lO)(t)[0],b=n&&h.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):k.label,v=n&&h.length>1?void 0:He(k).path;return h.length<=1?o.createElement(ce,(0,s.Z)({},u,{mobile:n,label:b,to:v,isActive:r?()=>!1:void 0})):o.createElement(ge,(0,s.Z)({},u,{mobile:n,label:b,to:v,items:h,isActive:r?()=>!1:void 0}))}};function Ve(e){let{type:n,...t}=e;const r=function(e,n){return e&&"default"!==e?e:"items"in n?"dropdown":"default"}(n,t),i=Ze[r];if(!i)throw new Error(`No NavbarItem component found for type "${n}".`);return o.createElement(i,t)}function We(){const e=(0,N.e)(),n=(0,w.L)().navbar.items;return o.createElement("ul",{className:"menu__list"},n.map(((n,t)=>o.createElement(Ve,(0,s.Z)({mobile:!0},n,{onClick:()=>e.toggle(),key:t})))))}function Ke(e){return o.createElement("button",(0,s.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),o.createElement(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Ye(){const e=0===(0,w.L)().navbar.items.length,n=F();return o.createElement(o.Fragment,null,!e&&o.createElement(Ke,{onClick:()=>n.hide()}),n.content)}function Qe(){const e=(0,N.e)();var n;return void 0===(n=e.shown)&&(n=!0),(0,o.useEffect)((()=>(document.body.style.overflow=n?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[n]),e.shouldRender?o.createElement(z,{header:o.createElement(J,null),primaryMenu:o.createElement(We,null),secondaryMenu:o.createElement(Ye,null)}):null}const Xe="navbarHideable_m1mJ",Je="navbarHidden_jGov";function en(e){return o.createElement("div",(0,s.Z)({role:"presentation"},e,{className:(0,r.Z)("navbar-sidebar__backdrop",e.className)}))}function nn(e){let{children:n}=e;const{navbar:{hideOnScroll:t,style:i}}=(0,w.L)(),a=(0,N.e)(),{navbarRef:s,isNavbarVisible:c}=function(e){const[n,t]=(0,o.useState)(e),r=(0,o.useRef)(!1),i=(0,o.useRef)(0),a=(0,o.useCallback)((e=>{null!==e&&(i.current=e.getBoundingClientRect().height)}),[]);return(0,O.RF)(((n,o)=>{let{scrollY:a}=n;if(!e)return;if(a=s?t(!1):a+l{if(!e)return;const o=n.location.hash;if(o?document.getElementById(o.substring(1)):void 0)return r.current=!0,void t(!1);t(!0)})),{navbarRef:a,isNavbarVisible:n}}(t);return o.createElement("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,r.Z)("navbar","navbar--fixed-top",t&&[Xe,!c&&Je],{"navbar--dark":"dark"===i,"navbar--primary":"primary"===i,"navbar-sidebar--show":a.shown})},n,o.createElement(en,{onClick:a.toggle}),o.createElement(Qe,null))}var tn=t(18780);const on="errorBoundaryError_a6uf";function rn(e){return o.createElement("button",(0,s.Z)({type:"button"},e),o.createElement(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function an(e){let{error:n}=e;const t=(0,tn.getErrorCausalChain)(n).map((e=>e.message)).join("\n\nCause:\n");return o.createElement("p",{className:on},t)}class sn extends o.Component{componentDidCatch(e,n){throw this.props.onError(e,n)}render(){return this.props.children}}function cn(e){let{width:n=30,height:t=30,className:r,...i}=e;return o.createElement("svg",(0,s.Z)({className:r,width:n,height:t,viewBox:"0 0 30 30","aria-hidden":"true"},i),o.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function ln(){const{toggle:e,shown:n}=(0,N.e)();return o.createElement("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":n,className:"navbar__toggle clean-btn",type:"button"},o.createElement(cn,null))}const un="colorModeToggle_DEke";function dn(e){let{items:n}=e;return o.createElement(o.Fragment,null,n.map(((e,n)=>o.createElement(sn,{key:n,onError:n=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:n})},o.createElement(Ve,e)))))}function pn(e){let{left:n,right:t}=e;return o.createElement("div",{className:"navbar__inner"},o.createElement("div",{className:"navbar__items"},n),o.createElement("div",{className:"navbar__items navbar__items--right"},t))}function fn(){const e=(0,N.e)(),n=(0,w.L)().navbar.items,[t,r]=function(e){function n(e){return"left"===(e.position??"right")}return[e.filter(n),e.filter((e=>!n(e)))]}(n),i=n.find((e=>"search"===e.type));return o.createElement(pn,{left:o.createElement(o.Fragment,null,!e.disabled&&o.createElement(ln,null),o.createElement(Q,null),o.createElement(dn,{items:t})),right:o.createElement(o.Fragment,null,o.createElement(dn,{items:r}),o.createElement(K,{className:un}),!i&&o.createElement(Ue,null,o.createElement(Fe,null)))})}function mn(){return o.createElement(nn,null,o.createElement(fn,null))}function gn(e){let{item:n}=e;const{to:t,href:r,label:i,prependBaseUrlToHref:a,...c}=n,l=(0,ne.Z)(t),u=(0,ne.Z)(r,{forcePrependBaseUrl:!0});return o.createElement(ee.Z,(0,s.Z)({className:"footer__link-item"},r?{href:a?u:r}:{to:l},c),i,r&&!(0,te.Z)(r)&&o.createElement(re.Z,null))}function hn(e){let{item:n}=e;return n.html?o.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:n.html}}):o.createElement("li",{key:n.href??n.to,className:"footer__item"},o.createElement(gn,{item:n}))}function kn(e){let{column:n}=e;return o.createElement("div",{className:"col footer__col"},o.createElement("div",{className:"footer__title"},n.title),o.createElement("ul",{className:"footer__items clean-list"},n.items.map(((e,n)=>o.createElement(hn,{key:n,item:e})))))}function bn(e){let{columns:n}=e;return o.createElement("div",{className:"row footer__links"},n.map(((e,n)=>o.createElement(kn,{key:n,column:e}))))}function vn(){return o.createElement("span",{className:"footer__link-separator"},"\xb7")}function wn(e){let{item:n}=e;return n.html?o.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:n.html}}):o.createElement(gn,{item:n})}function yn(e){let{links:n}=e;return o.createElement("div",{className:"footer__links text--center"},o.createElement("div",{className:"footer__links"},n.map(((e,t)=>o.createElement(o.Fragment,{key:t},o.createElement(wn,{item:e}),n.length!==t+1&&o.createElement(vn,null))))))}function _n(e){let{links:n}=e;return function(e){return"title"in e[0]}(n)?o.createElement(bn,{columns:n}):o.createElement(yn,{links:n})}var xn=t(50941);const En="footerLogoLink_BH7S";function Sn(e){let{logo:n}=e;const{withBaseUrl:t}=(0,ne.C)(),i={light:t(n.src),dark:t(n.srcDark??n.src)};return o.createElement(xn.Z,{className:(0,r.Z)("footer__logo",n.className),alt:n.alt,sources:i,width:n.width,height:n.height,style:n.style})}function Cn(e){let{logo:n}=e;return n.href?o.createElement(ee.Z,{href:n.href,className:En,target:n.target},o.createElement(Sn,{logo:n})):o.createElement(Sn,{logo:n})}function Tn(e){let{copyright:n}=e;return o.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:n}})}function An(e){let{style:n,links:t,logo:i,copyright:a}=e;return o.createElement("footer",{className:(0,r.Z)("footer",{"footer--dark":"dark"===n})},o.createElement("div",{className:"container container-fluid"},t,(i||a)&&o.createElement("div",{className:"footer__bottom text--center"},i&&o.createElement("div",{className:"margin-bottom--sm"},i),a)))}function Ln(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:n,links:t,logo:r,style:i}=e;return o.createElement(An,{style:i,links:t&&t.length>0&&o.createElement(_n,{links:t}),logo:r&&o.createElement(Cn,{logo:r}),copyright:n&&o.createElement(Tn,{copyright:n})})}const Pn=o.memo(Ln),Rn=(0,I.Qc)([U.S,y.pl,O.OC,Ge.L5,a.VC,function(e){let{children:n}=e;return o.createElement(D.n2,null,o.createElement(N.M,null,o.createElement(j,null,n)))}]);function Nn(e){let{children:n}=e;return o.createElement(Rn,null,n)}function On(e){let{error:n,tryAgain:t}=e;return o.createElement("main",{className:"container margin-vert--xl"},o.createElement("div",{className:"row"},o.createElement("div",{className:"col col--6 col--offset-3"},o.createElement("h1",{className:"hero__title"},o.createElement(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),o.createElement("div",{className:"margin-vert--lg"},o.createElement(rn,{onClick:t,className:"button button--primary shadow--lw"})),o.createElement("hr",null),o.createElement("div",{className:"margin-vert--md"},o.createElement(an,{error:n})))))}const In="mainWrapper_z2l0";function Dn(e){const{children:n,noFooter:t,wrapperClassName:s,title:c,description:l}=e;return(0,k.t)(),o.createElement(Nn,null,o.createElement(a.d,{title:c,description:l}),o.createElement(v,null),o.createElement(R,null),o.createElement(mn,null),o.createElement("div",{id:d,className:(0,r.Z)(h.k.wrapper.main,In,s)},o.createElement(i.Z,{fallback:e=>o.createElement(On,e)},n)),!t&&o.createElement(Pn,null))}},21327:(e,n,t)=>{"use strict";t.d(n,{Z:()=>d});var o=t(87462),r=t(67294),i=t(39960),a=t(44996),s=t(52263),c=t(86668),l=t(50941);function u(e){let{logo:n,alt:t,imageClassName:o}=e;const i={light:(0,a.Z)(n.src),dark:(0,a.Z)(n.srcDark||n.src)},s=r.createElement(l.Z,{className:n.className,sources:i,height:n.height,width:n.width,alt:t,style:n.style});return o?r.createElement("div",{className:o},s):s}function d(e){const{siteConfig:{title:n}}=(0,s.Z)(),{navbar:{title:t,logo:l}}=(0,c.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,a.Z)((null==l?void 0:l.href)||"/"),g=t?"":n,h=(null==l?void 0:l.alt)??g;return r.createElement(i.Z,(0,o.Z)({to:m},f,(null==l?void 0:l.target)&&{target:l.target}),l&&r.createElement(u,{logo:l,alt:h,imageClassName:d}),null!=t&&r.createElement("b",{className:p},t))}},90197:(e,n,t)=>{"use strict";t.d(n,{Z:()=>i});var o=t(67294),r=t(35742);function i(e){let{locale:n,version:t,tag:i}=e;const a=n;return o.createElement(r.Z,null,n&&o.createElement("meta",{name:"docusaurus_locale",content:n}),t&&o.createElement("meta",{name:"docusaurus_version",content:t}),i&&o.createElement("meta",{name:"docusaurus_tag",content:i}),a&&o.createElement("meta",{name:"docsearch:language",content:a}),t&&o.createElement("meta",{name:"docsearch:version",content:t}),i&&o.createElement("meta",{name:"docsearch:docusaurus_tag",content:i}))}},50941:(e,n,t)=>{"use strict";t.d(n,{Z:()=>l});var o=t(87462),r=t(67294),i=t(86010),a=t(72389),s=t(92949);const c={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function l(e){const n=(0,a.Z)(),{colorMode:t}=(0,s.I)(),{sources:l,className:u,alt:d,...p}=e,f=n?"dark"===t?["dark"]:["light"]:["light","dark"];return r.createElement(r.Fragment,null,f.map((e=>r.createElement("img",(0,o.Z)({key:e,src:l[e],alt:d,className:(0,i.Z)(c.themedImage,c[`themedImage--${e}`],u)},p)))))}},86043:(e,n,t)=>{"use strict";t.d(n,{u:()=>s,z:()=>g});var o=t(87462),r=t(67294),i=t(10412),a=t(91442);function s(e){let{initialState:n}=e;const[t,o]=(0,r.useState)(n??!1),i=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:t,setCollapsed:o,toggleCollapsed:i}}const c={display:"none",overflow:"hidden",height:"0px"},l={display:"block",overflow:"visible",height:"auto"};function u(e,n){const t=n?c:l;e.style.display=t.display,e.style.overflow=t.overflow,e.style.height=t.height}function d(e){let{collapsibleRef:n,collapsed:t,animation:o}=e;const i=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=n.current;function r(){const n=e.scrollHeight,t=(null==o?void 0:o.duration)??function(e){if((0,a.n)())return 1;const n=e/36;return Math.round(10*(4+15*n**.25+n/5))}(n);return{transition:`height ${t}ms ${(null==o?void 0:o.easing)??"ease-in-out"}`,height:`${n}px`}}function s(){const n=r();e.style.transition=n.transition,e.style.height=n.height}if(!i.current)return u(e,t),void(i.current=!0);return e.style.willChange="height",function(){const n=requestAnimationFrame((()=>{t?(s(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(n)}()}),[n,t,o])}function p(e){if(!i.Z.canUseDOM)return e?c:l}function f(e){let{as:n="div",collapsed:t,children:o,animation:i,onCollapseTransitionEnd:a,className:s,disableSSRStyle:c}=e;const l=(0,r.useRef)(null);return d({collapsibleRef:l,collapsed:t,animation:i}),r.createElement(n,{ref:l,style:c?void 0:p(t),onTransitionEnd:e=>{"height"===e.propertyName&&(u(l.current,t),null==a||a(t))},className:s},o)}function m(e){let{collapsed:n,...t}=e;const[i,a]=(0,r.useState)(!n),[s,c]=(0,r.useState)(n);return(0,r.useLayoutEffect)((()=>{n||a(!0)}),[n]),(0,r.useLayoutEffect)((()=>{i&&c(n)}),[i,n]),i?r.createElement(f,(0,o.Z)({},t,{collapsed:s})):null}function g(e){let{lazy:n,...t}=e;const o=n?m:f;return r.createElement(o,t)}},59689:(e,n,t)=>{"use strict";t.d(n,{nT:()=>m,pl:()=>f});var o=t(67294),r=t(72389),i=t(50012),a=t(902),s=t(86668);const c=(0,i.WA)("docusaurus.announcement.dismiss"),l=(0,i.WA)("docusaurus.announcement.id"),u=()=>"true"===c.get(),d=e=>c.set(String(e)),p=o.createContext(null);function f(e){let{children:n}=e;const t=function(){const{announcementBar:e}=(0,s.L)(),n=(0,r.Z)(),[t,i]=(0,o.useState)((()=>!!n&&u()));(0,o.useEffect)((()=>{i(u())}),[]);const a=(0,o.useCallback)((()=>{d(!0),i(!0)}),[]);return(0,o.useEffect)((()=>{if(!e)return;const{id:n}=e;let t=l.get();"annoucement-bar"===t&&(t="announcement-bar");const o=n!==t;l.set(n),o&&d(!1),!o&&u()||i(!1)}),[e]),(0,o.useMemo)((()=>({isActive:!!e&&!t,close:a})),[e,t,a])}();return o.createElement(p.Provider,{value:t},n)}function m(){const e=(0,o.useContext)(p);if(!e)throw new a.i6("AnnouncementBarProvider");return e}},92949:(e,n,t)=>{"use strict";t.d(n,{I:()=>h,S:()=>g});var o=t(67294),r=t(10412),i=t(902),a=t(50012),s=t(86668);const c=o.createContext(void 0),l="theme",u=(0,a.WA)(l),d="light",p="dark",f=e=>e===p?p:d;function m(){const{colorMode:{defaultMode:e,disableSwitch:n,respectPrefersColorScheme:t}}=(0,s.L)(),[i,a]=(0,o.useState)((e=>r.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e))(e));(0,o.useEffect)((()=>{n&&u.del()}),[n]);const c=(0,o.useCallback)((function(n,o){void 0===o&&(o={});const{persist:r=!0}=o;n?(a(n),r&&(e=>{u.set(f(e))})(n)):(a(t?window.matchMedia("(prefers-color-scheme: dark)").matches?p:d:e),u.del())}),[t,e]);(0,o.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(i))}),[i]),(0,o.useEffect)((()=>{if(n)return;const e=e=>{if(e.key!==l)return;const n=u.get();null!==n&&c(f(n))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[n,c]);const m=(0,o.useRef)(!1);return(0,o.useEffect)((()=>{if(n&&!t)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),o=()=>{window.matchMedia("print").matches||m.current?m.current=window.matchMedia("print").matches:c(null)};return e.addListener(o),()=>e.removeListener(o)}),[c,n,t]),(0,o.useMemo)((()=>({colorMode:i,setColorMode:c,get isDarkTheme(){return i===p},setLightTheme(){c(d)},setDarkTheme(){c(p)}})),[i,c])}function g(e){let{children:n}=e;const t=m();return o.createElement(c.Provider,{value:t},n)}function h(){const e=(0,o.useContext)(c);if(null==e)throw new i.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},60373:(e,n,t)=>{"use strict";t.d(n,{J:()=>v,L5:()=>k,Oh:()=>w});var o=t(67294),r=t(80143),i=t(29935),a=t(86668),s=t(53438),c=t(902),l=t(50012);const u=e=>`docs-preferred-version-${e}`,d=(e,n,t)=>{(0,l.WA)(u(e),{persistence:n}).set(t)},p=(e,n)=>(0,l.WA)(u(e),{persistence:n}).get(),f=(e,n)=>{(0,l.WA)(u(e),{persistence:n}).del()};const m=o.createContext(null);function g(){const e=(0,r._r)(),n=(0,a.L)().docs.versionPersistence,t=(0,o.useMemo)((()=>Object.keys(e)),[e]),[i,s]=(0,o.useState)((()=>(e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}]))))(t)));(0,o.useEffect)((()=>{s(function(e){let{pluginIds:n,versionPersistence:t,allDocsData:o}=e;function r(e){const n=p(e,t);return o[e].versions.some((e=>e.name===n))?{preferredVersionName:n}:(f(e,t),{preferredVersionName:null})}return Object.fromEntries(n.map((e=>[e,r(e)])))}({allDocsData:e,versionPersistence:n,pluginIds:t}))}),[e,n,t]);return[i,(0,o.useMemo)((()=>({savePreferredVersion:function(e,t){d(e,n,t),s((n=>({...n,[e]:{preferredVersionName:t}})))}})),[n])]}function h(e){let{children:n}=e;const t=g();return o.createElement(m.Provider,{value:t},n)}function k(e){let{children:n}=e;return s.cE?o.createElement(h,null,n):o.createElement(o.Fragment,null,n)}function b(){const e=(0,o.useContext)(m);if(!e)throw new c.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=i.m);const n=(0,r.zh)(e),[t,a]=b(),{preferredVersionName:s}=t[e];return{preferredVersion:n.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,o.useCallback)((n=>{a.savePreferredVersion(e,n)}),[a,e])}}function w(){const e=(0,r._r)(),[n]=b();function t(t){const o=e[t],{preferredVersionName:r}=n[t];return o.versions.find((e=>e.name===r))??null}const o=Object.keys(e);return Object.fromEntries(o.map((e=>[e,t(e)])))}},1116:(e,n,t)=>{"use strict";t.d(n,{V:()=>c,b:()=>s});var o=t(67294),r=t(902);const i=Symbol("EmptyContext"),a=o.createContext(i);function s(e){let{children:n,name:t,items:r}=e;const i=(0,o.useMemo)((()=>t&&r?{name:t,items:r}:null),[t,r]);return o.createElement(a.Provider,{value:i},n)}function c(){const e=(0,o.useContext)(a);if(e===i)throw new r.i6("DocsSidebarProvider");return e}},74477:(e,n,t)=>{"use strict";t.d(n,{E:()=>s,q:()=>a});var o=t(67294),r=t(902);const i=o.createContext(null);function a(e){let{children:n,version:t}=e;return o.createElement(i.Provider,{value:t},n)}function s(){const e=(0,o.useContext)(i);if(null===e)throw new r.i6("DocsVersionProvider");return e}},93163:(e,n,t)=>{"use strict";t.d(n,{M:()=>d,e:()=>p});var o=t(67294),r=t(13102),i=t(87524),a=t(91980),s=t(86668),c=t(902);const l=o.createContext(void 0);function u(){const e=function(){const e=(0,r.HY)(),{items:n}=(0,s.L)().navbar;return 0===n.length&&!e.component}(),n=(0,i.i)(),t=!e&&"mobile"===n,[c,l]=(0,o.useState)(!1);(0,a.Rb)((()=>{if(c)return l(!1),!1}));const u=(0,o.useCallback)((()=>{l((e=>!e))}),[]);return(0,o.useEffect)((()=>{"desktop"===n&&l(!1)}),[n]),(0,o.useMemo)((()=>({disabled:e,shouldRender:t,toggle:u,shown:c})),[e,t,u,c])}function d(e){let{children:n}=e;const t=u();return o.createElement(l.Provider,{value:t},n)}function p(){const e=o.useContext(l);if(void 0===e)throw new c.i6("NavbarMobileSidebarProvider");return e}},13102:(e,n,t)=>{"use strict";t.d(n,{HY:()=>s,Zo:()=>c,n2:()=>a});var o=t(67294),r=t(902);const i=o.createContext(null);function a(e){let{children:n}=e;const t=(0,o.useState)({component:null,props:null});return o.createElement(i.Provider,{value:t},n)}function s(){const e=(0,o.useContext)(i);if(!e)throw new r.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:n,props:t}=e;const a=(0,o.useContext)(i);if(!a)throw new r.i6("NavbarSecondaryMenuContentProvider");const[,s]=a,c=(0,r.Ql)(t);return(0,o.useEffect)((()=>{s({component:n,props:c})}),[s,n,c]),(0,o.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},19727:(e,n,t)=>{"use strict";t.d(n,{h:()=>r,t:()=>i});var o=t(67294);const r="navigation-with-keyboard";function i(){(0,o.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(r),"mousedown"===e.type&&document.body.classList.remove(r)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(r),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},66177:(e,n,t)=>{"use strict";t.d(n,{K:()=>a,M:()=>s});var o=t(67294),r=t(52263),i=t(91980);function a(){return(0,i.Nc)("q")}function s(){const{siteConfig:{baseUrl:e,themeConfig:n}}=(0,r.Z)(),{algolia:{searchPagePath:t}}=n;return(0,o.useCallback)((n=>`${e}${t}?q=${encodeURIComponent(n)}`),[e,t])}},87524:(e,n,t)=>{"use strict";t.d(n,{i:()=>l});var o=t(67294),r=t(10412);const i="desktop",a="mobile",s="ssr";function c(){return r.Z.canUseDOM?window.innerWidth>996?i:a:s}function l(){const[e,n]=(0,o.useState)((()=>c()));return(0,o.useEffect)((()=>{function e(){n(c())}return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),e}},35281:(e,n,t)=>{"use strict";t.d(n,{k:()=>o});const o={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},91442:(e,n,t)=>{"use strict";function o(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}t.d(n,{n:()=>o})},53438:(e,n,t)=>{"use strict";t.d(n,{MN:()=>E,Wl:()=>m,_F:()=>k,cE:()=>p,hI:()=>x,jA:()=>g,lO:()=>w,oz:()=>y,s1:()=>v,vY:()=>_,xz:()=>f});var o=t(67294),r=t(76775),i=t(18790),a=t(80143),s=t(60373),c=t(74477),l=t(1116),u=t(67392),d=t(48596);const p=!!a._r;function f(e){const n=(0,c.E)();if(!e)return;const t=n.docs[e];if(!t)throw new Error(`no version doc found by id=${e}`);return t}function m(e){if(e.href)return e.href;for(const n of e.items){if("link"===n.type)return n.href;if("category"===n.type){const e=m(n);if(e)return e}}}function g(){const{pathname:e}=(0,r.TH)(),n=(0,l.V)();if(!n)throw new Error("Unexpected: cant find current sidebar in context");const t=b({sidebarItems:n.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!t)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return t}const h=(e,n)=>void 0!==e&&(0,d.Mg)(e,n);function k(e,n){return"link"===e.type?h(e.href,n):"category"===e.type&&(h(e.href,n)||((e,n)=>e.some((e=>k(e,n))))(e.items,n))}function b(e){let{sidebarItems:n,pathname:t,onlyCategories:o=!1}=e;const r=[];return function e(n){for(const i of n)if("category"===i.type&&((0,d.Mg)(i.href,t)||e(i.items))||"link"===i.type&&(0,d.Mg)(i.href,t)){return o&&"category"!==i.type||r.unshift(i),!0}return!1}(n),r}function v(){var e;const n=(0,l.V)(),{pathname:t}=(0,r.TH)();return!1!==(null==(e=(0,a.gA)())?void 0:e.pluginData.breadcrumbs)&&n?b({sidebarItems:n.items,pathname:t}):null}function w(e){const{activeVersion:n}=(0,a.Iw)(e),{preferredVersion:t}=(0,s.J)(e),r=(0,a.yW)(e);return(0,o.useMemo)((()=>(0,u.j)([n,t,r].filter(Boolean))),[n,t,r])}function y(e,n){const t=w(n);return(0,o.useMemo)((()=>{const n=t.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),o=n.find((n=>n[0]===e));if(!o)throw new Error(`Can't find any sidebar with id "${e}" in version${t.length>1?"s":""} ${t.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${n.map((e=>e[0])).join("\n- ")}`);return o[1]}),[e,t])}function _(e,n){const t=w(n);return(0,o.useMemo)((()=>{const n=t.flatMap((e=>e.docs)),o=n.find((n=>n.id===e));if(!o){if(t.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${t.length>1?"s":""} "${t.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(n.map((e=>e.id))).join("\n- ")}`)}return o}),[e,t])}function x(e){let{route:n,versionMetadata:t}=e;const o=(0,r.TH)(),a=n.routes,s=a.find((e=>(0,r.LX)(o.pathname,e)));if(!s)return null;const c=s.sidebar,l=c?t.docsSidebars[c]:void 0;return{docElement:(0,i.H)(a),sidebarName:c,sidebarItems:l}}function E(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},82128:(e,n,t)=>{"use strict";t.d(n,{p:()=>r});var o=t(52263);function r(e){const{siteConfig:n}=(0,o.Z)(),{title:t,titleDelimiter:r}=n;return null!=e&&e.trim().length?`${e.trim()} ${r} ${t}`:t}},91980:(e,n,t)=>{"use strict";t.d(n,{Nc:()=>l,Rb:()=>s,_X:()=>c});var o=t(67294),r=t(76775),i=t(61688),a=t(902);function s(e){!function(e){const n=(0,r.k6)(),t=(0,a.zX)(e);(0,o.useEffect)((()=>n.block(((e,n)=>t(e,n)))),[n,t])}(((n,t)=>{if("POP"===t)return e(n,t)}))}function c(e){return function(e){const n=(0,r.k6)();return(0,i.useSyncExternalStore)(n.listen,(()=>e(n)),(()=>e(n)))}((n=>null===e?null:new URLSearchParams(n.location.search).get(e)))}function l(e){const n=c(e)??"",t=function(){const e=(0,r.k6)();return(0,o.useCallback)(((n,t,o)=>{const r=new URLSearchParams(e.location.search);t?r.set(n,t):r.delete(n),(null!=o&&o.push?e.push:e.replace)({search:r.toString()})}),[e])}();return[n,(0,o.useCallback)(((n,o)=>{t(e,n,o)}),[t,e])]}},67392:(e,n,t)=>{"use strict";function o(e,n){return void 0===n&&(n=(e,n)=>e===n),e.filter(((t,o)=>e.findIndex((e=>n(e,t)))!==o))}function r(e){return Array.from(new Set(e))}t.d(n,{j:()=>r,l:()=>o})},10833:(e,n,t)=>{"use strict";t.d(n,{FG:()=>p,d:()=>u,VC:()=>f});var o=t(67294),r=t(86010),i=t(35742),a=t(30226);function s(){const e=o.useContext(a._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var c=t(44996),l=t(82128);function u(e){let{title:n,description:t,keywords:r,image:a,children:s}=e;const u=(0,l.p)(n),{withBaseUrl:d}=(0,c.C)(),p=a?d(a,{absolute:!0}):void 0;return o.createElement(i.Z,null,n&&o.createElement("title",null,u),n&&o.createElement("meta",{property:"og:title",content:u}),t&&o.createElement("meta",{name:"description",content:t}),t&&o.createElement("meta",{property:"og:description",content:t}),r&&o.createElement("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&o.createElement("meta",{property:"og:image",content:p}),p&&o.createElement("meta",{name:"twitter:image",content:p}),s)}const d=o.createContext(void 0);function p(e){let{className:n,children:t}=e;const a=o.useContext(d),s=(0,r.Z)(a,n);return o.createElement(d.Provider,{value:s},o.createElement(i.Z,null,o.createElement("html",{className:s})),t)}function f(e){let{children:n}=e;const t=s(),i=`plugin-${t.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${t.plugin.id}`;return o.createElement(p,{className:(0,r.Z)(i,a)},n)}},902:(e,n,t)=>{"use strict";t.d(n,{D9:()=>a,Qc:()=>l,Ql:()=>c,i6:()=>s,zX:()=>i});var o=t(67294);const r=t(10412).Z.canUseDOM?o.useLayoutEffect:o.useEffect;function i(e){const n=(0,o.useRef)(e);return r((()=>{n.current=e}),[e]),(0,o.useCallback)((function(){return n.current(...arguments)}),[])}function a(e){const n=(0,o.useRef)();return r((()=>{n.current=e})),n.current}class s extends Error{constructor(e,n){var t,o,r;super(),this.name="ReactContextError",this.message=`Hook ${(null==(t=this.stack)||null==(o=t.split("\n")[1])||null==(r=o.match(/at (?:\w+\.)?(?\w+)/))?void 0:r.groups.name)??""} is called outside the <${e}>. ${n??""}`}}function c(e){const n=Object.entries(e);return n.sort(((e,n)=>e[0].localeCompare(n[0]))),(0,o.useMemo)((()=>e),n.flat())}function l(e){return n=>{let{children:t}=n;return o.createElement(o.Fragment,null,e.reduceRight(((e,n)=>o.createElement(n,null,e)),t))}}},98022:(e,n,t)=>{"use strict";function o(e,n){return void 0!==e&&void 0!==n&&new RegExp(e,"gi").test(n)}t.d(n,{F:()=>o})},48596:(e,n,t)=>{"use strict";t.d(n,{Mg:()=>a,Ns:()=>s});var o=t(67294),r=t(723),i=t(52263);function a(e,n){const t=e=>{var n;return null==(n=!e||e.endsWith("/")?e:`${e}/`)?void 0:n.toLowerCase()};return t(e)===t(n)}function s(){const{baseUrl:e}=(0,i.Z)().siteConfig;return(0,o.useMemo)((()=>function(e){let{baseUrl:n,routes:t}=e;function o(e){return e.path===n&&!0===e.exact}function r(e){return e.path===n&&!e.exact}return function e(n){if(0===n.length)return;return n.find(o)||e(n.filter(r).flatMap((e=>e.routes??[])))}(t)}({routes:r.Z,baseUrl:e})),[e])}},12466:(e,n,t)=>{"use strict";t.d(n,{Ct:()=>f,OC:()=>c,RF:()=>d,o5:()=>p});var o=t(67294),r=t(10412),i=t(72389),a=t(902);const s=o.createContext(void 0);function c(e){let{children:n}=e;const t=function(){const e=(0,o.useRef)(!0);return(0,o.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return o.createElement(s.Provider,{value:t},n)}function l(){const e=(0,o.useContext)(s);if(null==e)throw new a.i6("ScrollControllerProvider");return e}const u=()=>r.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,n){void 0===n&&(n=[]);const{scrollEventsEnabledRef:t}=l(),r=(0,o.useRef)(u()),i=(0,a.zX)(e);(0,o.useEffect)((()=>{const e=()=>{if(!t.current)return;const e=u();i(e,r.current),r.current=e},n={passive:!0};return e(),window.addEventListener("scroll",e,n),()=>window.removeEventListener("scroll",e,n)}),[i,t,...n])}function p(){const e=l(),n=function(){const e=(0,o.useRef)({elem:null,top:0}),n=(0,o.useCallback)((n=>{e.current={elem:n,top:n.getBoundingClientRect().top}}),[]),t=(0,o.useCallback)((()=>{const{current:{elem:n,top:t}}=e;if(!n)return{restored:!1};const o=n.getBoundingClientRect().top-t;return o&&window.scrollBy({left:0,top:o}),e.current={elem:null,top:0},{restored:0!==o}}),[]);return(0,o.useMemo)((()=>({save:n,restore:t})),[t,n])}(),t=(0,o.useRef)(void 0),r=(0,o.useCallback)((o=>{n.save(o),e.disableScrollEvents(),t.current=()=>{const{restored:o}=n.restore();if(t.current=void 0,o){const n=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",n)};window.addEventListener("scroll",n)}else e.enableScrollEvents()}}),[e,n]);return(0,o.useLayoutEffect)((()=>{queueMicrotask((()=>null==t.current?void 0:t.current()))})),{blockElementScrollPositionUntilNextRender:r}}function f(){const e=(0,o.useRef)(null),n=(0,i.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:t=>{e.current=n?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(t):function(e){let n=null;const t=document.documentElement.scrollTop>e;return function o(){const r=document.documentElement.scrollTop;(t&&r>e||!t&&rn&&cancelAnimationFrame(n)}(t)},cancelScroll:()=>null==e.current?void 0:e.current()}}},43320:(e,n,t)=>{"use strict";t.d(n,{HX:()=>a,_q:()=>c,os:()=>s});var o=t(80143),r=t(52263),i=t(60373);const a="default";function s(e,n){return`docs-${e}-${n}`}function c(){const{i18n:e}=(0,r.Z)(),n=(0,o._r)(),t=(0,o.WS)(),c=(0,i.Oh)();const l=[a,...Object.keys(n).map((function(e){const o=(null==t?void 0:t.activePlugin.pluginId)===e?t.activeVersion:void 0,r=c[e],i=n[e].versions.find((e=>e.isLast));return s(e,(o??r??i).name)}))];return{locale:e.currentLocale,tags:l}}},50012:(e,n,t)=>{"use strict";t.d(n,{Nk:()=>d,WA:()=>u});var o=t(67294),r=t(61688);const i="localStorage";function a(e){let{key:n,oldValue:t,newValue:o,storage:r}=e;if(t===o)return;const i=document.createEvent("StorageEvent");i.initStorageEvent("storage",!1,!1,n,t,o,window.location.href,r),window.dispatchEvent(i)}function s(e){if(void 0===e&&(e=i),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(t){return n=t,c||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",n),c=!0),null}var n}let c=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,n){if("undefined"==typeof window)return function(e){function n(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:n,set:n,del:n,listen:n}}(e);const t=s(null==n?void 0:n.persistence);return null===t?l:{get:()=>{try{return t.getItem(e)}catch(n){return console.error(`Docusaurus storage error, can't get key=${e}`,n),null}},set:n=>{try{const o=t.getItem(e);t.setItem(e,n),a({key:e,oldValue:o,newValue:n,storage:t})}catch(o){console.error(`Docusaurus storage error, can't set ${e}=${n}`,o)}},del:()=>{try{const n=t.getItem(e);t.removeItem(e),a({key:e,oldValue:n,newValue:null,storage:t})}catch(n){console.error(`Docusaurus storage error, can't delete key=${e}`,n)}},listen:n=>{try{const o=o=>{o.storageArea===t&&o.key===e&&n(o)};return window.addEventListener("storage",o),()=>window.removeEventListener("storage",o)}catch(o){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,o),()=>{}}}}}function d(e,n){const t=(0,o.useRef)((()=>null===e?l:u(e,n))).current(),i=(0,o.useCallback)((e=>"undefined"==typeof window?()=>{}:t.listen(e)),[t]);return[(0,r.useSyncExternalStore)(i,(()=>"undefined"==typeof window?null:t.get()),(()=>null)),t]}},94711:(e,n,t)=>{"use strict";t.d(n,{l:()=>i});var o=t(52263),r=t(76775);function i(){const{siteConfig:{baseUrl:e,url:n},i18n:{defaultLocale:t,currentLocale:i}}=(0,o.Z)(),{pathname:a}=(0,r.TH)(),s=i===t?e:e.replace(`/${i}/`,"/"),c=a.replace(e,"");return{createUrl:function(e){let{locale:o,fullyQualified:r}=e;return`${r?n:""}${function(e){return e===t?`${s}`:`${s}${e}/`}(o)}${c}`}}}},85936:(e,n,t)=>{"use strict";t.d(n,{S:()=>a});var o=t(67294),r=t(76775),i=t(902);function a(e){const n=(0,r.TH)(),t=(0,i.D9)(n),a=(0,i.zX)(e);(0,o.useEffect)((()=>{t&&n!==t&&a({location:n,previousLocation:t})}),[a,n,t])}},86668:(e,n,t)=>{"use strict";t.d(n,{L:()=>r});var o=t(52263);function r(){return(0,o.Z)().siteConfig.themeConfig}},6278:(e,n,t)=>{"use strict";t.d(n,{L:()=>r});var o=t(52263);function r(){const{siteConfig:{themeConfig:e}}=(0,o.Z)();return e}},239:(e,n,t)=>{"use strict";t.d(n,{l:()=>s});var o=t(67294),r=t(98022),i=t(44996),a=t(6278);function s(){const{withBaseUrl:e}=(0,i.C)(),{algolia:{externalUrlRegex:n,replaceSearchResultPathname:t}}=(0,a.L)();return(0,o.useCallback)((o=>{const i=new URL(o);if((0,r.F)(n,i.href))return o;const a=`${i.pathname+i.hash}`;return e(function(e,n){return n?e.replaceAll(new RegExp(n.from,"g"),n.to):e}(a,t))}),[e,n,t])}},8802:(e,n)=>{"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(e,n){const{trailingSlash:t,baseUrl:o}=n;if(e.startsWith("#"))return e;if(void 0===t)return e;const[r]=e.split(/[#?]/),i="/"===r||r===o?r:(a=r,t?function(e){return e.endsWith("/")?e:`${e}/`}(a):function(e){return e.endsWith("/")?e.slice(0,-1):e}(a));var a;return e.replace(r,i)}},54143:(e,n)=>{"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.getErrorCausalChain=void 0,n.getErrorCausalChain=function e(n){return n.cause?[n,...e(n.cause)]:[n]}},18780:function(e,n,t){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.getErrorCausalChain=n.applyTrailingSlash=n.blogPostContainerID=void 0,n.blogPostContainerID="__blog-post-container";var r=t(8802);Object.defineProperty(n,"applyTrailingSlash",{enumerable:!0,get:function(){return o(r).default}});var i=t(54143);Object.defineProperty(n,"getErrorCausalChain",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},86010:(e,n,t)=>{"use strict";function o(e){var n,t,r="";if("string"==typeof e||"number"==typeof e)r+=e;else if("object"==typeof e)if(Array.isArray(e))for(n=0;nr});const r=function(){for(var e,n,t=0,r="";t{"use strict";t.d(n,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>A,Ep:()=>p});var o=t(87462);function r(e){return"/"===e.charAt(0)}function i(e,n){for(var t=n,o=t+1,r=e.length;o=0;p--){var f=a[p];"."===f?i(a,p):".."===f?(i(a,p),d++):d&&(i(a,p),d--)}if(!l)for(;d--;d)a.unshift("..");!l||""===a[0]||a[0]&&r(a[0])||a.unshift("");var m=a.join("/");return t&&"/"!==m.substr(-1)&&(m+="/"),m};var s=t(2177);function c(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,n){return function(e,n){return 0===e.toLowerCase().indexOf(n.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(n.length))}(e,n)?e.substr(n.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var n=e.pathname,t=e.search,o=e.hash,r=n||"/";return t&&"?"!==t&&(r+="?"===t.charAt(0)?t:"?"+t),o&&"#"!==o&&(r+="#"===o.charAt(0)?o:"#"+o),r}function f(e,n,t,r){var i;"string"==typeof e?(i=function(e){var n=e||"/",t="",o="",r=n.indexOf("#");-1!==r&&(o=n.substr(r),n=n.substr(0,r));var i=n.indexOf("?");return-1!==i&&(t=n.substr(i),n=n.substr(0,i)),{pathname:n,search:"?"===t?"":t,hash:"#"===o?"":o}}(e),i.state=n):(void 0===(i=(0,o.Z)({},e)).pathname&&(i.pathname=""),i.search?"?"!==i.search.charAt(0)&&(i.search="?"+i.search):i.search="",i.hash?"#"!==i.hash.charAt(0)&&(i.hash="#"+i.hash):i.hash="",void 0!==n&&void 0===i.state&&(i.state=n));try{i.pathname=decodeURI(i.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+i.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return t&&(i.key=t),r?i.pathname?"/"!==i.pathname.charAt(0)&&(i.pathname=a(i.pathname,r.pathname)):i.pathname=r.pathname:i.pathname||(i.pathname="/"),i}function m(){var e=null;var n=[];return{setPrompt:function(n){return e=n,function(){e===n&&(e=null)}},confirmTransitionTo:function(n,t,o,r){if(null!=e){var i="function"==typeof e?e(n,t):e;"string"==typeof i?"function"==typeof o?o(i,r):r(!0):r(!1!==i)}else r(!0)},appendListener:function(e){var t=!0;function o(){t&&e.apply(void 0,arguments)}return n.push(o),function(){t=!1,n=n.filter((function(e){return e!==o}))}},notifyListeners:function(){for(var e=arguments.length,t=new Array(e),o=0;on?t.splice(n,t.length-n,r):t.push(r),d({action:o,location:r,index:n,entries:t})}}))},replace:function(e,n){var o="REPLACE",r=f(e,n,g(),w.location);u.confirmTransitionTo(r,o,t,(function(e){e&&(w.entries[w.index]=r,d({action:o,location:r}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var n=w.index+e;return n>=0&&n{"use strict";var o=t(59864),r={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function c(e){return o.isMemo(e)?a:s[e.$$typeof]||r}s[o.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[o.Memo]=a;var l=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(n,t,o){if("string"!=typeof t){if(m){var r=f(t);r&&r!==m&&e(n,r,o)}var a=u(t);d&&(a=a.concat(d(t)));for(var s=c(n),g=c(t),h=0;h{"use strict";e.exports=function(e,n,t,o,r,i,a,s){if(!e){var c;if(void 0===n)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[t,o,r,i,a,s],u=0;(c=new Error(n.replace(/%s/g,(function(){return l[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},32497:(e,n,t)=>{"use strict";t.r(n)},52295:(e,n,t)=>{"use strict";t.r(n)},74865:function(e,n,t){var o,r;o=function(){var e,n,t={version:"0.2.0"},o=t.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function r(e,n,t){return et?t:e}function i(e){return 100*(-1+e)}function a(e,n,t){var r;return(r="translate3d"===o.positionUsing?{transform:"translate3d("+i(e)+"%,0,0)"}:"translate"===o.positionUsing?{transform:"translate("+i(e)+"%,0)"}:{"margin-left":i(e)+"%"}).transition="all "+n+"ms "+t,r}t.configure=function(e){var n,t;for(n in e)void 0!==(t=e[n])&&e.hasOwnProperty(n)&&(o[n]=t);return this},t.status=null,t.set=function(e){var n=t.isStarted();e=r(e,o.minimum,1),t.status=1===e?null:e;var i=t.render(!n),l=i.querySelector(o.barSelector),u=o.speed,d=o.easing;return i.offsetWidth,s((function(n){""===o.positionUsing&&(o.positionUsing=t.getPositioningCSS()),c(l,a(e,u,d)),1===e?(c(i,{transition:"none",opacity:1}),i.offsetWidth,setTimeout((function(){c(i,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){t.remove(),n()}),u)}),u)):setTimeout(n,u)})),this},t.isStarted=function(){return"number"==typeof t.status},t.start=function(){t.status||t.set(0);var e=function(){setTimeout((function(){t.status&&(t.trickle(),e())}),o.trickleSpeed)};return o.trickle&&e(),this},t.done=function(e){return e||t.status?t.inc(.3+.5*Math.random()).set(1):this},t.inc=function(e){var n=t.status;return n?("number"!=typeof e&&(e=(1-n)*r(Math.random()*n,.1,.95)),n=r(n+e,0,.994),t.set(n)):t.start()},t.trickle=function(){return t.inc(Math.random()*o.trickleRate)},e=0,n=0,t.promise=function(o){return o&&"resolved"!==o.state()?(0===n&&t.start(),e++,n++,o.always((function(){0==--n?(e=0,t.done()):t.set((e-n)/e)})),this):this},t.render=function(e){if(t.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var n=document.createElement("div");n.id="nprogress",n.innerHTML=o.template;var r,a=n.querySelector(o.barSelector),s=e?"-100":i(t.status||0),l=document.querySelector(o.parent);return c(a,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),o.showSpinner||(r=n.querySelector(o.spinnerSelector))&&f(r),l!=document.body&&u(l,"nprogress-custom-parent"),l.appendChild(n),n},t.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(o.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},t.isRendered=function(){return!!document.getElementById("nprogress")},t.getPositioningCSS=function(){var e=document.body.style,n="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return n+"Perspective"in e?"translate3d":n+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function n(){var t=e.shift();t&&t(n)}return function(t){e.push(t),1==e.length&&n()}}(),c=function(){var e=["Webkit","O","Moz","ms"],n={};function t(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,n){return n.toUpperCase()}))}function o(n){var t=document.body.style;if(n in t)return n;for(var o,r=e.length,i=n.charAt(0).toUpperCase()+n.slice(1);r--;)if((o=e[r]+i)in t)return o;return n}function r(e){return e=t(e),n[e]||(n[e]=o(e))}function i(e,n,t){n=r(n),e.style[n]=t}return function(e,n){var t,o,r=arguments;if(2==r.length)for(t in n)void 0!==(o=n[t])&&n.hasOwnProperty(t)&&i(e,t,o);else i(e,r[1],r[2])}}();function l(e,n){return("string"==typeof e?e:p(e)).indexOf(" "+n+" ")>=0}function u(e,n){var t=p(e),o=t+n;l(t,n)||(e.className=o.substring(1))}function d(e,n){var t,o=p(e);l(e,n)&&(t=o.replace(" "+n+" "," "),e.className=t.substring(1,t.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return t},void 0===(r="function"==typeof o?o.call(n,t,n,e):o)||(e.exports=r)},27418:e=>{"use strict";var n=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;function r(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},t=0;t<10;t++)n["_"+String.fromCharCode(t)]=t;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n[e]})).join(""))return!1;var o={};return"abcdefghijklmnopqrst".split("").forEach((function(e){o[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},o)).join("")}catch(r){return!1}}()?Object.assign:function(e,i){for(var a,s,c=r(e),l=1;l{var o=t(5826);e.exports=f,e.exports.parse=i,e.exports.compile=function(e,n){return s(i(e,n),n)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var r=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function i(e,n){for(var t,o=[],i=0,a=0,s="",u=n&&n.delimiter||"/";null!=(t=r.exec(e));){var d=t[0],p=t[1],f=t.index;if(s+=e.slice(a,f),a=f+d.length,p)s+=p[1];else{var m=e[a],g=t[2],h=t[3],k=t[4],b=t[5],v=t[6],w=t[7];s&&(o.push(s),s="");var y=null!=g&&null!=m&&m!==g,_="+"===v||"*"===v,x="?"===v||"*"===v,E=t[2]||u,S=k||b;o.push({name:h||i++,prefix:g||"",delimiter:E,optional:x,repeat:_,partial:y,asterisk:!!w,pattern:S?l(S):w?".*":"[^"+c(E)+"]+?"})}}return a{"use strict";t.d(n,{Z:()=>i});var o=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,t={},o={util:{encode:function e(n){return n instanceof r?new r(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=d.reach);x+=_.value.length,_=_.next){var E=_.value;if(n.length>e.length)return;if(!(E instanceof r)){var S,C=1;if(b){if(!(S=i(y,x,e,k))||S.index>=e.length)break;var T=S.index,A=S.index+S[0].length,L=x;for(L+=_.value.length;T>=L;)L+=(_=_.next).value.length;if(x=L-=_.value.length,_.value instanceof r)continue;for(var P=_;P!==n.tail&&(Ld.reach&&(d.reach=I);var D=_.prev;if(N&&(D=c(n,D,N),x+=N.length),l(n,D,C),_=c(n,D,new r(p,h?o.tokenize(R,h):R,v,R)),O&&c(n,_,O),C>1){var M={cause:p+","+m,reach:I};a(e,n,t,_.prev,x,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function c(e,n,t){var o=n.next,r={value:t,prev:n,next:o};return n.next=r,o.prev=r,e.length++,r}function l(e,n,t){for(var o=n.next,r=0;r"+i.content+""},o}(),r=o;o.default=o,r.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},r.languages.markup.tag.inside["attr-value"].inside.entity=r.languages.markup.entity,r.languages.markup.doctype.inside["internal-subset"].inside=r.languages.markup,r.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(r.languages.markup.tag,"addInlined",{value:function(e,n){var t={};t["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:r.languages[n]},t.cdata=/^$/i;var o={"included-cdata":{pattern://i,inside:t}};o["language-"+n]={pattern:/[\s\S]+/,inside:r.languages[n]};var i={};i[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:o},r.languages.insertBefore("markup","cdata",i)}}),Object.defineProperty(r.languages.markup.tag,"addAttribute",{value:function(e,n){r.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:r.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),r.languages.html=r.languages.markup,r.languages.mathml=r.languages.markup,r.languages.svg=r.languages.markup,r.languages.xml=r.languages.extend("markup",{}),r.languages.ssml=r.languages.xml,r.languages.atom=r.languages.xml,r.languages.rss=r.languages.xml,function(e){var n="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",t={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},o={bash:t,environment:{pattern:RegExp("\\$"+n),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+n),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+n),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:o},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:t}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:o},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:o.entity}}],environment:{pattern:RegExp("\\$?"+n),alias:"constant"},variable:o.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},t.inside=e.languages.bash;for(var r=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],i=o.variable[1].inside,a=0;a]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},r.languages.c=r.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),r.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),r.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},r.languages.c.string],char:r.languages.c.char,comment:r.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:r.languages.c}}}}),r.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete r.languages.c.boolean,function(e){var n=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,t=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return n.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return n.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:n,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return t}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(r),function(e){var n=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+n.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+n.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+n.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:n,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var t=e.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(r),function(e){var n,t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:n={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=n,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var o={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},r={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:o,number:r,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:o,number:r})}(r),r.languages.javascript=r.languages.extend("clike",{"class-name":[r.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),r.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,r.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:r.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:r.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:r.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:r.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:r.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),r.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:r.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),r.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),r.languages.markup&&(r.languages.markup.tag.addInlined("script","javascript"),r.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),r.languages.js=r.languages.javascript,function(e){var n=/#(?!\{).+/,t={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:n,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:t}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:n,interpolation:t}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:t}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(r),function(e){var n=/[*&][^\s[\]{},]+/,t=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,o="(?:"+t.source+"(?:[ \t]+"+n.source+")?|"+n.source+"(?:[ \t]+"+t.source+")?)",r=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),i=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function a(e,n){n=(n||"").replace(/m/g,"")+"m";var t=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return o})).replace(/<>/g,(function(){return e}));return RegExp(t,n)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return o}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return o})).replace(/<>/g,(function(){return"(?:"+r+"|"+i+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:a(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:a(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:a(i),lookbehind:!0,greedy:!0},number:{pattern:a(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:t,important:n,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(r),function(e){var n=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function t(e){return e=e.replace(//g,(function(){return n})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var o=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,r=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return o})),i=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+r+i+"(?:"+r+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+r+i+")(?:"+r+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(o),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+r+")"+i+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+r+"$"),inside:{"table-header":{pattern:RegExp(o),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:t(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:t(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:t(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:t(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(n){["url","bold","italic","strike","code-snippet"].forEach((function(t){n!==t&&(e.languages.markdown[n].inside.content.inside[t]=e.languages.markdown[t])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(n){if(n&&"string"!=typeof n)for(var t=0,o=n.length;t",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(r),r.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:r.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},r.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var n=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),t=0;t0)){var s=p(/^\{$/,/^\}$/);if(-1===s)continue;for(var c=t;c=0&&f(l,"variable-input")}}}}function u(e){return n[t+e]}function d(e,n){n=n||0;for(var t=0;t?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var n=e.languages.javascript["template-string"],t=n.pattern.source,o=n.inside.interpolation,r=o.inside["interpolation-punctuation"],i=o.pattern.source;function a(n,o){if(e.languages[n])return{pattern:RegExp("((?:"+o+")\\s*)"+t),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:n}}}}function s(e,n){return"___"+n.toUpperCase()+"_"+e+"___"}function c(n,t,o){var r={code:n,grammar:t,language:o};return e.hooks.run("before-tokenize",r),r.tokens=e.tokenize(r.code,r.grammar),e.hooks.run("after-tokenize",r),r.tokens}function l(n){var t={};t["interpolation-punctuation"]=r;var i=e.tokenize(n,t);if(3===i.length){var a=[1,1];a.push.apply(a,c(i[1],e.languages.javascript,"javascript")),i.splice.apply(i,a)}return new e.Token("interpolation",i,o.alias,n)}function u(n,t,o){var r=e.tokenize(n,{interpolation:{pattern:RegExp(i),lookbehind:!0}}),a=0,u={},d=c(r.map((function(e){if("string"==typeof e)return e;for(var t,r=e.content;-1!==n.indexOf(t=s(a++,o)););return u[t]=r,t})).join(""),t,o),p=Object.keys(u);return a=0,function e(n){for(var t=0;t=p.length)return;var o=n[t];if("string"==typeof o||"string"==typeof o.content){var r=p[a],i="string"==typeof o?o:o.content,s=i.indexOf(r);if(-1!==s){++a;var c=i.substring(0,s),d=l(u[r]),f=i.substring(s+r.length),m=[];if(c&&m.push(c),m.push(d),f){var g=[f];e(g),m.push.apply(m,g)}"string"==typeof o?(n.splice.apply(n,[t,1].concat(m)),t+=m.length-1):o.content=m}}else{var h=o.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(o,d,"language-"+o,n)}e.languages.javascript["template-string"]=[a("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),a("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),a("svg",/\bsvg/.source),a("markdown",/\b(?:markdown|md)/.source),a("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),a("sql",/\bsql/.source),n].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(n){n.language in d&&function n(t){for(var o=0,r=t.length;o]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var n=e.languages.extend("typescript",{});delete n["class-name"],e.languages.typescript["class-name"].inside=n,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:n}}}}),e.languages.ts=e.languages.typescript}(r),function(e){function n(e,n){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),n)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:n(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:n(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:n(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var t=["function","function-variable","method","method-variable","property-access"],o=0;o*\.{3}(?:[^{}]|)*\})/.source;function i(e,n){return e=e.replace(//g,(function(){return t})).replace(//g,(function(){return o})).replace(//g,(function(){return r})),RegExp(e,n)}r=i(r).source,e.languages.jsx=e.languages.extend("markup",n),e.languages.jsx.tag.pattern=i(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=n.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:i(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:i(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var a=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(a).join(""):""},s=function(n){for(var t=[],o=0;o0&&t[t.length-1].tagName===a(r.content[0].content[1])&&t.pop():"/>"===r.content[r.content.length-1].content||t.push({tagName:a(r.content[0].content[1]),openedBraces:0}):t.length>0&&"punctuation"===r.type&&"{"===r.content?t[t.length-1].openedBraces++:t.length>0&&t[t.length-1].openedBraces>0&&"punctuation"===r.type&&"}"===r.content?t[t.length-1].openedBraces--:i=!0),(i||"string"==typeof r)&&t.length>0&&0===t[t.length-1].openedBraces){var c=a(r);o0&&("string"==typeof n[o-1]||"plain-text"===n[o-1].type)&&(c=a(n[o-1])+c,n.splice(o-1,1),o--),n[o]=new e.Token("plain-text",c,null,c)}r.content&&"string"!=typeof r.content&&s(r.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(r),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var n={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(n).forEach((function(t){var o=n[t],r=[];/^\w+$/.test(t)||r.push(/\w+/.exec(t)[0]),"diff"===t&&r.push("bold"),e.languages.diff[t]={pattern:RegExp("^(?:["+o+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:r,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(t)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:n})}(r),r.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},r.languages.go=r.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),r.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete r.languages.go["class-name"],function(e){function n(e,n){return"___"+e.toUpperCase()+n+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(t,o,r,i){if(t.language===o){var a=t.tokenStack=[];t.code=t.code.replace(r,(function(e){if("function"==typeof i&&!i(e))return e;for(var r,s=a.length;-1!==t.code.indexOf(r=n(o,s));)++s;return a[s]=e,r})),t.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(t,o){if(t.language===o&&t.tokenStack){t.grammar=e.languages[o];var r=0,i=Object.keys(t.tokenStack);!function a(s){for(var c=0;c=i.length);c++){var l=s[c];if("string"==typeof l||l.content&&"string"==typeof l.content){var u=i[r],d=t.tokenStack[u],p="string"==typeof l?l:l.content,f=n(o,u),m=p.indexOf(f);if(m>-1){++r;var g=p.substring(0,m),h=new e.Token(o,e.tokenize(d,t.grammar),"language-"+o,d),k=p.substring(m+f.length),b=[];g&&b.push.apply(b,a([g])),b.push(h),k&&b.push.apply(b,a([k])),"string"==typeof l?s.splice.apply(s,[c,1].concat(b)):l.content=b}}else l.content&&a(l.content)}return s}(t.tokens)}}}})}(r),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(n){e.languages["markup-templating"].buildPlaceholders(n,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(n){e.languages["markup-templating"].tokenizePlaceholders(n,"handlebars")})),e.languages.hbs=e.languages.handlebars}(r),r.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},r.languages.webmanifest=r.languages.json,r.languages.less=r.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),r.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),r.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},r.languages.objectivec=r.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete r.languages.objectivec["class-name"],r.languages.objc=r.languages.objectivec,r.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},r.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},r.languages.python["string-interpolation"].inside.interpolation.inside.rest=r.languages.python,r.languages.py=r.languages.python,r.languages.reason=r.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),r.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete r.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var n=/\$[-\w]+|#\{\$[-\w]+\}/,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:n,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:n,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(r),r.languages.scss=r.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),r.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),r.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),r.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),r.languages.scss.atrule.inside.rest=r.languages.scss,function(e){var n={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},t={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},o={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:n,number:t,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:n,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:t,punctuation:/[{}()\[\];:,]/};o.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:o}},o.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:o}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:o}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:o}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:o}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:o.interpolation}},rest:o}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:o.interpolation,comment:o.comment,punctuation:/[{},]/}},func:o.func,string:o.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:o.interpolation,punctuation:/[{}()\[\];:.]/}}(r),function(e){var n=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",n),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var t=e.languages.tsx.tag;t.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(r),r.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const i=r},29901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,n,t)=>{const o=t(29901),r=t(39642),i=new Set;function a(e){void 0===e?e=Object.keys(o.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const n=[...i,...Object.keys(Prism.languages)];r(o,e,n).load((e=>{if(!(e in o.languages))return void(a.silent||console.warn("Language does not exist: "+e));const n="./prism-"+e;delete t.c[t(16500).resolve(n)],delete Prism.languages[e],t(16500)(n),i.add(e)}))}a.silent=!1,e.exports=a},6726:(e,n,t)=>{var o={"./":2885};function r(e){var n=i(e);return t(n)}function i(e){if(!t.o(o,e)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return o[e]}r.keys=function(){return Object.keys(o)},r.resolve=i,e.exports=r,r.id=6726},16500:(e,n,t)=>{var o={"./":2885};function r(e){var n=i(e);return t(n)}function i(e){if(!t.o(o,e)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return o[e]}r.keys=function(){return Object.keys(o)},r.resolve=i,e.exports=r,r.id=16500},39642:e=>{"use strict";var n=function(){var e=function(){};function n(e,n){Array.isArray(e)?e.forEach(n):null!=e&&n(e,0)}function t(e){for(var n={},t=0,o=e.length;t "));var s={},c=e[o];if(c){function l(n){if(!(n in e))throw new Error(o+" depends on an unknown component "+n);if(!(n in s))for(var a in r(n,i),s[n]=!0,t[n])s[a]=!0}n(c.require,l),n(c.optional,l),n(c.modify,l)}t[o]=s,i.pop()}}return function(e){var n=t[e];return n||(r(e,o),n=t[e]),n}}function r(e){for(var n in e)return!0;return!1}return function(i,a,s){var c=function(e){var n={};for(var t in e){var o=e[t];for(var r in o)if("meta"!=r){var i=o[r];n[r]="string"==typeof i?{title:i}:i}}return n}(i),l=function(e){var t;return function(o){if(o in e)return o;if(!t)for(var r in t={},e){var i=e[r];n(i&&i.alias,(function(n){if(n in t)throw new Error(n+" cannot be alias for both "+r+" and "+t[n]);if(n in e)throw new Error(n+" cannot be alias of "+r+" because it is a component.");t[n]=r}))}return t[o]||o}}(c);a=a.map(l),s=(s||[]).map(l);var u=t(a),d=t(s);a.forEach((function e(t){var o=c[t];n(o&&o.require,(function(n){n in d||(u[n]=!0,e(n))}))}));for(var p,f=o(c),m=u;r(m);){for(var g in p={},m){var h=c[g];n(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var k in d)if(!(k in u))for(var b in f(k))if(b in u){p[k]=!0;break}for(var v in m=p)u[v]=!0}var w={getIds:function(){var e=[];return w.load((function(n){e.push(n)})),e},load:function(n,t){return function(n,t,o,r){var i=r?r.series:void 0,a=r?r.parallel:e,s={},c={};function l(e){if(e in s)return s[e];c[e]=!0;var r,u=[];for(var d in n(e))d in t&&u.push(d);if(0===u.length)r=o(e);else{var p=a(u.map((function(e){var n=l(e);return delete c[e],n})));i?r=i(p,(function(){return o(e)})):o(e)}return s[e]=r}for(var u in t)l(u);var d=[];for(var p in c)d.push(s[p]);return a(d)}(f,u,n,t)}};return w}}();e.exports=n},92703:(e,n,t)=>{"use strict";var o=t(50414);function r(){}function i(){}i.resetWarningCache=r,e.exports=function(){function e(e,n,t,r,i,a){if(a!==o){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function n(){return e}e.isRequired=e;var t={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:n,element:e,elementType:e,instanceOf:n,node:e,objectOf:n,oneOf:n,oneOfType:n,shape:n,exact:n,checkPropTypes:i,resetWarningCache:r};return t.PropTypes=t,t}},45697:(e,n,t)=>{e.exports=t(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,n,t)=>{"use strict";var o=t(67294),r=t(27418),i=t(63840);function a(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t