{
    "componentChunkName": "component---src-templates-issues-tsx",
    "path": "/issues/335",
    "result": {"data":{"issuesJson":{"id":"c693fe52-97d7-5259-b7e5-3fc59bf28299","title":"danielfoehrKn/kubeswitch: 一款 k8s 多集群配置文件管理切换工具","number":335,"bodyHTML":"<div align=\"center\" dir=\"auto\">\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\"><img src=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\" width=\"100%\" height=\"3\" data-animated-image=\"\" data-canonical-src=\"https://cdn.jsdelivr.net/gh/eryajf/tu@main/img/image_20240420_214408.gif\" style=\"max-width: 100%; height: auto; max-height: 3px;\"></a><br><br></p>\n<markdown-accessiblity-table><table role=\"table\">\n<thead>\n<tr>\n<th align=\"right\">Repos</th>\n<th align=\"left\"><a href=\"https://github.com/danielfoehrKn/kubeswitch\">danielfoehrKn/kubeswitch</a></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"right\"><strong>Views</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/8bb13b01ee076be7ead511e0e543dac96f69576fd553afbbfe325231b9a41b90/68747470733a2f2f76696577732e77686174696c656172656e65642e746f6461792f76696577732f6769746875622f64616e69656c666f6568724b6e2f6b7562657377697463682e737667\" alt=\"views\" data-canonical-src=\"https://views.whatilearened.today/views/github/danielfoehrKn/kubeswitch.svg\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>Stars</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/f8d99df744e096fac5c19e5fa9e797d1a781d62bdd9781a73219f8f5846790ac/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f64616e69656c666f6568724b6e2f6b7562657377697463683f636f6c6f723d663266303864266c6f676f3d556e64657274616c65266c6f676f436f6c6f723d656234363330\" alt=\"stars\" data-canonical-src=\"https://img.shields.io/github/stars/danielfoehrKn/kubeswitch?color=f2f08d&amp;logo=Undertale&amp;logoColor=eb4630\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>Forks</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/4ab1faa8257a0790be566baf5a8904b798e11cfc0d0e9c9b6338e27a63be4d8b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f64616e69656c666f6568724b6e2f6b7562657377697463683f636f6c6f723d626138366562266c6f676f3d48616e647368616b65266c6f676f436f6c6f723d656136616136\" alt=\"forks\" data-canonical-src=\"https://img.shields.io/github/forks/danielfoehrKn/kubeswitch?color=ba86eb&amp;logo=Handshake&amp;logoColor=ea6aa6\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>License</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/d02da0d88ef38f1dcfdbd5d5c9dc1d6582ea97a84d8fab5f27223b8a8d8b0ae9/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f64616e69656c666f6568724b6e2f6b7562657377697463683f6c6f676f3d64617461253341696d616765253246706e672533426261736536342532436956424f5277304b47676f414141414e53556845556741414144414141414177434159414141425841766d48414141414358424957584d41414173544141414c457745416d70775941414144336b6c45515652346e4f335953557a5555426748384a726f57567255474a66456d3773584e63534446784d544c327069347348456778654e526f77586770455742445552522532424e414e4f4b4f4b36366f6f4b4a4742586545475263574163455646475152484677516d483525324630774861655748493944554455354c356b6e6568644f62377a66652532423139636e434a47495243516945596c514237594a4979474c38616f73756c565a36695246516a69474b6b7564576735614c6c704f70704e586e665071773555304459524a6d56786a4367464633424c755a476d416f5655694b4541726d583744375553677351706f72674761336748664b34483663754262435644334771683141352532424c6745253242467749656e514d306a6f446f66714c6f48564e7742796d384370546e416d327a51713073676478624964515a556c416b7150415a3664676a303541446f59526f6f66792532466f5869726f376b3551586a4c6f70677a4b69514e6c4c4461716f4967754577426a7a7150355066446a45394479495879493633464d547751464d43567271774e61763451666f52673538514625324266724d485172454b3844546f434d714e4179574e4866786d54526f4c4f726d5352566747744466714345715a4f4851727a6f34706243557341333431365169364551394b476a6345465267484f724f4b6e5536574162396247455459656b4b7843766a546167394534706a653534446b3551503862624d4859762532464333756541654a6b50304f4778422532424a70426e4172595238455951516e6f4e31414e4661426e5050356c385372736559514c303641646b30464a5938484f5761424d6c6541486a683068506f73497a6c6f3876304125324633345a694f6548726130714b52504d5653493774762532423932747725324676687855654252713456454c674d376642714b354770526d6f514c584e7075625475367a6f4e52706754386e5051627138347764253246494375767978694b4871694e41664933774d367549684271476b4c696977414f734b44714f68743749747239567938536a52424557667941627225324668523142667056514664484a42253246423268683778376a36517077435665655951326b72554235436c636a3641326d3067576a25324244306d4c34397a573563517943484c4e37726a6c6d6d6174457958582532464372547a412532466f51785a6b576c39474a5443566f25324279546a3837253242346769504b6376307149486f344156344430565a727251493334706e70524d36357875652532467a417265453425324654253246536f676c664542794d7369517441546c4c3352414a355948725378365a44665337307337754d486842705225324659423573305057366f455270316236253246667252684b3353444c35546965364f515548516c5133735644752532427a50636b397657453973747225324236496a533967486d5750616861444a25324277434b364e494242587348423948796b587378774470686c436d416476706c6162554a4e6e5a504239342532464e7436784f6538587a4562503257684d335741673147756236744825324233513150673337365239713475716c6e6f36676448476a444f5139306562303141484d3672596975554a314f713472344656756a35765239427a4d3957674e764f7977446869495951467667626366774166774d764863615067425041253246447948476a50624e394138616d6562636477416444354e6633373574787165774e5552656f797677424958594c645170576c6877465771745061435044334173467541535636717171496c62304a766b564331464c39576b4c55556c55574b337a585a4c46432532423125324642726f46746f364f7358497545594a5034447a7a5732594656316f4a614141414141456c46546b5375516d4343\" alt=\"license\" data-canonical-src=\"https://img.shields.io/github/license/danielfoehrKn/kubeswitch?logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD3klEQVR4nO3YSUzUUBgH8JroWVrUGJfEm7sXNcSDFxMTL2pi4sHEgxeNRowXgpEWBDURR%2BNANOKOK66ooKJGBXeEGRcWAcEVFGQRHFwQmH5%2F0wHaeWHI9DUDU5L5knehdOb7zfe%2B19cnCJGIRCQiEYlQB7YJIyGL8aosulVZ6iRFQjiGKkudWg5aLlpOppNXnfPqw5U0DYRJmVxjCgFF3BLuZGmAoVUiKEArmX7D7USgsQporgGa3gHfK4H6cuBbCVD3Gqh1A5%2BLgE%2BFwIenQM0joDofqLoHVNwBym8CpTnAm2zQq0sgdxbIdQZUlAkqPAZ6dgj05ADoYRoofy%2FoXiro7k5QXjLopgzKiQNlLDaqoIguEwBjzqP5PfDjE9DyIXyI63FMTwQFMCVrqwNav4QfoRg58QF%2BfrMHQrEK8DToCMqNAyWNHfxmTRoLOrmSRVgGtDfqCEqZOHQrzo4pbCUsA3416Qi6EQ9KGjcEFRgHOrOKnU6WAb9bGETYekKxCvjTag9E4pje54Dk5QP8bbMHYv%2FC3ueAeJkP0OGxB%2BJpBnArYR8EYQQnoN1ANFaBnPP5l8SrseYQL06Adk0FJY8HOWaBMleAHjh0hPosIzlo8v0A%2F34ZiOeHra0qKRPMVSI7tv%2B92tw%2FvhxUeBRq4VELgM7fBqK5GpRmoQLXNpubTu6zoNRpgT8nPQbq84wd%2FICuvyxiKHqiNAfI3wM6uIhBqGkLiiwAOsKDqOht7Itr9Vy8SjRBEWfyAbr%2FhR1BfpVQFdHJB%2FB2hh7x7j6QpwCVeeYQ2krUB5Clcj6A2m0gWj%2BD0mL49zW5cQyCHLN7rjlmmatEyXX%2FCrTzA%2FoQxZkWl9GJTCVo%2ByTj87%2B4giPKcv0qIHo4AV4D0VZrrQI34pnpRM65xue%2FzAreE4%2FT%2FSoglfEByMsiQtATlL3RAJ5YHrSx6ZDfS70s7uMHhBpR%2FYB5s0PW6oERp1b6%2FfrRhK3SDL5Tie6OQUHQlQ3sVDu%2BzPck9vWE9str%2B6IjS9gHmWPahaDJ%2BwCK6NIBBXsHB9HykXsxwDphlCmAdvplabUJNnZPB94%2FNt6xOe8XzEbP2WhM3WAg1Gub6tH%2B3Q1Pg376R9q4uqlno6gdHGjDOQ90eb01AHM6rYiuUJ1Oq4r4FVuj5vR9BzM9WgNvOywDhiIYQFvgbcfwAfwMvHcaPgBPA%2FDyHGjPbN9A8amebcdwAdD5Nf375txqewNUReoyvwBIXYLdQpWlhwFWqtPaCPD3AsFuASV6qqqIlb0JvkVC1FL9WkLUUlUWK3zXZLFC%2B1%2FBroFto6OsXIuEYJP4DzzW2YFV1oJaAAAAAElFTkSuQmCC\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>UpdatedAt</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/db54523674dc1954c137172f4731c5f9e9176ee44d4bed3d64d66c6156c4b2ce/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f64616e69656c666f6568724b6e2f6b7562657377697463683f646973706c61795f74696d657374616d703d636f6d6d6974746572266c6f676f3d64617461253341696d616765253246706e672533426261736536342532436956424f5277304b47676f414141414e5355684555674141414234414141416543415941414141374d4b3669414141414358424957584d41414173544141414c457745416d7077594141414648556c45515652346e4c5658375539615678776d3236646c582532466468627825324232253246516e626b7655627264554151674a4a496655444e574454546d4f76314651554661504a346b7573725630314a7431734e70637453327533626f745a746d786439744a5346536f714b71494635625944464c436f76436c656673747a4a387758524c445a4c7a6e6b634f343535376e3364332532466e655a3472454f515a74315771462532423858467234253242664f4c4565326a6f59307a776638546f795a50766a45676b4c592532426b306d6d72584f36644b696e787a476b30666a5430782532425279723055716e6359637a4d317263347451253242497270324c4758646f344e4334567657715453373277716c632532427231334f527269364b6458646e624f484c6c776c7a4a70524b6e3657342532424b36706f4f434e6e494166486a253246253242776168495a4234764b6e715a6630714a704e49716c2532467638545530634e6c3572627963337730516e54703379324c54614a374d314e617844723266526e315370504736476961323174664533345463614f617931694d55564f5146624659714957536f31573854694156616e43306576584f4542375770313448466232327a453566714c4f433545524c515769644e614e49347545636339693768634a6c644868324e57725135674464624f6c7061756d49754c62326174415144506e7a3062384e6257636d785656524a33486d7870536377777a4f4a6d4b44524765384c6c435a444c4739673754496e5631516c376462586256316533675430574b697243466f6d6b5079767758466c5a474a4f6a563625324253743634757564445a4f55354555636f782532464d455144567674364d62634e3237593341797a687633737061557242365a3971724a534f3139657a6a387032704c426b4a792532426343484a7857493567573574636652527a31645531394766476b6f7539505a4f34736d52396a4746777065783444793362766e6d4b79706f74625531335669646a71595a68726a343972764d457425324625324659714c7a396430304e6a57253246637a67796f394f35317a7336614e6c6f354644747530445a675146686c47584a30644241446f4e6864367576703657686f617967374e394c564748386d443462253246486e667455516f4e4734764c51306769784d716c5725324234714f6a744e48446733723166365969525347785279375576714c62395534716b716e78504f4e7661356c447048723125324279794b524e4b57425a793565644d554842326d3572792532422532424551772532427a6766347a6f39253246306f634e3357527a4c4277344a2532424a7950574372716d4967475974554f735744346f785a46516f50556a4770564871493425324661666b51504336665a5165654d31253242764c7549516e6a754257514444437363726d485039656f4e5041744271664f6e5875614b25324268364a45624772732532427076764d6d78654962683836336162565065597953456f39464a48704e4d464a59253242503563575a6b6667374f3174537759436553514c54593345385130392532464256504a556c78516a7368543142736343593032723955445542667643484236367063665041336c794165336e6772332532463437584467614a7a736c7937787741364e5a746c555550437541487161536a5549502532427375653842525741432532464e6651374a5a505a35397330476a3756747049537a34685125324243706658474d4b685a63764c70554b7866574d386f68766637702532464f446a4842666356463849736b383267314648796b63564645253242555a414158343761452532464d6c34504f3530506e75683025324678346e6d637957507364774468427836436d6b4c562532466746446a594b784f4a4f4674623077517949684c39527943774b33414f664947703159464542686e4d4a634c525745624b644b516f55366e63545a6b494544696341792532463831645675454d3552775066657934784f7830496b25324649324e6e466b692532425761664f6f464959466367595a43797864376543556a626334416d46363566742532466b4d686b336f25324235686337734d4a79716a4a45477659466151464972375930775077384246415925324236253242766d6b3377367a7a5275444d6d5a5652736668385274413075455453443775434254364459514e36697665553066706b594c6a453671725672744f78654e4b553954484c5a4a396b4255324a427342685635416976422532466f4b61514e4b675043427744596149665a4334616454684f71463457454e56694c4a77566f586f62664c424b56773637414f6154734c6336355461564b32317651344c613939654b6359673576627873624f627a5451394e37554b4467554f3177446a6944494942736868357a746733396e514d4c535a4248344f7a424f55444551586d323036643366634c67737762585141345068634b336e6873775531427a3877765130395248472532466f597933656a6677424e6d746f59714c4130586741414141424a52553545726b4a676767253344253344266c6162656c3d557064617465644174\" alt=\"last-commit\" data-canonical-src=\"https://img.shields.io/github/last-commit/danielfoehrKn/kubeswitch?display_timestamp=committer&amp;logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHUlEQVR4nLVX7U9aVxwm26dlX%2Fdhbx%2B2%2FQnbkvUbrdUAQgJJIfUDNWDTTmOv1FQUFaPJ4kusrV01Jt1sNpctS2u3botZtmxd9tJSFSoqKqIF5bYDFLCovClefstzJ8wXRLDZLznkcO4557n3d3%2FneZ4rEOQZt1WqF%2B8XFr4%2BfOLEe2joY0zwf8ToyZPvjEgkLY%2Bk0mmrXO6dKinxzGk0fjT0x%2BRyr0UqncYczM1rc4tQ%2BIrp2LGXdo4NC4VvWqTS72wqlc%2Br13ORri6KdXdnbOHLlwlzJpRKn6W4%2BK6poOCNnIAfHj%2F%2BwahIZB4vKnqZf0qJpNIql%2Fv8TU0cNl5rbyc3w0QnTp3y2LTaJ7M1NaxDr2fRn1SpPG6Gia21tfE34TcaOay1iMUVOQFbFYqIWSo1W8TiAVanC0evXOEB7Wp14HFb22zE5fqLOC5ERLQWidNaNI4uEcc9i7hcJldHh2NWrQ5gDdbOlpaumIuLb2atAQDPnz0b8NbWcmxVVRJ3HmxpScwwzOJmKDRGe8LlCZDLG9g7TInV1Ql7dbXbV1e3gT0WKirCFomkPyvwXFlZGJOjV6%2BSt64uudDZOU5EUcox%2FMEQDVvt6MbcN27Y3Ayzhv3spaUrB6Z9qrJSO19ezj8p2pLBkJy%2BcCHJxWI5gW5tcfRRz1dU19GfGkou9PZO4smR9jGFwpex4Dy3bvnmKypotbU13VidjqYZhrj49rvMEt%2F%2FYqLz9d00NjW%2Fczgyo9O51zs6aNlo5FDtu0DZgQFhlGXJ0dBADoNhd6uvp6Whoayg7N9LVGH8mD4b%2FHnftUQoNG4vLQ0gixMqlW%2B4qOjtNHDg3r1f6YiRSGxRy7UvqLb9U4qkqnxPONva5lDpHr1%2ByyKRNKWBZy5edMUHB2m5ry%2B%2BEQw%2Bzgf4zo9%2F0ocN3WRzLBw4J%2BJyPWCrqmIgGYtUOsWD4oxZFQoPUjGpVHqI4%2FafkQPC6fZQeeM1%2BvLuIQnjuBWQDDCscrmHP9eoNPAtBqfOnXuaK%2Bh6JEbGrs%2BpvvMmxeIbh863abVPeYySEo9FJHpNMFJY%2BP5cWZkfg7O1tSwYCeSQLTY3E8Q09%2FBVPJUlxQjshT1BscCY02r9UDUBfvCHB66pcfPA3lyAe3ngr3%2F47XDgaJzsly7xwA6NZtlUUPCuAHqaSjUIP%2Bsue8BRWAC%2FNfQ7JZPZ59s0Gj7VtpISz4hQ%2BCpfXGMKhZcvLpUKxfWM8ohvf7p%2FODjHBfcVF8Isk82g1FHykcVFE%2BUZAAX47aE%2FMl4PO50Pnuh0%2Fx4nmcyWPsdwDhBx6CmkLV%2FgFDjYKxOJOFtb0wQyIhL9RyCwK3AOfIGp1YFEBhnMJcLRWEbKdKQoU6ncTZkIEDicAy%2F81dVuEM5RwPfey4xOx0Ik%2FI2NnFki%2BWafOoFIYFcgYZCyxd7eCUjbc4AmF65ft%2FkMhk3o%2B5hc7sMJyqjJEGvYFaQFIr7Y0wPw8BFAY%2B6%2Bvmk3w6zzRuDMmZVRsfh8RtA0uETSD7uCBT6DYQN6iveU0fpkYLjE6qrVrtOxeNKU9THLZJ9kBU2JBsBhV5AivB%2FoKaQNKgPCBwDYaIfZC4adThOqF4WENViLJwVoXobfLBKVw67AOaTsLc65TaVK21vQ4La99eKcYg5vbxsbObzTQ9N7UKDgUO1wDjiDIIBshh5ztg39nQMLSZBH4OzBOUDEQXm206d3fcLgswbXQA4PhcK3nhswU1Bz8wvQ09RHG%2FoYy3ejfwBNmtoYqLA0XgAAAABJRU5ErkJggg%3D%3D&amp;label=UpdatedAt\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>CreatedAt</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/106082eec57e1a6dec96b02fde1e6416b5d18ec51fa6d77df3f3d27303346b3d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f637265617465642d61742f64616e69656c666f6568724b6e2f6b7562657377697463683f6c6f676f3d64617461253341696d616765253246706e672533426261736536342532436956424f5277304b47676f414141414e5355684555674141414234414141416543415941414141374d4b3669414141414358424957584d41414173544141414c457745416d7077594141414648556c45515652346e4c5658375539615678776d3236646c582532466468627825324232253246516e626b7655627264554151674a4a496655444e574454546d4f76314651554661504a346b7573725630314a7431734e70637453327533626f745a746d786439744a5346536f714b71494635625944464c436f76436c656673747a4a387758524c445a4c7a6e6b634f343535376e3364332532466e655a3472454f515a74315771462532423858467234253242664f4c4565326a6f59307a776638546f795a50766a45676b4c592532426b306d6d72584f36644b696e787a476b30666a5430782532425279723055716e6359637a4d317263347451253242497270324c4758646f344e4334567657715453373277716c632532427231334f527269364b6458646e624f484c6c776c7a4a70524b6e3657342532424b36706f4f434e6e494166486a253246253242776168495a4234764b6e715a6630714a704e49716c2532467638545530634e6c3572627963337730516e54703379324c54614a374d314e617844723266526e315370504736476961323174664533345463614f617931694d55564f5146624659714957536f31573854694156616e43306576584f4542375770313448466232327a453566714c4f433545524c515769644e614e49347545636339693768634a6c644868324e57725135674464624f6c7061756d49754c62326174415144506e7a3062384e6257636d785656524a33486d7870536377777a4f4a6d4b44524765384c6c435a444c4739673754496e5631516c376462586256316533675430574b697243466f6d6b5079767758466c5a474a4f6a563625324253743634757564445a4f55354555636f782532464d455144567674364d62634e3237593341797a687633737061557242365a3971724a534f3139657a6a387032704c426b4a792532426343484a7857493567573574636652527a31645531394766476b6f7539505a4f34736d52396a4746777065783444793362766e6d4b79706f74625531335669646a71595a68726a343972764d457425324625324659714c7a396430304e6a57253246637a67796f394f35317a7336614e6c6f354644747530445a675146686c47584a30644241446f4e6864367576703657686f617967374e394c564748386d443462253246486e667455516f4e4734764c51306769784d716c5725324234714f6a744e48446733723166365969525347785279375576714c62395534716b716e78504f4e7661356c447048723125324279794b524e4b57425a793565644d554842326d3572792532422532424551772532427a6766347a6f39253246306f634e3357527a4c4277344a2532424a7950574372716d4967475974554f735744346f785a46516f50556a4770564871493425324661666b51504336665a5165654d31253242764c7549516e6a754257514444437363726d485039656f4e5041744271664f6e5875614b25324268364a45624772732532427076764d6d78654962683836336162565065597953456f39464a48704e4d464a59253242503563575a6b6667374f3174537759436553514c54593345385130392532464256504a556c78516a7368543142736343593032723955445542667643484236367063665041336c794165336e6772332532463437584467614a7a736c7937787741364e5a746c555550437541487161536a5549502532427375653842525741432532464e6651374a5a505a35397330476a3756747049537a34685125324243706658474d4b685a63764c70554b7866574d386f68766637702532464f446a4842666356463849736b383267314648796b63564645253242555a414158343761452532464d6c34504f3530506e75683025324678346e6d637957507364774468427836436d6b4c562532466746446a594b784f4a4f4674623077517949684c39527943774b33414f664947703159464542686e4d4a634c525745624b644b516f55366e63545a6b494544696341792532463831645675454d3552775066657934784f7830496b25324649324e6e466b692532425761664f6f464959466367595a43797864376543556a626334416d46363566742532466b4d686b336f25324235686337734d4a79716a4a45477659466151464972375930775077384246415925324236253242766d6b3377367a7a5275444d6d5a5652736668385274413075455453443775434254364459514e36697665553066706b594c6a453671725672744f78654e4b553954484c5a4a396b4255324a427342685635416976422532466f4b61514e4b675043427744596149665a4334616454684f71463457454e56694c4a77566f586f62664c424b56773637414f6154734c6336355461564b32317651344c613939654b6359673576627873624f627a5451394e37554b4467554f3177446a6944494942736868357a746733396e514d4c535a4248344f7a424f55444551586d323036643366634c67737762585141345068634b336e6873775531427a3877765130395248472532466f597933656a6677424e6d746f59714c4130586741414141424a52553545726b4a676767253344253344266c6162656c3d437265617465644174\" alt=\"create-at\" data-canonical-src=\"https://img.shields.io/github/created-at/danielfoehrKn/kubeswitch?logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHUlEQVR4nLVX7U9aVxwm26dlX%2Fdhbx%2B2%2FQnbkvUbrdUAQgJJIfUDNWDTTmOv1FQUFaPJ4kusrV01Jt1sNpctS2u3botZtmxd9tJSFSoqKqIF5bYDFLCovClefstzJ8wXRLDZLznkcO4557n3d3%2FneZ4rEOQZt1WqF%2B8XFr4%2BfOLEe2joY0zwf8ToyZPvjEgkLY%2Bk0mmrXO6dKinxzGk0fjT0x%2BRyr0UqncYczM1rc4tQ%2BIrp2LGXdo4NC4VvWqTS72wqlc%2Br13ORri6KdXdnbOHLlwlzJpRKn6W4%2BK6poOCNnIAfHj%2F%2BwahIZB4vKnqZf0qJpNIql%2Fv8TU0cNl5rbyc3w0QnTp3y2LTaJ7M1NaxDr2fRn1SpPG6Gia21tfE34TcaOay1iMUVOQFbFYqIWSo1W8TiAVanC0evXOEB7Wp14HFb22zE5fqLOC5ERLQWidNaNI4uEcc9i7hcJldHh2NWrQ5gDdbOlpaumIuLb2atAQDPnz0b8NbWcmxVVRJ3HmxpScwwzOJmKDRGe8LlCZDLG9g7TInV1Ql7dbXbV1e3gT0WKirCFomkPyvwXFlZGJOjV6%2BSt64uudDZOU5EUcox%2FMEQDVvt6MbcN27Y3Ayzhv3spaUrB6Z9qrJSO19ezj8p2pLBkJy%2BcCHJxWI5gW5tcfRRz1dU19GfGkou9PZO4smR9jGFwpex4Dy3bvnmKypotbU13VidjqYZhrj49rvMEt%2F%2FYqLz9d00NjW%2Fczgyo9O51zs6aNlo5FDtu0DZgQFhlGXJ0dBADoNhd6uvp6Whoayg7N9LVGH8mD4b%2FHnftUQoNG4vLQ0gixMqlW%2B4qOjtNHDg3r1f6YiRSGxRy7UvqLb9U4qkqnxPONva5lDpHr1%2ByyKRNKWBZy5edMUHB2m5ry%2B%2BEQw%2Bzgf4zo9%2F0ocN3WRzLBw4J%2BJyPWCrqmIgGYtUOsWD4oxZFQoPUjGpVHqI4%2FafkQPC6fZQeeM1%2BvLuIQnjuBWQDDCscrmHP9eoNPAtBqfOnXuaK%2Bh6JEbGrs%2BpvvMmxeIbh863abVPeYySEo9FJHpNMFJY%2BP5cWZkfg7O1tSwYCeSQLTY3E8Q09%2FBVPJUlxQjshT1BscCY02r9UDUBfvCHB66pcfPA3lyAe3ngr3%2F47XDgaJzsly7xwA6NZtlUUPCuAHqaSjUIP%2Bsue8BRWAC%2FNfQ7JZPZ59s0Gj7VtpISz4hQ%2BCpfXGMKhZcvLpUKxfWM8ohvf7p%2FODjHBfcVF8Isk82g1FHykcVFE%2BUZAAX47aE%2FMl4PO50Pnuh0%2Fx4nmcyWPsdwDhBx6CmkLV%2FgFDjYKxOJOFtb0wQyIhL9RyCwK3AOfIGp1YFEBhnMJcLRWEbKdKQoU6ncTZkIEDicAy%2F81dVuEM5RwPfey4xOx0Ik%2FI2NnFki%2BWafOoFIYFcgYZCyxd7eCUjbc4AmF65ft%2FkMhk3o%2B5hc7sMJyqjJEGvYFaQFIr7Y0wPw8BFAY%2B6%2Bvmk3w6zzRuDMmZVRsfh8RtA0uETSD7uCBT6DYQN6iveU0fpkYLjE6qrVrtOxeNKU9THLZJ9kBU2JBsBhV5AivB%2FoKaQNKgPCBwDYaIfZC4adThOqF4WENViLJwVoXobfLBKVw67AOaTsLc65TaVK21vQ4La99eKcYg5vbxsbObzTQ9N7UKDgUO1wDjiDIIBshh5ztg39nQMLSZBH4OzBOUDEQXm206d3fcLgswbXQA4PhcK3nhswU1Bz8wvQ09RHG%2FoYy3ejfwBNmtoYqLA0XgAAAABJRU5ErkJggg%3D%3D&amp;label=CreatedAt\" style=\"max-width: 100%;\"></a></td>\n</tr>\n</tbody>\n</table></markdown-accessiblity-table>\n<a href=\"https://github.com/opsre/awesome-ops\">\n</a><p dir=\"auto\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/b964a36ea4078c39f603d46a29436371c7541a2f26e0228d7b21b9d9805b43d3/68747470733a2f2f736f6369616c6966792e6769742e63692f6f707372652f617765736f6d652d6f70732f696d6167653f6465736372697074696f6e3d3126666f6e743d42697474657226666f726b733d31266973737565733d31266c616e67756167653d31266c6f676f3d6874747073253341253246253246617661746172732e67697468756275736572636f6e74656e742e636f6d25324675253246313838353638303230266e616d653d31266f776e65723d31267061747465726e3d436972637569742b426f6172642670756c6c733d31267374617267617a6572733d31267468656d653d4c69676874\" alt=\"\" data-canonical-src=\"https://socialify.git.ci/opsre/awesome-ops/image?description=1&amp;font=Bitter&amp;forks=1&amp;issues=1&amp;language=1&amp;logo=https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F188568020&amp;name=1&amp;owner=1&amp;pattern=Circuit+Board&amp;pulls=1&amp;stargazers=1&amp;theme=Light\" style=\"max-width: 100%;\"></a></p>\n<a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\"><img src=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\" width=\"100%\" height=\"3\" data-animated-image=\"\" data-canonical-src=\"https://cdn.jsdelivr.net/gh/eryajf/tu@main/img/image_20240420_214408.gif\" style=\"max-width: 100%; height: auto; max-height: 3px;\"></a>\n</div>\n<h1 dir=\"auto\">Kubeswitch</h1>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://camo.githubusercontent.com/ab70aaa17c9b07b7cc92aaa23a4589c54aee5002615e878c56199bb925562e54/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f64616e69656c666f6568726b6e2f6b7562657377697463682e737667\"><img src=\"https://camo.githubusercontent.com/ab70aaa17c9b07b7cc92aaa23a4589c54aee5002615e878c56199bb925562e54/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f64616e69656c666f6568726b6e2f6b7562657377697463682e737667\" alt=\"Latest GitHub release\" data-canonical-src=\"https://img.shields.io/github/v/release/danielfoehrkn/kubeswitch.svg\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://github.com/danielfoehrKn/switch/actions?query=workflow%3A%22Build%22\"><img src=\"https://github.com/danielfoehrKn/kubeswitch/workflows/Build/badge.svg\" alt=\"Build\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://goreportcard.com/badge/github.com/danielfoehrKn/kubeswitch\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/e32dd0b930cdf8266040fd97b7fc1937ebf8e61f0826819c9596c6797d134e2d/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f64616e69656c666f6568724b6e2f6b756265737769746368\" alt=\"Go Report Card\" data-canonical-src=\"https://goreportcard.com/badge/github.com/danielfoehrKn/kubeswitch\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://opensource.org/licenses/Apache-2.0\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/859a1a0bc85ce8bbd7a730a274fec5c9e77c4726ffdf6aa762a78685e26033a4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d417061636865253230322e302d626c75652e737667\" alt=\"License\" data-canonical-src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg\" style=\"max-width: 100%;\"></a></p>\n<p dir=\"auto\">The kubectx for operators.</p>\n<p dir=\"auto\"><code class=\"notranslate\">kubeswitch</code> (lazy: <code class=\"notranslate\">switch</code>) is the single pane of glass for all of your kubeconfig files.<br>\nCaters to operators of large scale Kubernetes installations.<br>\nDesigned as a <a href=\"#difference-to-kubectx\">drop-in replacement</a> for <a href=\"https://github.com/ahmetb/kubectx\">kubectx</a>.</p>\n<h2 dir=\"auto\">Highlights</h2>\n<ul dir=\"auto\">\n<li><strong>Unified search over multiple providers</strong>\n<ul dir=\"auto\">\n<li><a href=\"docs/stores/eks/eks.md\">Amazon Elastic Kubernetes Service (EKS)</a></li>\n<li><a href=\"docs/stores/azure/azure.md\">Azure Kubernetes Service (AKS)</a></li>\n<li><a href=\"docs/stores/digitalocean/digitalocean.md\">DigitalOcean Kubernetes (DOKS)</a></li>\n<li><a href=\"docs/stores/exoscale/exoscale.md\">Exoscale</a></li>\n<li><a href=\"docs/stores/gardener/gardener.md\">Gardener</a></li>\n<li><a href=\"docs/stores/gke/gke.md\">Google Kubernetes Engine (GKE)</a></li>\n<li><a href=\"docs/stores/vault/use_vault_store.md\">Hashicorp Vault</a></li>\n<li><a href=\"docs/stores/filesystem/filesystem.md\">Local filesystem</a></li>\n<li><a href=\"docs/stores/ovh/ovh.md\">OVH</a></li>\n<li><a href=\"docs/stores/rancher/rancher.md\">Rancher</a></li>\n<li>Scaleway (documentation tbd)</li>\n<li><a href=\"docs/stores/akamai/akamai.md\">Akamai / Linode</a></li>\n<li><a href=\"docs/stores/capi/capi.md\">Cluster API (capi)</a></li>\n<li>Your favorite Cloud Provider or Managed Kubernetes Platform is not supported yet? Looking for contributions!</li>\n</ul>\n</li>\n<li><strong>Change the namespace</strong></li>\n<li><strong>Change to any context and namespace from the history</strong></li>\n<li><strong>Terminal Window Isolation</strong>\n<ul dir=\"auto\">\n<li>Each terminal window can target a different cluster (does not overwrite the current-context in a shared Kubeconfig)</li>\n<li>Each terminal window can target the same cluster and set a <a href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#setting-the-namespace-preference\" rel=\"nofollow\">different namespace preference</a></li>\n</ul>\n</li>\n<li><strong>Efficiency</strong>: uses local caches for kubeconfig contexts and namespaces</li>\n<li><strong>Advanced Search Capabilities</strong>\n<ul dir=\"auto\">\n<li>Hot reload capability (adds Kubeconfigs to the search on the fly - especially useful when searching large directories)</li>\n<li>Live preview of the selected Kubeconfig file (<strong>sanitized from credentials</strong>)</li>\n<li>Recursive search (e.g. on the local filesystem or in Vault)</li>\n<li>Easily find clusters with <a href=\"#search-cryptic-context-names\">cryptic context names</a></li>\n</ul>\n</li>\n<li><strong>Easy Navigation</strong>\n<ul dir=\"auto\">\n<li>Define alias names for contexts without changing the underlying Kubeconfig</li>\n</ul>\n</li>\n<li><strong>Extensibility</strong>\n<ul dir=\"auto\">\n<li>Integrate custom functionality using <a href=\"./hooks/README.md\">Hooks</a> (comparable with Git pre-commit hooks).</li>\n<li>Build your own integration e.g., synchronise Kubeconfig files of clusters from Git or remote systems.</li>\n</ul>\n</li>\n</ul>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"resources/gifs/switch-demo-large.gif\"><img src=\"resources/gifs/switch-demo-large.gif\" alt=\"demo GIF\" data-animated-image=\"\" style=\"max-width: 100%;\"></a></p>\n<h2 dir=\"auto\">Non-goals</h2>\n<ul dir=\"auto\">\n<li>To provide a customized shell prompt. Use <a href=\"https://github.com/jonmosco/kube-ps1\">kube-ps1</a>.</li>\n</ul>\n<h2 dir=\"auto\">Installation</h2>\n<p dir=\"auto\">Kubeswitch can be installed using <code class=\"notranslate\">brew</code> for OSX, MacPorts, from Github Releases or from source.<br>\nPlease <a href=\"docs/installation.md\">see the documentation</a>.</p>\n<h2 dir=\"auto\">Usage</h2>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"$ switch -h\nThe kubectx for operators.\n\nUsage:\n  switch [flags]\n  switch [command]\n\nAvailable Commands:\n  alias                Create an alias for a context. Use ALIAS=CONTEXT_NAME\n  clean                Cleans all temporary and cached kubeconfig files\n  completion           Generate the autocompletion script for the specified shell\n  exec                 Execute any command towards the matching contexts from the wildcard search\n  gardener             gardener specific commands\n  help                 Help about any command\n  history              Switch to any previous tuple {context,namespace} from the history\n  hooks                Run configured hooks\n  list-contexts        List all available contexts\n  namespace            Change the current namespace\n  set-context          Switch to context name provided as first argument\n  set-last-context     Switch to the last used context from the history\n  set-previous-context Switch to the previous context from the history\n  version              show switch version info\n\nFlags:\n      --config-path string         path on the local filesystem to the configuration file. (default &quot;/Users/tommyolsen/.kube/switch-config.yaml&quot;)\n      --debug                      show debug logs\n  -h, --help                       help for switch\n      --kubeconfig-name string     only shows kubeconfig files with this name. Accepts wilcard arguments '*' and '?'. Defaults to 'config'. (default &quot;config&quot;)\n      --kubeconfig-path string     path to be recursively searched for kubeconfigs. Can be a file or a directory on the local filesystem or a path in Vault. (default &quot;$HOME/.kube/config&quot;)\n      --no-index                   stores do not read from index files. The index is refreshed.\n      --show-preview               show preview of the selected kubeconfig. Possibly makes sense to disable when using vault as the kubeconfig store to prevent excessive requests against the API. (default true)\n      --state-directory string     path to the local directory used for storing internal state. (default &quot;/Users/tommyolsen/.kube/switch-state&quot;)\n      --store string               the backing store to be searched for kubeconfig files. Can be either &quot;filesystem&quot; or &quot;vault&quot; (default &quot;filesystem&quot;)\n      --vault-api-address string   the API address of the Vault store. Overrides the default &quot;vaultAPIAddress&quot; field in the SwitchConfig. This flag is overridden by the environment variable &quot;VAULT_ADDR&quot;.\n  -v, --version                    version for switch\n\nUse &quot;switch [command] --help&quot; for more information about a command.\"><pre class=\"notranslate\"><code class=\"notranslate\">$ switch -h\nThe kubectx for operators.\n\nUsage:\n  switch [flags]\n  switch [command]\n\nAvailable Commands:\n  alias                Create an alias for a context. Use ALIAS=CONTEXT_NAME\n  clean                Cleans all temporary and cached kubeconfig files\n  completion           Generate the autocompletion script for the specified shell\n  exec                 Execute any command towards the matching contexts from the wildcard search\n  gardener             gardener specific commands\n  help                 Help about any command\n  history              Switch to any previous tuple {context,namespace} from the history\n  hooks                Run configured hooks\n  list-contexts        List all available contexts\n  namespace            Change the current namespace\n  set-context          Switch to context name provided as first argument\n  set-last-context     Switch to the last used context from the history\n  set-previous-context Switch to the previous context from the history\n  version              show switch version info\n\nFlags:\n      --config-path string         path on the local filesystem to the configuration file. (default \"/Users/tommyolsen/.kube/switch-config.yaml\")\n      --debug                      show debug logs\n  -h, --help                       help for switch\n      --kubeconfig-name string     only shows kubeconfig files with this name. Accepts wilcard arguments '*' and '?'. Defaults to 'config'. (default \"config\")\n      --kubeconfig-path string     path to be recursively searched for kubeconfigs. Can be a file or a directory on the local filesystem or a path in Vault. (default \"$HOME/.kube/config\")\n      --no-index                   stores do not read from index files. The index is refreshed.\n      --show-preview               show preview of the selected kubeconfig. Possibly makes sense to disable when using vault as the kubeconfig store to prevent excessive requests against the API. (default true)\n      --state-directory string     path to the local directory used for storing internal state. (default \"/Users/tommyolsen/.kube/switch-state\")\n      --store string               the backing store to be searched for kubeconfig files. Can be either \"filesystem\" or \"vault\" (default \"filesystem\")\n      --vault-api-address string   the API address of the Vault store. Overrides the default \"vaultAPIAddress\" field in the SwitchConfig. This flag is overridden by the environment variable \"VAULT_ADDR\".\n  -v, --version                    version for switch\n\nUse \"switch [command] --help\" for more information about a command.\n</code></pre></div>\n<p dir=\"auto\">Just type <code class=\"notranslate\">switch</code> to search over the context names defined in the default Kubeconfig file <code class=\"notranslate\">~/.kube/config</code><br>\nor from the environment variable <code class=\"notranslate\">KUBECONFIG</code>.</p>\n<p dir=\"auto\">To recursively <strong>search over multiple directories, files and Kubeconfig stores</strong>, please see the <a href=\"docs/kubeconfig_stores.md\">documentation</a><br>\nto set up the necessary configuration file.</p>\n<h2 dir=\"auto\">Change namespace</h2>\n<p dir=\"auto\">Change the current namespace using <code class=\"notranslate\">switch ns</code><br>\nUses a <strong>self-updating</strong> local namespace <strong>cache</strong> for instant search results.</p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"resources/gifs/namespace.gif\"><img src=\"resources/gifs/namespace.gif\" alt=\"\" data-animated-image=\"\" style=\"max-width: 100%;\"></a></p>\n<h2 dir=\"auto\">History</h2>\n<p dir=\"auto\">Similar to the command histories of a shell, <code class=\"notranslate\">switch</code> keeps a history of used contexts and namespaces.<br>\nA history entry is always a tuple of <code class=\"notranslate\">{context-name, namespace}</code>.<br>\nThis allows to jump back to any context and namespace in the history.</p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"resources/gifs/history.gif\"><img src=\"resources/gifs/history.gif\" alt=\"\" data-animated-image=\"\" style=\"max-width: 100%;\"></a></p>\n<p dir=\"auto\">In addition, use</p>\n<ul dir=\"auto\">\n<li><code class=\"notranslate\">switch .</code> to change to the last used context and namespace (handy for new terminals)</li>\n<li><code class=\"notranslate\">switch -</code> to change to the previous history entry</li>\n</ul>\n<h2 dir=\"auto\">List and search for contexts</h2>\n<p dir=\"auto\">You can list all your indexed contexts by issuing the following command: <code class=\"notranslate\">switch list-contexts</code>.<br>\nAnd if you want to search for only parts of those contexts, you can use wildcard search:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"switch list-contexts &quot;*-dev-?&quot;\"><pre class=\"notranslate\">switch list-contexts <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>*-dev-?<span class=\"pl-pds\">\"</span></span></pre></div>\n<p dir=\"auto\">Wildcard search supports <a href=\"https://en.wikipedia.org/wiki/Matching_wildcards\" rel=\"nofollow\">matching wildcards</a> notation also known as globbing:</p>\n<ul dir=\"auto\">\n<li><code class=\"notranslate\">?</code> matches exactly one occurrence of any character.</li>\n<li><code class=\"notranslate\">*</code> matches arbitrary many (including zero) occurrences of any character.</li>\n</ul>\n<h2 dir=\"auto\">Execute commands</h2>\n<p dir=\"auto\">You can use the above wildcard search to execute any commands towards the matching clusters. This makes it powerful for quickly running a command through a given set of clusters and see the output of these commands:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"switch exec &quot;*-dev-?&quot; -- kubectl get ns\"><pre class=\"notranslate\">switch <span class=\"pl-c1\">exec</span> <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>*-dev-?<span class=\"pl-pds\">\"</span></span> -- kubectl get ns</pre></div>\n<p dir=\"auto\">You can also wrap the command(s) into a script and execute it via <code class=\"notranslate\">switch exec</code>:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"switch exec &quot;*-dev-?&quot; -- bash script.sh\"><pre class=\"notranslate\">switch <span class=\"pl-c1\">exec</span> <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>*-dev-?<span class=\"pl-pds\">\"</span></span> -- bash script.sh</pre></div>\n<p dir=\"auto\">For inline shell script execution, you need to specify the default shell in the <code class=\"notranslate\">SwitchConfig</code> file:</p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ~/.kube/switch-config.yaml\nkind: SwitchConfig\nexecShell: &quot;/bin/bash&quot;\"><pre class=\"notranslate\"><span class=\"pl-c\"><span class=\"pl-c\">#</span> ~/.kube/switch-config.yaml</span>\n<span class=\"pl-ent\">kind</span>: <span class=\"pl-s\">SwitchConfig</span>\n<span class=\"pl-ent\">execShell</span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>/bin/bash<span class=\"pl-pds\">\"</span></span></pre></div>\n<p dir=\"auto\">Then you can run shell commands like so:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# executes /bin/bash -c 'for i in 1 2 3; do sleep 1; echo &quot;hi $i&quot;; done'\nswitch exec &quot;*-dev-?&quot; -- 'for i in 1 2 3; do sleep 1; echo &quot;hi $i&quot;; done'\"><pre class=\"notranslate\"><span class=\"pl-c\"><span class=\"pl-c\">#</span> executes /bin/bash -c 'for i in 1 2 3; do sleep 1; echo \"hi $i\"; done'</span>\nswitch <span class=\"pl-c1\">exec</span> <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>*-dev-?<span class=\"pl-pds\">\"</span></span> -- <span class=\"pl-s\"><span class=\"pl-pds\">'</span>for i in 1 2 3; do sleep 1; echo \"hi $i\"; done<span class=\"pl-pds\">'</span></span></pre></div>\n<h2 dir=\"auto\">Kubeconfig stores</h2>\n<p dir=\"auto\">Multiple Kubeconfig stores are supported.<br>\nThe local filesystem is the default store and does not require any additional setup.<br>\nHowever, if you intend to search for all Kubeconfig context/files in the <code class=\"notranslate\">~/.kube</code> directory,<br>\nplease <a href=\"docs/kubeconfig_stores.md#additional-considerations\">first consider this</a>.</p>\n<p dir=\"auto\">To search over multiple directories and setup Kubeconfig stores (such as Vault), <a href=\"docs/kubeconfig_stores.md\">please see here</a>.</p>\n<h2 dir=\"auto\">Kubeconfig cache</h2>\n<p dir=\"auto\">A cache for kubeconfig files can be added to a store to prevent loading from remote on each invocation of <code class=\"notranslate\">kubeswitch</code>.<br>\nThe kubeconfig file will be cached after first download.</p>\n<p dir=\"auto\">To see how to configure the cache, <a href=\"docs/kubeconfig_cache.md\">please see here</a>.</p>\n<h2 dir=\"auto\">Transition from Kubectx</h2>\n<p dir=\"auto\">Offers a smooth transition as <code class=\"notranslate\">kubeswitch</code> is a<br>\ndrop-in replacement for <em>kubectx</em>.<br>\nYou can set an alias and keep using your existing setup.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"  alias kubectx='switch'\n  alias kctx='switch'\"><pre class=\"notranslate\"><code class=\"notranslate\">  alias kubectx='switch'\n  alias kctx='switch'\n</code></pre></div>\n<p dir=\"auto\">However, that does not mean that <code class=\"notranslate\">kubeswitch</code> behaves exactly like <code class=\"notranslate\">kubectx</code>.<br>\nPlease <a href=\"#difference-to-kubectx\">see here</a> to read about some main differences to kubectx.</p>\n<h2 dir=\"auto\">Alias</h2>\n<p dir=\"auto\">An alias for any context name can be defined.<br>\nAn alias <strong>does not modify</strong> or rename the context in the kubeconfig file,<br>\ninstead it is just injected for the search.</p>\n<p dir=\"auto\">Define an alias.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"$ switch alias mediathekview=gke_mediathekviewmobile-real_europe-west1-c_mediathekviewmobile\"><pre class=\"notranslate\"><code class=\"notranslate\">$ switch alias mediathekview=gke_mediathekviewmobile-real_europe-west1-c_mediathekviewmobile\n</code></pre></div>\n<p dir=\"auto\">It is also possible to use <code class=\"notranslate\">switch alias &lt;alias&gt;=.</code> to create an alias for the current context.</p>\n<p dir=\"auto\">See the created alias</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"$ switch alias ls\n+---------------+-------------------------------------------------------------------------------+\n| ALIAS         | CONTEXT                                                                       |\n+---------------+-------------------------------------------------------------------------------+\n| mediathekview | mediathekview/gke_mediathekviewmobile-real_europe-west1-c_mediathekviewmobile |\n+---------------+-------------------------------------------------------------------------------+\n| TOTAL         | 1                                                                             |\n+---------------+-------------------------------------------------------------------------------+ \"><pre class=\"notranslate\"><code class=\"notranslate\">$ switch alias ls\n+---------------+-------------------------------------------------------------------------------+\n| ALIAS         | CONTEXT                                                                       |\n+---------------+-------------------------------------------------------------------------------+\n| mediathekview | mediathekview/gke_mediathekviewmobile-real_europe-west1-c_mediathekviewmobile |\n+---------------+-------------------------------------------------------------------------------+\n| TOTAL         | 1                                                                             |\n+---------------+-------------------------------------------------------------------------------+ \n</code></pre></div>\n<p dir=\"auto\">Remove the alias</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"$ switch alias rm mediathekview\"><pre class=\"notranslate\"><code class=\"notranslate\">$ switch alias rm mediathekview\n</code></pre></div>\n<h3 dir=\"auto\">Caching</h3>\n<p dir=\"auto\">See <a href=\"docs/search_index.md\">here</a> how to use a search index (cache) to speed up search operations.<br>\nUsing the search index is especially useful when</p>\n<ul dir=\"auto\">\n<li>dealing with large amounts of Kubeconfigs and querying the Kubeconfig store is slow (e.g. searching a large directory)</li>\n<li>when using a remote systems (such as Vault) as the Kubeconfig store to increase search speed, reduce latency and save API requests</li>\n</ul>\n<h3 dir=\"auto\">Hot Reload</h3>\n<p dir=\"auto\">For large directories with many Kubeconfig files, the Kubeconfigs are added to the search set on the fly.<br>\nFor smaller directory sizes, the search feels instantaneous.</p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"resources/gifs/hot-reload.gif\"><img src=\"resources/gifs/hot-reload.gif\" alt=\"demo GIF\" data-animated-image=\"\" style=\"max-width: 100%;\"></a></p>\n<h2 dir=\"auto\">Search cryptic context names</h2>\n<p dir=\"auto\">Unfortunately operators sometimes have to deal with cryptic or generated kubeconfig context names that make<br>\nit hard to guess which Kubernetes cluster this kubeconfig context actually points to.<br>\nFor example, these could be temporary CI clusters.</p>\n<p dir=\"auto\">Without having to manually change the Kubeconfig file, <code class=\"notranslate\">kubeswitch</code> makes it easier to identify<br>\nthe right context name by including the <strong>direct parent path</strong> name in the fuzzy search.<br>\nThis way, the directory layout can actually convey information useful for the search.</p>\n<p dir=\"auto\">To exemplify this, look at the path layout below.<br>\nEach Kubernetes landscape (called <code class=\"notranslate\">dev</code>, <code class=\"notranslate\">canary</code> and <code class=\"notranslate\">live</code>) have their own directory containing the Kubeconfigs<br>\nof the Kubernetes clusters on that landscape.<br>\nEvery <code class=\"notranslate\">Kubeconfig</code> is named <code class=\"notranslate\">config</code>.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"$ tree .kube/my-path\n.kube/my-path\n├── canary\n│   └── config\n├── dev\n│   ├── config\n│   └── config-tmp\n└── live\n    └── config\"><pre class=\"notranslate\"><code class=\"notranslate\">$ tree .kube/my-path\n.kube/my-path\n├── canary\n│   └── config\n├── dev\n│   ├── config\n│   └── config-tmp\n└── live\n    └── config\n</code></pre></div>\n<p dir=\"auto\">This is how the search looks like for this directory.<br>\nThe parent directory name is part of the search.</p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"resources/gifs/search-show-parent-folder.png\"><img src=\"resources/gifs/search-show-parent-folder.png\" alt=\"demo GIF\" style=\"max-width: 100%;\"></a></p>\n<p dir=\"auto\">You can either manually create such a path layout and place the kubeconfigs, or write a <a href=\"hooks/README.md\">custom<br>\nhook</a> (script / binary) to do that prior to the search.</p>\n<h3 dir=\"auto\">Extensibilty</h3>\n<p dir=\"auto\">Customization is possible by using <code class=\"notranslate\">Hooks</code> (think Git pre-commit hooks).<br>\nHooks can call an arbitrary executable or execute commands at a certain time (e.g every 6 hours) prior to the search via <code class=\"notranslate\">kubeswitch</code>.<br>\nFor more information <a href=\"./hooks/README.md\">take a look here</a>.</p>\n<h3 dir=\"auto\">Difference to kubectx</h3>\n<p dir=\"auto\"><code class=\"notranslate\">kubectx</code> is great when dealing with few Kubeconfig files - however lacks support when<br>\noperating large Kubernetes installations where clusters spin up on demand,<br>\nhave cryptic context names or are stored in various kubeconfig stores (e.g., Vault).</p>\n<p dir=\"auto\"><code class=\"notranslate\">kubeswitch</code> is build for a world where Kubernetes clusters are <a href=\"https://devops.stackexchange.com/questions/653/what-is-the-definition-of-cattle-not-pets\" rel=\"nofollow\">treated as cattle, not pets</a>.<br>\nThis has implications on how Kubeconfig files are managed.<br>\n<code class=\"notranslate\">kubeswitch</code> is fundamentally designed for the modern Kubernetes operator of large dynamic Kubernetes<br>\ninstallations with possibly thousands of Kubeconfig files in <a href=\"docs/kubeconfig_stores.md\">various locations</a>.</p>\n<p dir=\"auto\">Has build-in</p>\n<ul dir=\"auto\">\n<li>convenience features (terminal window isolation, context history, <a href=\"#alias\">context aliasing</a>, <a href=\"#search-cryptic-context-names\">improved search experience</a>, sanitized Kubeconfig preview);</li>\n<li>advanced search capabilities (search index, hot reload);</li>\n<li>as well as integration points with external systems (<a href=\"hooks/README.md\">hooks</a>).</li>\n</ul>\n<p dir=\"auto\">In addition, <code class=\"notranslate\">kubeswitch</code> is a drop-in replacement for <em>kubectx</em>.<br>\nYou can set an alias and keep using your existing setup.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"  alias kubectx='switch'\n  alias kctx='switch'\"><pre class=\"notranslate\"><code class=\"notranslate\">  alias kubectx='switch'\n  alias kctx='switch'\n</code></pre></div>\n<p dir=\"auto\">However, that does not mean that <code class=\"notranslate\">kubeswitch</code> behaves exactly like <code class=\"notranslate\">kubectx</code>.</p>\n<p dir=\"auto\"><strong>Alias Names</strong></p>\n<p dir=\"auto\"><code class=\"notranslate\">kubectx</code> supports renaming context names using <code class=\"notranslate\">kubectx &lt;NEW_NAME&gt;=&lt;NAME&gt;</code>.<br>\nLikewise, use <code class=\"notranslate\">switch &lt;NEW_NAME&gt;=&lt;NAME&gt;</code> to create an alias.<br>\nAn alias <strong>does not modify</strong> or rename the context in the kubeconfig file.<br>\nIt is just a local configuration that can be removed again via <code class=\"notranslate\">switch alias rm &lt;NAME&gt;</code>.<br>\nDirectly modifying the Kubeconfig is problematic:</p>\n<ul dir=\"auto\">\n<li>Common tooling might be used across the team which needs to rely on predictable cluster naming conventions</li>\n<li>Modifying the file is not always possible e.g., when the Kubeconfig is actually stored in a Vault</li>\n<li>No easy way to revert the alias or see aliases that are currently in use</li>\n</ul>\n<p dir=\"auto\"><strong>Terminal Window isolation</strong></p>\n<p dir=\"auto\"><code class=\"notranslate\">kubectx</code> directly modifies the kubeconfig file to set the current context.<br>\nThis has the disadvantage that every other terminal using the same<br>\nKubeconfig file (e.g, via environment variable <em>KUBECONFIG</em>) will also be affected and change the context.</p>\n<p dir=\"auto\">A guideline of <code class=\"notranslate\">kubeswitch</code> is to not modify the underlying Kubeconfig file.<br>\nHence, a temporary copy of the original Kubeconfig file is created and used to modify the context.<br>\nThis way, each terminal window works on its own copy of the Kubeconfig file and cannot interfere with each other.</p>\n<h3 dir=\"auto\">Limitations</h3>\n<p dir=\"auto\">Please make sure there are no kubeconfig files that have the same context name within one directory.<br>\nDefine multiple search paths using the <a href=\"docs/kubeconfig_stores.md\">configuration file</a>.</p>\n<h3 dir=\"auto\">Future Plans</h3>\n<ul dir=\"auto\">\n<li>Support more Cloud Providers and Managed Kubernetes Platforms</li>\n</ul>","updatedAt":"2025-05-21T16:09:12Z","upvoteCount":null,"author":{"login":"eryajf","avatarUrl":"https://avatars.githubusercontent.com/u/33259379?u=e4a4090a38ac2473aaed4ef9945233636776c6c3&v=4","url":"https://github.com/eryajf"},"category":null,"labels":{"edges":[{"node":{"name":"更多","color":"25B472"}},{"node":{"name":"K8S-Tools","color":"2d411a"}},{"node":{"name":"danielfoehrKn","color":"805716"}}]},"comments":{"edges":[]}}},"pageContext":{"number":335,"previous":{"title":"kubernetes/kube-state-metrics: k8s官方推出的用于监控k8s集群状态的指标收集器，提供了大量的k8s集群状态指标，如节点状态、pod状态、deployment状态等","number":334},"next":{"title":"kubetail-org/kubetail: 一个通用的 Kubernetes 日志仪表板，可以暴漏在浏览器当中查看。","number":336}}},
    "staticQueryHashes": ["151096407","2861350382"]}