[{"data":1,"prerenderedAt":415},["ShallowReactive",2],{"site-data":3,"article-list-25-1":143,"article-hot-25":315,"article-rec-25":404},{"settings":4,"categorys":35,"tree":97,"models":118,"search_model_select":128,"nav_list":130},{"changefreq":5,"changyan_app_id":6,"changyan_app_key":6,"copy":7,"description":8,"editor":9,"file":6,"guest_feedback":10,"head_html":6,"icp":11,"index_banner":12,"index_banner_bg":13,"is_excel":14,"is_watermark":10,"keywords":15,"links":16,"logo":17,"lzcms_banner":6,"lzcms_banner_link":18,"qq_app_id":6,"qq_app_key":6,"qr_code":6,"search_model":19,"site_closedreason":6,"site_idea":6,"site_idea1":20,"site_idea2":21,"site_idea3":22,"site_name":23,"site_statistice":6,"site_status":14,"site_url":18,"sitemap_model":19,"stationmaster_motto":24,"stationmaster_name":25,"stationmaster_occupation":26,"stationmaster_qq":27,"stationmaster_qqnet":28,"stationmaster_qqnet_code":29,"threshold":14,"title_add":30,"watermark":6,"watermark_alpha":31,"watermark_height":32,"watermark_locate":33,"watermark_width":34},"weekly","","版权所有 © \u003Ca class=\"site_url\" href=\"https://zhl123.com\">2026 zhl123.com\u003C/a>","linux、Python、mysql、docker、k8s技术交流","layedit","0","粤ICP备15054664号-1","/uploads/images/20181109/7a86191de8b8bb60e9c6b54d8b27c5cc.jpg","#xe604","1","linux、Python、mysql、docker、k8s","{\"1\":{\"id\":\"1\",\"name\":\"linux\\u4e2d\\u56fd\",\"link_url\":\"http:\\/\\/linux.cn\",\"sort\":\"1\"}}","/uploads/images/20181109/e7305012448aed257176dd591846f50a.png","https://zhl123.com","2","学无止境\n学习，探索，研究，从不了解到了解，从无知到掌握，到灵活运用，在不断的学习中加深认识。由浅入深，由表及里。","业精于勤\n“业精于勤荒于嬉”，精深的业技靠的是勤学、刻苦努力，靠的是争分夺秒的勤学苦练才会有精深的技术。得在认真，失在随便。","工匠精神\n精益求精，注重细节，追求完美和极致，不惜花费时间精力，孜孜不倦，反复改进产品，把99%提高到99.99%。","linux","业精于勤、学无止境、工匠精神","廖地金","高级Linux运维工程师","1256636645","592958303","\u003Ca target=\"_blank\" href=\"//shang.qq.com/wpa/qunwpa?idkey=09be7d1a682073783fd636102e666393169b8a8aac8f3393da1de57bcaa821a0\">\u003Cimg border=\"0\" src=\"//pub.idqqimg.com/wpa/images/group.png\" alt=\"Linux技术\" title=\"Linux技术\">\u003C/a>"," | Python | mysql | docker | k8s 技术交流","100","300","9","500",{"0":36,"17":51,"18":60,"19":63,"20":67,"21":71,"22":76,"25":80,"26":83,"27":89,"29":94},{"children":37},{"0":38,"25":43,"26":48},[39,40,41,42],25,21,22,26,[44,45,46,47],17,18,19,20,[49,50],27,29,{"create_time":6,"description":6,"id":44,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":23,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":53,"subtitle":6,"update_time":6,"url":59},"index",1,"list","article",2,"文章模型","show","/article/lists?category_id=17",{"create_time":6,"description":6,"id":45,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":61,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":56,"subtitle":6,"update_time":6,"url":62},"python","/article/lists?category_id=18",{"create_time":6,"description":6,"id":46,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":64,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":65,"subtitle":6,"update_time":6,"url":66},"容器技术",3,"/article/lists?category_id=19",{"create_time":6,"description":6,"id":47,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":68,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":69,"subtitle":6,"update_time":6,"url":70},"负载均衡",4,"/article/lists?category_id=20",{"create_time":6,"description":6,"id":40,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":72,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":74,"subtitle":6,"update_time":6,"url":75},"分享无价",0,5,"/article/lists?category_id=21",{"create_time":6,"description":6,"id":41,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":77,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":78,"subtitle":6,"update_time":6,"url":79},"随笔",6,"/article/lists?category_id=22",{"create_time":6,"description":6,"id":39,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":81,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":73,"subtitle":6,"update_time":6,"url":82},"学无止境","/article/lists?category_id=25",{"create_time":6,"description":6,"id":42,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":84,"model_id":65,"model_name":85,"name":86,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":87,"subtitle":6,"update_time":6,"url":88},"picture","图集模型","关于",8,"/picture/lists?category_id=26",{"create_time":6,"description":6,"id":49,"image_url":6,"index_template":52,"is_cover":53,"is_menu":73,"keywords":6,"list_template":54,"model_code":90,"model_id":53,"model_name":91,"name":92,"parent_id":42,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":47,"subtitle":6,"update_time":6,"url":93},"page","单页模型","关于博主","/page/27",{"create_time":6,"description":6,"id":50,"image_url":6,"index_template":52,"is_cover":73,"is_menu":73,"keywords":6,"list_template":54,"model_id":73,"name":95,"parent_id":42,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":47,"subtitle":6,"update_time":6,"url":96},"留言","/feedback",[98,108,110,112],{"children":99,"create_time":6,"description":6,"id":39,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":81,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":73,"subtitle":6,"update_time":6,"url":82},[100,102,104,106],{"children":101,"create_time":6,"description":6,"id":44,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":23,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":53,"subtitle":6,"update_time":6,"url":59},[],{"children":103,"create_time":6,"description":6,"id":45,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":61,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":56,"subtitle":6,"update_time":6,"url":62},[],{"children":105,"create_time":6,"description":6,"id":46,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":64,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":65,"subtitle":6,"update_time":6,"url":66},[],{"children":107,"create_time":6,"description":6,"id":47,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":68,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":69,"subtitle":6,"update_time":6,"url":70},[],{"children":109,"create_time":6,"description":6,"id":40,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":72,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":74,"subtitle":6,"update_time":6,"url":75},[],{"children":111,"create_time":6,"description":6,"id":41,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":77,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":78,"subtitle":6,"update_time":6,"url":79},[],{"children":113,"create_time":6,"description":6,"id":42,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":84,"model_id":65,"model_name":85,"name":86,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":87,"subtitle":6,"update_time":6,"url":88},[114,116],{"children":115,"create_time":6,"description":6,"id":49,"image_url":6,"index_template":52,"is_cover":53,"is_menu":73,"keywords":6,"list_template":54,"model_code":90,"model_id":53,"model_name":91,"name":92,"parent_id":42,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":47,"subtitle":6,"update_time":6,"url":93},[],{"children":117,"create_time":6,"description":6,"id":50,"image_url":6,"index_template":52,"is_cover":73,"is_menu":73,"keywords":6,"list_template":54,"model_id":73,"name":95,"parent_id":42,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":47,"subtitle":6,"update_time":6,"url":96},[],{"1":119,"2":120,"3":121,"4":122,"5":125},{"id":53,"index_template":52,"list_template":54,"name":91,"show_template":58,"status":73,"tablename":90},{"id":56,"index_template":52,"list_template":54,"name":57,"show_template":58,"status":73,"tablename":55},{"id":65,"index_template":52,"list_template":54,"name":85,"show_template":58,"status":73,"tablename":84},{"id":69,"index_template":52,"list_template":54,"name":123,"show_template":58,"status":73,"tablename":124},"链接模型","link",{"id":74,"index_template":52,"list_template":54,"name":126,"show_template":58,"status":73,"tablename":127},"下载模型","download",[129],{"id":56,"name":57,"tablename":55},[131,137,139,141],{"children":132,"create_time":6,"description":6,"id":39,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":81,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":73,"subtitle":6,"update_time":6,"url":82},[133,134,135,136],{"create_time":6,"description":6,"id":44,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":23,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":53,"subtitle":6,"update_time":6,"url":59},{"create_time":6,"description":6,"id":45,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":61,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":56,"subtitle":6,"update_time":6,"url":62},{"create_time":6,"description":6,"id":46,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":64,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":65,"subtitle":6,"update_time":6,"url":66},{"create_time":6,"description":6,"id":47,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":68,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":69,"subtitle":6,"update_time":6,"url":70},{"children":138,"create_time":6,"description":6,"id":40,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":72,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":74,"subtitle":6,"update_time":6,"url":75},[],{"children":140,"create_time":6,"description":6,"id":41,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":77,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":78,"subtitle":6,"update_time":6,"url":79},[],{"children":142,"create_time":6,"description":6,"id":42,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":84,"model_id":65,"model_name":85,"name":86,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":87,"subtitle":6,"update_time":6,"url":88},[],{"breadcrumb":144,"category":146,"list":147,"second_categorys":309,"seo":314},[145],{"id":39,"name":81,"url":82},{"create_time":6,"description":6,"id":39,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":81,"parent_id":73,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":73,"subtitle":6,"update_time":6,"url":82},{"data":148,"total":306,"per_page":307,"current_page":53,"last_page":308},[149,159,169,179,189,199,209,220,231,242,253,264,275,286,296],{"id":150,"category_id":44,"title":151,"keywords":6,"description":152,"image_url":6,"content":153,"content_md":154,"url":155,"hits":156,"is_recommend":73,"is_top":73,"create_time":157,"update_time":158},122,"Nginx性能调优18条黄金法则：支撑10万并发的配置模板","一、概述1.1 背景介绍说实话，Nginx调优这事儿我踩过无数坑。记得2019年双11，我们电商平台流量暴涨，Nginx直接扛不住了，QPS从平时的2万飙升到8万，响应时间从50ms飙到了2秒，最后还是靠临时加机器扛过去的。那次事故之后，我花了大半年时间专门研究Nginx的性能极限，总结出了这20条黄金法则。Nginx作为目前最流行的Web服务器和反向代理，官方数据显示单机可以轻松处理10万+的并发连接。但实际生产环境中，很多同学拿到默认配置就直接上了，结果发现连1万并发都扛不住。问题不在Ngi","\u003Ch1 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__1\">\u003Cspan leaf=\"\">一、概述\u003C/span>\u003C/span>\u003C/h1>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__2\">\u003Cspan leaf=\"\">1.1 背景介绍\u003C/span>\u003C/span>\u003C/h3>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__3\">\u003Cspan leaf=\"\">说实话，Nginx调优这事儿我踩过无数坑。记得2019年双11，我们电商平台流量暴涨，Nginx直接扛不住了，QPS从平时的2万飙升到8万，响应时间从50ms飙到了2秒，最后还是靠临时加机器扛过去的。那次事故之后，我花了大半年时间专门研究Nginx的性能极限，总结出了这20条黄金法则。\u003C/span>\u003C/p>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__4\">\u003Cspan leaf=\"\">Nginx作为目前最流行的Web服务器和反向代理，官方数据显示单机可以轻松处理10万+的并发连接。但实际生产环境中，很多同学拿到默认配置就直接上了，结果发现连1万并发都扛不住。问题不在Nginx本身，而在于配置。\u003C/span>\u003C/p>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__5\">\u003Cspan leaf=\"\">1.2 技术特点\u003C/span>\u003C/span>\u003C/h3>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__6\">\u003Cspan leaf=\"\">Nginx采用事件驱动的异步非阻塞架构，这跟传统的Apache每个连接一个进程/线程的模式完全不同。打个比方：Apache像是银行柜台，每个客户都需要一个柜员全程服务；Nginx则像是叫号系统，一个柜员可以同时处理多个客户的不同阶段任务。\u003C/span>\u003C/p>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__7\">\u003Cspan leaf=\"\">核心优势：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__8\">\u003Cli>\u003Csection class=\"js_darkmode__9\">\u003Cspan leaf=\"\">内存占用低：处理10000个非活跃HTTP keep-alive连接仅需2.5MB内存\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__10\">\u003Cspan leaf=\"\">事件驱动：基于epoll/kqueue，不会因为连接数增加而线性增长CPU消耗\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__11\">\u003Cspan leaf=\"\">模块化设计：只加载需要的模块，减少资源浪费\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__12\">\u003Cspan leaf=\"\">热部署：配置修改无需重启，平滑reload\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__13\">\u003Cspan leaf=\"\">1.3 适用场景\u003C/span>\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__14\">\u003Cli>\u003Csection class=\"js_darkmode__15\">\u003Cspan leaf=\"\">高并发静态资源服务（图片、CSS、JS、视频）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__16\">\u003Cspan leaf=\"\">反向代理和负载均衡\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__17\">\u003Cspan leaf=\"\">API网关\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__18\">\u003Cspan leaf=\"\">SSL/TLS终结点\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__19\">\u003Cspan leaf=\"\">缓存服务器\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__20\">\u003Cspan leaf=\"\">WebSocket代理\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__21\">\u003Cspan leaf=\"\">1.4 环境要求\u003C/span>\u003C/span>\u003C/h3>\u003Csection data-tool=\"mdnice编辑器\">\u003Ctable class=\"layui-table\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__22\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">组件\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__23\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">版本\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__24\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">说明\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr class=\"js_darkmode__25\">\u003Ctd class=\"js_darkmode__26\">\u003Csection>\u003Cspan leaf=\"\">操作系统\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__27\">\u003Csection>\u003Cspan leaf=\"\">Rocky Linux 9.4 / Ubuntu 24.04 LTS\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__28\">\u003Csection>\u003Cspan leaf=\"\">内核版本建议5.15+\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__29\">\u003Ctd class=\"js_darkmode__30\">\u003Csection>\u003Cspan leaf=\"\">Nginx\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__31\">\u003Csection>\u003Cspan leaf=\"\">1.26.2 / 1.27.0\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__32\">\u003Csection>\u003Cspan leaf=\"\">mainline版本功能更新，stable版本更稳定\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__33\">\u003Ctd class=\"js_darkmode__34\">\u003Csection>\u003Cspan leaf=\"\">CPU\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__35\">\u003Csection>\u003Cspan leaf=\"\">8核+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__36\">\u003Csection>\u003Cspan leaf=\"\">Nginx worker数量与CPU核心数相关\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__37\">\u003Ctd class=\"js_darkmode__38\">\u003Csection>\u003Cspan leaf=\"\">内存\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__39\">\u003Csection>\u003Cspan leaf=\"\">16GB+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__40\">\u003Csection>\u003Cspan leaf=\"\">主要用于连接缓冲和缓存\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__41\">\u003Ctd class=\"js_darkmode__42\">\u003Csection>\u003Cspan leaf=\"\">网络\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__43\">\u003Csection>\u003Cspan leaf=\"\">万兆网卡\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__44\">\u003Csection>\u003Cspan leaf=\"\">千兆网卡在高并发下会成为瓶颈\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__45\">\u003Ctd class=\"js_darkmode__46\">\u003Csection>\u003Cspan leaf=\"\">磁盘\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__47\">\u003Csection>\u003Cspan leaf=\"\">NVMe SSD\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__48\">\u003Csection>\u003Cspan leaf=\"\">日志写入和缓存需要高IOPS\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/section>\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__49\">\u003Cspan leaf=\"\">二、详细步骤\u003C/span>\u003C/span>\u003C/h2>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__50\">\u003Cspan leaf=\"\">2.1 准备工作\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__51\">\u003Cspan leaf=\"\">2.1.1 系统内核参数调优\u003C/span>\u003C/span>\u003C/h4>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__52\">\u003Cspan leaf=\"\">在动Nginx配置之前，得先把操作系统底子打好。很多人忽略了这一步，结果Nginx配得再好也白搭。\u003C/span>\u003C/p>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__53\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__0 js_darkmode__54\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__55\">\u003Cspan class=\"js_darkmode__56\"># /etc/sysctl.conf 追加以下内容\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan class=\"js_darkmode__57\"># 文件描述符限制\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">fs.file-max = 2097152\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">fs.nr_open = 2097152\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan class=\"js_darkmode__58\"># TCP连接相关\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.core.somaxconn = 65535\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.core.netdev_max_backlog = 65535\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_max_syn_backlog = 65535\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan class=\"js_darkmode__59\"># TIME_WAIT优化（这个参数救过我无数次）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_tw_reuse = 1\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_fin_timeout = 15\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_max_tw_buckets = 262144\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan class=\"js_darkmode__60\"># TCP keepalive\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_keepalive_time = 600\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_keepalive_intvl = 30\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_keepalive_probes = 3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan class=\"js_darkmode__61\"># 网络缓冲区\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.core.rmem_max = 16777216\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.core.wmem_max = 16777216\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_rmem = 4096 87380 16777216\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.tcp_wmem = 4096 65536 16777216\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan class=\"js_darkmode__62\"># 本地端口范围\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">net.ipv4.ip_local_port_range = 1024 65535\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__63\">\u003Cspan leaf=\"\">应用配置：\u003C/span>\u003C/p>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__64\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__1 js_darkmode__65\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__66\">\u003Cspan leaf=\"\">sysctl -p\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__67\">\u003Cspan leaf=\"\">2.1.2 文件描述符限制\u003C/span>\u003C/span>\u003C/h4>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__68\">\u003Cspan leaf=\"\">这是个老生常谈的问题了，但每次接手新项目还是会遇到。Nginx报\"Too many open files\"错误，十有八九就是这个没配好。\u003C/span>\u003C/p>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__69\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__2 js_darkmode__70\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__71\">\u003Cspan class=\"js_darkmode__72\"># /etc/security/limits.conf\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">* soft nofile 1048576\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">* hard nofile 1048576\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">nginx soft nofile 1048576\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">nginx hard nofile 1048576\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan class=\"js_darkmode__73\"># /etc/systemd/system/nginx.service.d/override.conf\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">[Service]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">LimitNOFILE=1048576\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__74\">\u003Cspan leaf=\"\">2.2 核心配置\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__75\">\u003Cspan leaf=\"\">法则1：worker进程数量配置\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__76\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__3 js_darkmode__77\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__78\">\u003Cspan leaf=\"\"># 自动检测CPU核心数，省心省力\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">worker_processes auto;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 或者手动指定，建议等于CPU核心数\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># worker_processes 8;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># CPU亲和性绑定，减少CPU缓存失效\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">worker_cpu_affinity auto;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__79\">\u003Cstrong class=\"js_darkmode__80\">踩坑记录\u003C/strong>\u003Cspan leaf=\"\">：早期我喜欢把worker_processes设成CPU核心数的2倍，觉得这样能处理更多请求。结果发现这是典型的过度优化，多出来的worker进程反而增加了上下文切换开销，QPS不升反降。\u003C/span>\u003C/p>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__81\">\u003Cspan leaf=\"\">法则2：worker连接数配置\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__82\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__4 js_darkmode__83\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__84\">\u003Cspan leaf=\"\">events {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 每个worker的最大连接数\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 理论最大并发 = worker_processes * worker_connections\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; worker_connections 65535;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 使用epoll事件模型（Linux 2.6+必选）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; use epoll;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 允许一个worker进程同时接受多个新连接\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; multi_accept on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 互斥锁，高并发场景建议关闭\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; accept_mutex off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__85\">\u003Cspan leaf=\"\">法则3：文件描述符缓存\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__86\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__5 js_darkmode__87\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__88\">\u003Cspan leaf=\"\"># main context\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">worker_rlimit_nofile 1048576;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__89\">\u003Cspan leaf=\"\">法则4：sendfile零拷贝\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__90\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__6 js_darkmode__91\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__92\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 开启sendfile，避免用户态和内核态之间的数据拷贝\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; sendfile on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 配合sendfile使用，减少网络报文段数量\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; tcp_nopush on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 禁用Nagle算法，减少延迟\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; tcp_nodelay on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__93\">\u003Cstrong class=\"js_darkmode__94\">原理解释\u003C/strong>\u003Cspan leaf=\"\">：传统文件发送需要经历\"磁盘-&gt;内核缓冲区-&gt;用户缓冲区-&gt;socket缓冲区\"四次拷贝。sendfile直接在内核态完成\"磁盘-&gt;socket缓冲区\"的数据传输，理论上可以提升30%-40%的吞吐量。\u003C/span>\u003C/p>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__95\">\u003Cspan leaf=\"\">法则5：超时配置\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__96\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__7 js_darkmode__97\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__98\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 客户端请求头超时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; client_header_timeout 15s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 客户端请求体超时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; client_body_timeout 15s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 响应超时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; send_timeout 15s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # keepalive超时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; keepalive_timeout 65s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # keepalive请求数量限制\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; keepalive_requests 10000;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__99\">\u003Cstrong class=\"js_darkmode__100\">踩坑记录\u003C/strong>\u003Cspan leaf=\"\">：曾经有个项目，上传大文件总是失败。排查半天发现是client_body_timeout设成了10秒，但大文件上传需要更长时间。生产环境这个值建议根据实际业务调整，不要一刀切。\u003C/span>\u003C/p>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__101\">\u003Cspan leaf=\"\">法则6：缓冲区配置\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__102\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__8 js_darkmode__103\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__104\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 客户端请求体缓冲区\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; client_body_buffer_size 128k;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; client_max_body_size 100m;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 请求头缓冲区\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; client_header_buffer_size 4k;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; large_client_header_buffers 4 32k;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 代理缓冲区\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_buffer_size 64k;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_buffers 8 128k;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_busy_buffers_size 256k;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__105\">\u003Cspan leaf=\"\">法则7：Gzip压缩\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__106\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__9 js_darkmode__107\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__108\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gzip on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gzip_vary on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gzip_proxied any;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 压缩级别1-9，建议4-6，太高CPU消耗大\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gzip_comp_level 5;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 最小压缩长度，太小的文件压缩反而浪费CPU\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gzip_min_length 1024;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 压缩类型\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gzip_types\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; text/plain\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; text/css\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; text/javascript\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; application/javascript\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; application/json\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; application/xml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; application/xml+rss\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; image/svg+xml;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 预压缩文件支持\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gzip_static on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__109\">\u003Cstrong class=\"js_darkmode__110\">性能对比\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Csection data-tool=\"mdnice编辑器\">\u003Ctable class=\"layui-table\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__111\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">压缩级别\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__112\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">压缩率\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__113\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">CPU消耗\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__114\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">适用场景\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr class=\"js_darkmode__115\">\u003Ctd class=\"js_darkmode__116\">\u003Csection>\u003Cspan leaf=\"\">1\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__117\">\u003Csection>\u003Cspan leaf=\"\">低\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__118\">\u003Csection>\u003Cspan leaf=\"\">最低\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__119\">\u003Csection>\u003Cspan leaf=\"\">CPU受限环境\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__120\">\u003Ctd class=\"js_darkmode__121\">\u003Csection>\u003Cspan leaf=\"\">4-5\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__122\">\u003Csection>\u003Cspan leaf=\"\">中\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__123\">\u003Csection>\u003Cspan leaf=\"\">中等\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__124\">\u003Csection>\u003Cspan leaf=\"\">通用场景（推荐）\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__125\">\u003Ctd class=\"js_darkmode__126\">\u003Csection>\u003Cspan leaf=\"\">9\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__127\">\u003Csection>\u003Cspan leaf=\"\">高\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__128\">\u003Csection>\u003Cspan leaf=\"\">最高\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__129\">\u003Csection>\u003Cspan leaf=\"\">带宽极其昂贵\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/section>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__130\">\u003Cspan leaf=\"\">法则8：静态文件缓存\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__131\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__10 js_darkmode__132\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__133\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 打开文件缓存\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; open_file_cache max=100000 inactive=60s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; open_file_cache_valid 60s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; open_file_cache_min_uses 2;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; open_file_cache_errors on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">server {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; location ~* \\.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; expires 30d;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; add_header Cache-Control \"public, immutable\";\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; access_log off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; }\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__134\">\u003Cspan leaf=\"\">法则9：日志优化\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__135\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__11 js_darkmode__136\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__137\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 使用缓冲写入，减少磁盘IO\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; access_log /var/log/nginx/access.log main buffer=64k flush=5s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 或者对于高并发场景，考虑关闭access log\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # access_log off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 错误日志级别\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; error_log /var/log/nginx/error.log warn;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__138\">\u003Cstrong class=\"js_darkmode__139\">血泪教训\u003C/strong>\u003Cspan leaf=\"\">：生产环境日志不要开debug级别！我曾经为了排查问题临时开了debug，结果磁盘一会儿就满了，服务直接挂掉。\u003C/span>\u003C/p>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__140\">\u003Cspan leaf=\"\">法则10：SSL/TLS优化\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__141\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__12 js_darkmode__142\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__143\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # SSL会话缓存\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_session_cache shared:SSL:50m;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_session_timeout 1d;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_session_tickets on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # SSL协议版本\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_protocols TLSv1.2 TLSv1.3;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 优先使用服务器端加密套件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_prefer_server_ciphers off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # TLS 1.3加密套件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # OCSP Stapling\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_stapling on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ssl_stapling_verify on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; resolver 8.8.8.8 8.8.4.4 valid=300s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__144\">\u003Cspan leaf=\"\">法则11：HTTP/2配置\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__145\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__13 js_darkmode__146\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__147\">\u003Cspan leaf=\"\">server {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; listen 443 ssl;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; http2 on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # HTTP/2推送（Nginx 1.25.1+）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 注意：主流浏览器已逐步废弃Server Push\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__148\">\u003Cspan leaf=\"\">法则12：连接复用优化\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__149\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__14 js_darkmode__150\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__151\">\u003Cspan leaf=\"\">upstream backend {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server 10.0.0.1:8080;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server 10.0.0.2:8080;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 与后端保持的连接数\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; keepalive 300;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 单个连接最大请求数\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; keepalive_requests 10000;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 连接超时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; keepalive_timeout 60s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">server {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; location /api/ {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass http://backend;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; # 必须使用HTTP/1.1才能使用keepalive\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_http_version 1.1;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header Connection \"\";\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; }\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__152\">\u003Cstrong class=\"js_darkmode__153\">这条救命配置\u003C/strong>\u003Cspan leaf=\"\">：很多人配了upstream的keepalive但不生效，99%是因为没加\u003C/span>\u003Ccode class=\"js_darkmode__154\">\u003Cspan leaf=\"\">proxy_set_header Connection \"\"\u003C/span>\u003C/code>\u003Cspan leaf=\"\">。默认情况下Nginx会把Connection头设成close，导致每次请求都新建连接。\u003C/span>\u003C/p>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__155\">\u003Cspan leaf=\"\">法则13：负载均衡算法选择\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__156\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__15 js_darkmode__157\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__158\">\u003Cspan leaf=\"\">upstream backend {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 最少连接数算法，推荐\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; least_conn;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 或者IP哈希（需要会话保持时使用）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # ip_hash;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 或者一致性哈希\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # hash $request_uri consistent;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server 10.0.0.1:8080 weight=3;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server 10.0.0.2:8080 weight=2;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server 10.0.0.3:8080 weight=1 backup;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__159\">\u003Cspan leaf=\"\">法则14：健康检查\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__160\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__16 js_darkmode__161\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__162\">\u003Cspan leaf=\"\">upstream backend {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__163\">\u003Cspan leaf=\"\">开源版Nginx的健康检查比较弱，只能被动检测。如果需要主动健康检查，建议：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__164\">\u003Cli>\u003Csection class=\"js_darkmode__165\">\u003Cspan leaf=\"\">使用Nginx Plus（商业版）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__166\">\u003Cspan leaf=\"\">使用第三方模块nginx_upstream_check_module\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__167\">\u003Cspan leaf=\"\">使用OpenResty\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__168\">\u003Cspan leaf=\"\">法则15：请求限流\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__169\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__17 js_darkmode__170\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__171\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 定义限流区域\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; limit_conn_zone $binary_remote_addr zone=conn_limit:10m;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">server {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; location /api/ {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; # 请求速率限制\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; limit_req zone=api_limit burst=200 nodelay;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; # 并发连接限制\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; limit_conn conn_limit 50;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; # 限流返回码\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; limit_req_status 429;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; limit_conn_status 429;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; }\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__172\">\u003Cspan leaf=\"\">法则16：proxy优化\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__173\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__18 js_darkmode__174\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__175\">\u003Cspan leaf=\"\">location /api/ {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_pass http://backend;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 连接超时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_connect_timeout 5s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_send_timeout 60s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_read_timeout 60s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 失败重试\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_next_upstream error timeout http_502 http_503;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_next_upstream_tries 3;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_next_upstream_timeout 10s;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 请求头传递\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_set_header Host $host;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_set_header X-Real-IP $remote_addr;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_set_header X-Forwarded-Proto $scheme;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__176\">\u003Cspan leaf=\"\">法则17：缓存配置\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__177\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__19 js_darkmode__178\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__179\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 定义缓存路径\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; proxy_cache_path /var/cache/nginx levels=1:2\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; keys_zone=api_cache:100m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; max_size=10g\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; inactive=60m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; use_temp_path=off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">server {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; location /api/public/ {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass http://backend;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache api_cache;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache_valid 200 10m;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache_valid 404 1m;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache_use_stale error timeout updating;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_cache_lock on;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; add_header X-Cache-Status $upstream_cache_status;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; }\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__180\">\u003Cspan leaf=\"\">法则18：安全加固\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__181\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEpeUhObicFUoIgKXw8XWhGkQeLA9oicBia3S3ZQ1g7RJVRSenCN4eaibW2NjdOeU8RXhs6Tic8eSNEMxt/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__20 js_darkmode__182\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__183\">\u003Cspan leaf=\"\">http {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 隐藏版本号\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; server_tokens off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 安全响应头\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; add_header X-Frame-Options \"SAMEORIGIN\" always;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; add_header X-Content-Type-Options \"nosniff\" always;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; add_header X-XSS-Protection \"1; mode=block\" always;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">server {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 禁止访问隐藏文件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; location ~ /\\. {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; deny all;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; access_log off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; log_not_found off;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; }\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003C/code>\u003C/pre>","# 一、概述\n\n### 1.1 背景介绍\n\n说实话，Nginx调优这事儿我踩过无数坑。记得2019年双11，我们电商平台流量暴涨，Nginx直接扛不住了，QPS从平时的2万飙升到8万，响应时间从50ms飙到了2秒，最后还是靠临时加机器扛过去的。那次事故之后，我花了大半年时间专门研究Nginx的性能极限，总结出了这20条黄金法则。\n\nNginx作为目前最流行的Web服务器和反向代理，官方数据显示单机可以轻松处理10万+的并发连接。但实际生产环境中，很多同学拿到默认配置就直接上了，结果发现连1万并发都扛不住。问题不在Nginx本身，而在于配置。\n\n### 1.2 技术特点\n\nNginx采用事件驱动的异步非阻塞架构，这跟传统的Apache每个连接一个进程/线程的模式完全不同。打个比方：Apache像是银行柜台，每个客户都需要一个柜员全程服务；Nginx则像是叫号系统，一个柜员可以同时处理多个客户的不同阶段任务。\n\n核心优势：\n\n- 内存占用低：处理10000个非活跃HTTP keep-alive连接仅需2.5MB内存\n- 事件驱动：基于epoll/kqueue，不会因为连接数增加而线性增长CPU消耗\n- 模块化设计：只加载需要的模块，减少资源浪费\n- 热部署：配置修改无需重启，平滑reload\n\n### 1.3 适用场景\n\n- 高并发静态资源服务（图片、CSS、JS、视频）\n- 反向代理和负载均衡\n- API网关\n- SSL/TLS终结点\n- 缓存服务器\n- WebSocket代理\n\n### 1.4 环境要求\n\n组件\n\n版本\n\n说明\n\n操作系统\n\nRocky Linux 9.4 / Ubuntu 24.04 LTS\n\n内核版本建议5.15+\n\nNginx\n\n1.26.2 / 1.27.0\n\nmainline版本功能更新，stable版本更稳定\n\nCPU\n\n8核+\n\nNginx worker数量与CPU核心数相关\n\n内存\n\n16GB+\n\n主要用于连接缓冲和缓存\n\n网络\n\n万兆网卡\n\n千兆网卡在高并发下会成为瓶颈\n\n磁盘\n\nNVMe SSD\n\n日志写入和缓存需要高IOPS\n\n## 二、详细步骤\n\n### 2.1 准备工作\n\n#### 2.1.1 系统内核参数调优\n\n在动Nginx配置之前，得先把操作系统底子打好。很多人忽略了这一步，结果Nginx配得再好也白搭。\n\n```\n# /etc/sysctl.conf 追加以下内容# 文件描述符限制fs.file-max = 2097152fs.nr_open = 2097152# TCP连接相关net.core.somaxconn = 65535net.core.netdev_max_backlog = 65535net.ipv4.tcp_max_syn_backlog = 65535# TIME_WAIT优化（这个参数救过我无数次）net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_fin_timeout = 15net.ipv4.tcp_max_tw_buckets = 262144# TCP keepalivenet.ipv4.tcp_keepalive_time = 600net.ipv4.tcp_keepalive_intvl = 30net.ipv4.tcp_keepalive_probes = 3# 网络缓冲区net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.ipv4.tcp_rmem = 4096 87380 16777216net.ipv4.tcp_wmem = 4096 65536 16777216# 本地端口范围net.ipv4.ip_local_port_range = 1024 65535\n```\n\n应用配置：\n\n```\nsysctl -p\n```\n\n#### 2.1.2 文件描述符限制\n\n这是个老生常谈的问题了，但每次接手新项目还是会遇到。Nginx报\"Too many open files\"错误，十有八九就是这个没配好。\n\n```\n# /etc/security/limits.conf* soft nofile 1048576* hard nofile 1048576nginx soft nofile 1048576nginx hard nofile 1048576# /etc/systemd/system/nginx.service.d/override.conf[Service]LimitNOFILE=1048576\n```\n\n### 2.2 核心配置\n\n#### 法则1：worker进程数量配置\n\n```\n# 自动检测CPU核心数，省心省力worker_processes auto;# 或者手动指定，建议等于CPU核心数# worker_processes 8;# CPU亲和性绑定，减少CPU缓存失效worker_cpu_affinity auto;\n```\n\n**踩坑记录**\n：早期我喜欢把worker_processes设成CPU核心数的2倍，觉得这样能处理更多请求。结果发现这是典型的过度优化，多出来的worker进程反而增加了上下文切换开销，QPS不升反降。\n\n#### 法则2：worker连接数配置\n\n```\nevents {    # 每个worker的最大连接数    # 理论最大并发 = worker_processes * worker_connections    worker_connections 65535;    # 使用epoll事件模型（Linux 2.6+必选）    use epoll;    # 允许一个worker进程同时接受多个新连接    multi_accept on;    # 互斥锁，高并发场景建议关闭    accept_mutex off;}\n```\n\n#### 法则3：文件描述符缓存\n\n```\n# main contextworker_rlimit_nofile 1048576;\n```\n\n#### 法则4：sendfile零拷贝\n\n```\nhttp {    # 开启sendfile，避免用户态和内核态之间的数据拷贝    sendfile on;    # 配合sendfile使用，减少网络报文段数量    tcp_nopush on;    # 禁用Nagle算法，减少延迟    tcp_nodelay on;}\n```\n\n**原理解释**\n：传统文件发送需要经历\"磁盘->内核缓冲区->用户缓冲区->socket缓冲区\"四次拷贝。sendfile直接在内核态完成\"磁盘->socket缓冲区\"的数据传输，理论上可以提升30%-40%的吞吐量。\n\n#### 法则5：超时配置\n\n```\nhttp {    # 客户端请求头超时    client_header_timeout 15s;    # 客户端请求体超时    client_body_timeout 15s;    # 响应超时    send_timeout 15s;    # keepalive超时    keepalive_timeout 65s;    # keepalive请求数量限制    keepalive_requests 10000;}\n```\n\n**踩坑记录**\n：曾经有个项目，上传大文件总是失败。排查半天发现是client_body_timeout设成了10秒，但大文件上传需要更长时间。生产环境这个值建议根据实际业务调整，不要一刀切。\n\n#### 法则6：缓冲区配置\n\n```\nhttp {    # 客户端请求体缓冲区    client_body_buffer_size 128k;    client_max_body_size 100m;    # 请求头缓冲区    client_header_buffer_size 4k;    large_client_header_buffers 4 32k;    # 代理缓冲区    proxy_buffer_size 64k;    proxy_buffers 8 128k;    proxy_busy_buffers_size 256k;}\n```\n\n#### 法则7：Gzip压缩\n\n```\nhttp {    gzip on;    gzip_vary on;    gzip_proxied any;    # 压缩级别1-9，建议4-6，太高CPU消耗大    gzip_comp_level 5;    # 最小压缩长度，太小的文件压缩反而浪费CPU    gzip_min_length 1024;    # 压缩类型    gzip_types        text/plain        text/css        text/javascript        application/javascript        application/json        application/xml        application/xml+rss        image/svg+xml;    # 预压缩文件支持    gzip_static on;}\n```\n\n**性能对比**\n：\n\n压缩级别\n\n压缩率\n\nCPU消耗\n\n适用场景\n\n1\n\n低\n\n最低\n\nCPU受限环境\n\n4-5\n\n中\n\n中等\n\n通用场景（推荐）\n\n9\n\n高\n\n最高\n\n带宽极其昂贵\n\n#### 法则8：静态文件缓存\n\n```\nhttp {    # 打开文件缓存    open_file_cache max=100000 inactive=60s;    open_file_cache_valid 60s;    open_file_cache_min_uses 2;    open_file_cache_errors on;}server {    location ~* \\.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {        expires 30d;        add_header Cache-Control \"public, immutable\";        access_log off;    }}\n```\n\n#### 法则9：日志优化\n\n```\nhttp {    # 使用缓冲写入，减少磁盘IO    access_log /var/log/nginx/access.log main buffer=64k flush=5s;    # 或者对于高并发场景，考虑关闭access log    # access_log off;    # 错误日志级别    error_log /var/log/nginx/error.log warn;}\n```\n\n**血泪教训**\n：生产环境日志不要开debug级别！我曾经为了排查问题临时开了debug，结果磁盘一会儿就满了，服务直接挂掉。\n\n#### 法则10：SSL/TLS优化\n\n```\nhttp {    # SSL会话缓存    ssl_session_cache shared:SSL:50m;    ssl_session_timeout 1d;    ssl_session_tickets on;    # SSL协议版本    ssl_protocols TLSv1.2 TLSv1.3;    # 优先使用服务器端加密套件    ssl_prefer_server_ciphers off;    # TLS 1.3加密套件    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;    # OCSP Stapling    ssl_stapling on;    ssl_stapling_verify on;    resolver 8.8.8.8 8.8.4.4 valid=300s;}\n```\n\n#### 法则11：HTTP/2配置\n\n```\nserver {    listen 443 ssl;    http2 on;    # HTTP/2推送（Nginx 1.25.1+）    # 注意：主流浏览器已逐步废弃Server Push}\n```\n\n#### 法则12：连接复用优化\n\n```\nupstream backend {    server 10.0.0.1:8080;    server 10.0.0.2:8080;    # 与后端保持的连接数    keepalive 300;    # 单个连接最大请求数    keepalive_requests 10000;    # 连接超时    keepalive_timeout 60s;}server {    location /api/ {        proxy_pass http://backend;        # 必须使用HTTP/1.1才能使用keepalive        proxy_http_version 1.1;        proxy_set_header Connection \"\";    }}\n```\n\n**这条救命配置**\n：很多人配了upstream的keepalive但不生效，99%是因为没加\n`\nproxy_set_header Connection \"\"\n`\n。默认情况下Nginx会把Connection头设成close，导致每次请求都新建连接。\n\n#### 法则13：负载均衡算法选择\n\n```\nupstream backend {    # 最少连接数算法，推荐    least_conn;    # 或者IP哈希（需要会话保持时使用）    # ip_hash;    # 或者一致性哈希    # hash $request_uri consistent;    server 10.0.0.1:8080 weight=3;    server 10.0.0.2:8080 weight=2;    server 10.0.0.3:8080 weight=1 backup;}\n```\n\n#### 法则14：健康检查\n\n```\nupstream backend {    server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;    server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;}\n```\n\n开源版Nginx的健康检查比较弱，只能被动检测。如果需要主动健康检查，建议：\n\n- 使用Nginx Plus（商业版）\n- 使用第三方模块nginx_upstream_check_module\n- 使用OpenResty\n\n#### 法则15：请求限流\n\n```\nhttp {    # 定义限流区域    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;}server {    location /api/ {        # 请求速率限制        limit_req zone=api_limit burst=200 nodelay;        # 并发连接限制        limit_conn conn_limit 50;        # 限流返回码        limit_req_status 429;        limit_conn_status 429;    }}\n```\n\n#### 法则16：proxy优化\n\n```\nlocation /api/ {    proxy_pass http://backend;    # 连接超时    proxy_connect_timeout 5s;    proxy_send_timeout 60s;    proxy_read_timeout 60s;    # 失败重试    proxy_next_upstream error timeout http_502 http_503;    proxy_next_upstream_tries 3;    proxy_next_upstream_timeout 10s;    # 请求头传递    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header X-Forwarded-Proto $scheme;}\n```\n\n#### 法则17：缓存配置\n\n```\nhttp {    # 定义缓存路径    proxy_cache_path /var/cache/nginx levels=1:2        keys_zone=api_cache:100m        max_size=10g        inactive=60m        use_temp_path=off;}server {    location /api/public/ {        proxy_pass http://backend;        proxy_cache api_cache;        proxy_cache_valid 200 10m;        proxy_cache_valid 404 1m;        proxy_cache_use_stale error timeout updating;        proxy_cache_lock on;        add_header X-Cache-Status $upstream_cache_status;    }}\n```\n\n#### 法则18：安全加固\n\n```\nhttp {    # 隐藏版本号    server_tokens off;    # 安全响应头    add_header X-Frame-Options \"SAMEORIGIN\" always;    add_header X-Content-Type-Options \"nosniff\" always;    add_header X-XSS-Protection \"1; mode=block\" always;    add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;}server {    # 禁止访问隐藏文件    location ~ /\\. {        deny all;        access_log off;        log_not_found off;    }}\n```","/article/122",337,"2026-01-12 11:11:50","2026-01-12 11:12:28",{"id":160,"category_id":46,"title":161,"keywords":6,"description":162,"image_url":6,"content":163,"content_md":164,"url":165,"hits":166,"is_recommend":73,"is_top":73,"create_time":167,"update_time":168},121,"Docker 镜像优化与安全扫描：将镜像体积压缩 70%","1. 适用场景 & 前置条件项目要求适用场景容器化应用镜像体积过大（> 500MB），构建时间长（> 10分钟），存在安全漏洞（CVE高危）OSRHEL/CentOS 7.9+ 或 Ubuntu 20.04+内核Linux Kernel 3.10+软件版本Docker 20.10+ 或 Podman 3.0+，Trivy 0.40+（安全扫描工具）资源规格2C4G（最小）/ 4C8G（推荐），磁盘 50GB+（存储镜像与缓存）网络可访问 Docker Hub/阿里云镜像仓库（","\u003Ch3 class=\"js_darkmode__bg__23\" style=\"text-align: justify;\">\u003Cspan>架构与数据流说明\u003C/span>\u003C/h3>\u003Cp class=\"js_darkmode__84\" style=\"text-align: justify;\">\u003Cspan>Docker 镜像分层架构：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__24 js_darkmode__85\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">镜像 = 基础镜像层 + 依赖层 + 应用层 + 配置层\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ↓\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">每个 Dockerfile 指令（RUN/COPY/ADD）创建新层（Layer）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ↓\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">层累加形成最终镜像（Union File System，联合文件系统）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ↓\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">容器运行时在镜像顶部添加可写层（Container Layer）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__86\" style=\"text-align: justify;\">\u003Cspan>镜像体积构成：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__25 js_darkmode__87\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">总体积 = 基础镜像（如 Ubuntu:22.04 = 77MB）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;+ 系统依赖（apt install = 100-500MB）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;+ 应用依赖（Python packages = 50-200MB）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;+ 应用代码（10-50MB）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;+ 缓存与临时文件（50-200MB）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__88\" style=\"text-align: justify;\">\u003Cspan>优化策略：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__89\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">1.&nbsp;\u003C/span>\u003Cspan>替换基础镜像\u003C/span>\u003Cspan leaf=\"\">：Ubuntu（77MB）→ Alpine（5MB）→ Distroless（&lt; 2MB）→ Scratch（0MB，仅静态二进制）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">2.&nbsp;\u003C/span>\u003Cspan>多阶段构建\u003C/span>\u003Cspan leaf=\"\">：构建阶段（完整工具链）→ 运行时阶段（仅复制二进制与依赖）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">3.&nbsp;\u003C/span>\u003Cspan>层合并\u003C/span>\u003Cspan leaf=\"\">：多个 RUN 指令合并为一个（减少层数，清理临时文件）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">4.&nbsp;\u003C/span>\u003Cspan>依赖精简\u003C/span>\u003Cspan leaf=\"\">：仅安装运行时必需依赖，移除构建工具\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cp class=\"js_darkmode__90\" style=\"text-align: justify;\">\u003Cspan>安全扫描流程：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__26 js_darkmode__91\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">构建镜像 → Trivy 扫描 → 发现漏洞（CVE列表）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ↓\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">分析漏洞来源（基础镜像 / 依赖包 / 应用代码）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ↓\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">修复措施：升级基础镜像 / 更新依赖 / 打补丁\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; ↓\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">重新构建 → 再次扫描 → 确认修复\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__27 js_darkmode__92\" style=\"text-align: justify;\">\u003Ch3 class=\"js_darkmode__bg__28\" style=\"text-align: justify;\">\u003Cspan>Step 1: 评估当前镜像（基线测量）\u003C/span>\u003C/h3>\u003Cp class=\"js_darkmode__93\" style=\"text-align: justify;\">\u003Cspan>目标：\u003C/span>\u003Cspan leaf=\"\">&nbsp;获取优化前的镜像大小、层数、漏洞数量作为对比基线\u003C/span>\u003C/p>\u003Ch4 class=\"js_darkmode__bg__29\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>1.1 检查镜像大小与层数\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__30 js_darkmode__94\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 查看镜像列表与大小\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker images\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 示例输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># REPOSITORY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TAG &nbsp; &nbsp; &nbsp; IMAGE ID &nbsp; &nbsp; &nbsp; CREATED &nbsp; &nbsp; &nbsp; &nbsp; SIZE\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app &nbsp; &nbsp; &nbsp; v1.0 &nbsp; &nbsp; &nbsp;a1b2c3d4e5f6 &nbsp; 2 hours ago &nbsp; &nbsp; 1.2GB &nbsp;# ⚠️ 过大\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 查看镜像构建历史（每层大小）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker&nbsp;\u003C/span>\u003Cspan leaf=\"\">history\u003C/span>\u003Cspan leaf=\"\">&nbsp;my-python-app:v1.0\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 示例输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># IMAGE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CREATED &nbsp; &nbsp; &nbsp; CREATED BY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SIZE &nbsp; &nbsp; &nbsp;COMMENT\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># a1b2c3d4e5f6 &nbsp; 2 hours ago &nbsp; /bin/sh -c pip install -r requirements.txt &nbsp; &nbsp; &nbsp;350MB &nbsp; &nbsp; # ⚠️ 依赖层过大\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># b2c3d4e5f6a7 &nbsp; 3 hours ago &nbsp; /bin/sh -c apt-get install -y build-essential &nbsp; 250MB &nbsp; &nbsp; # ⚠️ 构建工具未清理\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># c3d4e5f6a7b8 &nbsp; 1 day ago &nbsp; &nbsp; /bin/sh -c #(nop) FROM ubuntu:22.04 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;77MB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 统计总层数\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker&nbsp;\u003C/span>\u003Cspan leaf=\"\">history\u003C/span>\u003Cspan leaf=\"\">&nbsp;my-python-app:v1.0 --no-trunc |&nbsp;\u003C/span>\u003Cspan leaf=\"\">wc\u003C/span>\u003Cspan leaf=\"\">&nbsp;-l\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 预期输出：25 层（正常应 &lt; 15 层）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__31\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>1.2 安装并运行 Trivy 安全扫描\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__95\" style=\"text-align: justify;\">\u003Cspan>安装 Trivy（Ubuntu/Debian）：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__32 js_darkmode__96\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 方法1：使用官方脚本\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 方法2：使用 apt\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">sudo\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get install wget apt-transport-https gnupg lsb-release\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key |&nbsp;\u003C/span>\u003Cspan leaf=\"\">sudo\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-key add -\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">echo\u003C/span>\u003Cspan leaf=\"\">\"deb https://aquasecurity.github.io/trivy-repo/deb&nbsp;\u003C/span>\u003Cspan leaf=\"\">$(lsb_release -sc)\u003C/span>\u003Cspan leaf=\"\">&nbsp;main\"\u003C/span>\u003Cspan leaf=\"\">&nbsp;|&nbsp;\u003C/span>\u003Cspan leaf=\"\">sudo\u003C/span>\u003Cspan leaf=\"\">tee\u003C/span>\u003Cspan leaf=\"\">&nbsp;-a /etc/apt/sources.list.d/trivy.list\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">sudo\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get update &amp;&amp;&nbsp;\u003C/span>\u003Cspan leaf=\"\">sudo\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get install trivy\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__97\" style=\"text-align: justify;\">\u003Cspan>安装 Trivy（RHEL/CentOS）：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__33 js_darkmode__98\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 使用 rpm\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.48.3/trivy_0.48.3_Linux-64bit.rpm\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 或使用二进制文件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">wget https://github.com/aquasecurity/trivy/releases/download/v0.48.3/trivy_0.48.3_Linux-64bit.tar.gz\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">tar -zxvf trivy_0.48.3_Linux-64bit.tar.gz\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">sudo\u003C/span>\u003Cspan leaf=\"\">mv\u003C/span>\u003Cspan leaf=\"\">&nbsp;trivy /usr/local/bin/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__99\" style=\"text-align: justify;\">\u003Cspan>扫描镜像漏洞：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__34 js_darkmode__100\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 扫描镜像并输出报告\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy image my-python-app:v1.0\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 示例输出（截取）：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app:v1.0 (ubuntu 22.04)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">#\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Total: 342 (UNKNOWN: 0, LOW: 150, MEDIUM: 120, HIGH: 50, CRITICAL: 22) &nbsp;# ⚠️ 22个严重漏洞！\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">#\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># +--------------+------------------+----------+-------------------+---------------+\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | LIBRARY &nbsp; &nbsp; &nbsp;| VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># +--------------+------------------+----------+-------------------+---------------+\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | libc6 &nbsp; &nbsp; &nbsp; &nbsp;| CVE-2023-4911 &nbsp; &nbsp;| CRITICAL | 2.35-0ubuntu3.1 &nbsp; | 2.35-0ubuntu3.4 |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | openssl &nbsp; &nbsp; &nbsp;| CVE-2023-5678 &nbsp; &nbsp;| HIGH &nbsp; &nbsp; | 3.0.2-0ubuntu1.10 | 3.0.2-0ubuntu1.12 |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | python3.10 &nbsp; | CVE-2023-9999 &nbsp; &nbsp;| HIGH &nbsp; &nbsp; | 3.10.12-1 &nbsp; &nbsp; &nbsp; &nbsp; | 3.10.12-2 |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># +--------------+------------------+----------+-------------------+---------------+\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 仅显示高危及以上漏洞\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy image --severity HIGH,CRITICAL my-python-app:v1.0\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 导出 JSON 格式报告（用于 CI/CD）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy image --format json --output report.json my-python-app:v1.0\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__101\" style=\"text-align: justify;\">\u003Cspan>执行前验证：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__35 js_darkmode__102\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 确认 Docker 已安装\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker --version\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 预期输出：Docker version 24.0.7\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 确认镜像存在\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker images | grep my-python-app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__103\" style=\"text-align: justify;\">\u003Cspan>执行后验证：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__36 js_darkmode__104\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 确认 Trivy 安装成功\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy --version\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 预期输出：Version: 0.48.3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 检查扫描报告文件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">ls\u003C/span>\u003Cspan leaf=\"\">&nbsp;-lh report.json\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__37 js_darkmode__105\" style=\"text-align: justify;\">\u003Ch3 class=\"js_darkmode__bg__38\" style=\"text-align: justify;\">\u003Cspan>Step 2: 优化 Dockerfile - 切换基础镜像\u003C/span>\u003C/h3>\u003Cp class=\"js_darkmode__106\" style=\"text-align: justify;\">\u003Cspan>目标：\u003C/span>\u003Cspan leaf=\"\">&nbsp;将基础镜像从 Ubuntu 替换为 Alpine Linux，减少 70-90% 体积\u003C/span>\u003C/p>\u003Ch4 class=\"js_darkmode__bg__39\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>2.1 原 Dockerfile（未优化）\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__40 js_darkmode__107\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 原 Dockerfile（Python 应用示例）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">FROM\u003C/span>\u003Cspan leaf=\"\">&nbsp;ubuntu:\u003C/span>\u003Cspan leaf=\"\">22.04\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 安装系统依赖\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get update &amp;&amp; apt-get install -y \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; python3 \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; python3-pip \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; build-essential \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; libpq-dev \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; curl \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; vim\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 安装 Python 依赖\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;requirements.txt /app/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">WORKDIR\u003C/span>\u003Cspan leaf=\"\">&nbsp;/app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;pip3 install -r requirements.txt\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 复制应用代码\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;. /app/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 暴露端口\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">EXPOSE\u003C/span>\u003Cspan leaf=\"\">8000\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 启动命令\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">CMD\u003C/span>\u003Cspan leaf=\"\">&nbsp;[\u003C/span>\u003Cspan leaf=\"\">\"python3\"\u003C/span>\u003Cspan leaf=\"\">,&nbsp;\u003C/span>\u003Cspan leaf=\"\">\"app.py\"\u003C/span>\u003Cspan leaf=\"\">]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 问题分析：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 1. 基础镜像过大（Ubuntu 77MB）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 2. 安装了不必要的工具（vim/curl）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 3. 未清理 apt 缓存\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 4. 未使用多阶段构建\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 5. 以 root 用户运行（安全风险）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__108\" style=\"text-align: justify;\">\u003Cspan>构建并测量：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__41 js_darkmode__109\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">docker build -t my-python-app:v1.0-ubuntu .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker images my-python-app:v1.0-ubuntu\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 输出：SIZE = 1.2GB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__42\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>2.2 优化版 Dockerfile（Alpine 基础镜像）\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__43 js_darkmode__110\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 优化 Dockerfile（Alpine Linux）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">FROM\u003C/span>\u003Cspan leaf=\"\">&nbsp;python:\u003C/span>\u003Cspan leaf=\"\">3.11\u003C/span>\u003Cspan leaf=\"\">-alpine3.\u003C/span>\u003Cspan leaf=\"\">18\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 设置工作目录\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">WORKDIR\u003C/span>\u003Cspan leaf=\"\">&nbsp;/app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 安装运行时依赖（仅必需的库）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apk add --no-cache \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; libpq \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &amp;&amp;&nbsp;\u003C/span>\u003Cspan leaf=\"\">rm\u003C/span>\u003Cspan leaf=\"\">&nbsp;-rf /var/cache/apk/* &nbsp;\u003C/span>\u003Cspan leaf=\"\"># 清理apk缓存\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 安装 Python 依赖（使用虚拟环境）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;requirements.txt .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apk add --no-cache --virtual .build-deps \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gcc \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; musl-dev \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; postgresql-dev \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &amp;&amp; pip install --no-cache-dir -r requirements.txt \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &amp;&amp; apk del .build-deps &nbsp;\u003C/span>\u003Cspan leaf=\"\"># 删除构建依赖\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 复制应用代码\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;--\u003C/span>\u003Cspan leaf=\"\">chown\u003C/span>\u003Cspan leaf=\"\">=appuser:appuser . .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 创建非 root 用户\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;addgroup -S appuser &amp;&amp; adduser -S appuser -G appuser\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 切换到非 root 用户\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">USER\u003C/span>\u003Cspan leaf=\"\">&nbsp;appuser\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 暴露端口\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">EXPOSE\u003C/span>\u003Cspan leaf=\"\">8000\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 健康检查\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">HEALTHCHECK\u003C/span>\u003Cspan leaf=\"\">&nbsp;--interval=30s --\u003C/span>\u003Cspan leaf=\"\">timeout\u003C/span>\u003Cspan leaf=\"\">=3s \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; CMD wget --quiet --tries=1 --spider http://localhost:8000/health ||&nbsp;\u003C/span>\u003Cspan leaf=\"\">exit\u003C/span>\u003Cspan leaf=\"\">&nbsp;1\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 启动命令\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">CMD\u003C/span>\u003Cspan leaf=\"\">&nbsp;[\u003C/span>\u003Cspan leaf=\"\">\"python\"\u003C/span>\u003Cspan leaf=\"\">,&nbsp;\u003C/span>\u003Cspan leaf=\"\">\"app.py\"\u003C/span>\u003Cspan leaf=\"\">]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__111\" style=\"text-align: justify;\">\u003Cspan>关键优化点解释：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__112\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">1.&nbsp;\u003C/span>\u003Cspan>python:3.11-alpine3.18\u003C/span>\u003Cspan leaf=\"\">：官方 Alpine 基础镜像（约 50MB，比 Ubuntu 小 35%）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">2.&nbsp;\u003C/span>\u003Cspan>apk add --no-cache\u003C/span>\u003Cspan leaf=\"\">：不保留 apk 索引缓存（减少 5-10MB）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">3.&nbsp;\u003C/span>\u003Cspan>–virtual .build-deps\u003C/span>\u003Cspan leaf=\"\">：构建依赖打包为虚拟包，安装后可整体删除\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">4.&nbsp;\u003C/span>\u003Cspan>–no-cache-dir\u003C/span>\u003Cspan leaf=\"\">：pip 不缓存下载的包（减少 50-100MB）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">5.&nbsp;\u003C/span>\u003Cspan>USER appuser\u003C/span>\u003Cspan leaf=\"\">：非 root 用户运行（安全加固）\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cp class=\"js_darkmode__113\" style=\"text-align: justify;\">\u003Cspan>构建并对比：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__44 js_darkmode__114\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">docker build -t my-python-app:v1.0-alpine .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker images | grep my-python-app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app:v1.0-ubuntu &nbsp; 1.2GB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app:v1.0-alpine &nbsp; 350MB &nbsp;# 减少 70.8%\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__45 js_darkmode__115\" style=\"text-align: justify;\">\u003Ch3 class=\"js_darkmode__bg__46\" style=\"text-align: justify;\">\u003Cspan>Step 3: 优化 Dockerfile - 多阶段构建\u003C/span>\u003C/h3>\u003Cp class=\"js_darkmode__116\" style=\"text-align: justify;\">\u003Cspan>目标：\u003C/span>\u003Cspan leaf=\"\">&nbsp;将构建环境与运行时环境分离，进一步减少 50-70% 体积\u003C/span>\u003C/p>\u003Ch4 class=\"js_darkmode__bg__47\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>3.1 多阶段构建 Dockerfile（最终优化版）\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__48 js_darkmode__117\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># ============ 阶段1：构建阶段 ============\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">FROM\u003C/span>\u003Cspan leaf=\"\">&nbsp;python:\u003C/span>\u003Cspan leaf=\"\">3.11\u003C/span>\u003Cspan leaf=\"\">-alpine3.\u003C/span>\u003Cspan leaf=\"\">18\u003C/span>\u003Cspan leaf=\"\">&nbsp;AS builder\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">WORKDIR\u003C/span>\u003Cspan leaf=\"\">&nbsp;/app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 安装构建依赖\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apk add --no-cache \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; gcc \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; musl-dev \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; postgresql-dev \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; libffi-dev\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 安装 Python 依赖到虚拟环境\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;requirements.txt .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;python -m venv /opt/venv &amp;&amp; \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; /opt/venv/bin/pip install --no-cache-dir -r requirements.txt\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># ============ 阶段2：运行时阶段 ============\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">FROM\u003C/span>\u003Cspan leaf=\"\">&nbsp;python:\u003C/span>\u003Cspan leaf=\"\">3.11\u003C/span>\u003Cspan leaf=\"\">-alpine3.\u003C/span>\u003Cspan leaf=\"\">18\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">WORKDIR\u003C/span>\u003Cspan leaf=\"\">&nbsp;/app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 仅安装运行时库（无需编译工具）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apk add --no-cache \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; libpq \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; libffi \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &amp;&amp;&nbsp;\u003C/span>\u003Cspan leaf=\"\">rm\u003C/span>\u003Cspan leaf=\"\">&nbsp;-rf /var/cache/apk/*\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 从构建阶段复制虚拟环境\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;--from=builder /opt/venv /opt/venv\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 复制应用代码\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;--\u003C/span>\u003Cspan leaf=\"\">chown\u003C/span>\u003Cspan leaf=\"\">=appuser:appuser . .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 创建非 root 用户\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;addgroup -S appuser &amp;&amp; adduser -S appuser -G appuser\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 设置环境变量（使用虚拟环境）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">ENV\u003C/span>\u003Cspan leaf=\"\">&nbsp;PATH=\u003C/span>\u003Cspan leaf=\"\">\"/opt/venv/bin:$PATH\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">USER\u003C/span>\u003Cspan leaf=\"\">&nbsp;appuser\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">EXPOSE\u003C/span>\u003Cspan leaf=\"\">8000\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">HEALTHCHECK\u003C/span>\u003Cspan leaf=\"\">&nbsp;--interval=30s --\u003C/span>\u003Cspan leaf=\"\">timeout\u003C/span>\u003Cspan leaf=\"\">=3s \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; CMD wget --quiet --tries=1 --spider http://localhost:8000/health ||&nbsp;\u003C/span>\u003Cspan leaf=\"\">exit\u003C/span>\u003Cspan leaf=\"\">&nbsp;1\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">CMD\u003C/span>\u003Cspan leaf=\"\">&nbsp;[\u003C/span>\u003Cspan leaf=\"\">\"python\"\u003C/span>\u003Cspan leaf=\"\">,&nbsp;\u003C/span>\u003Cspan leaf=\"\">\"app.py\"\u003C/span>\u003Cspan leaf=\"\">]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__118\" style=\"text-align: justify;\">\u003Cspan>多阶段构建优势：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__119\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>阶段1（builder）\u003C/span>\u003Cspan leaf=\"\">：包含完整编译工具链（gcc/make），用于编译 C 扩展依赖\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>阶段2（运行时）\u003C/span>\u003Cspan leaf=\"\">：仅复制编译好的二进制与依赖，不包含编译工具\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>体积减少\u003C/span>\u003Cspan leaf=\"\">：编译工具约占 150-200MB，通过多阶段构建完全删除\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cp class=\"js_darkmode__120\" style=\"text-align: justify;\">\u003Cspan>构建并对比：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__49 js_darkmode__121\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">docker build -t my-python-app:v1.0-multistage .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker images | grep my-python-app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app:v1.0-ubuntu &nbsp; &nbsp; &nbsp;1.2GB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app:v1.0-alpine &nbsp; &nbsp; &nbsp;350MB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app:v1.0-multistage &nbsp;120MB &nbsp;# 减少 90%！\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__122\" style=\"text-align: justify;\">\u003Cspan>验证功能完整性：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__50 js_darkmode__123\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 启动容器\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker run -d -p 8000:8000 --name test-app my-python-app:v1.0-multistage\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 测试应用\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl http://localhost:8000/health\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 预期输出：{\"status\": \"healthy\"}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 检查容器日志\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker logs test-app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 清理测试容器\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker stop test-app &amp;&amp; docker&nbsp;\u003C/span>\u003Cspan leaf=\"\">rm\u003C/span>\u003Cspan leaf=\"\">&nbsp;test-app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__51 js_darkmode__124\" style=\"text-align: justify;\">\u003Ch3 class=\"js_darkmode__bg__52\" style=\"text-align: justify;\">\u003Cspan>Step 4: 层合并与缓存清理\u003C/span>\u003C/h3>\u003Cp class=\"js_darkmode__125\" style=\"text-align: justify;\">\u003Cspan>目标：\u003C/span>\u003Cspan leaf=\"\">&nbsp;减少镜像层数，清理构建缓存与临时文件\u003C/span>\u003C/p>\u003Ch4 class=\"js_darkmode__bg__53\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>4.1 合并 RUN 指令\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__126\" style=\"text-align: justify;\">\u003Cspan>未优化（多层）：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__54 js_darkmode__127\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get update\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get install -y python3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get install -y python3-pip\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get install -y libpq-dev\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get clean\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 问题：每个 RUN 创建一层，即使最后 clean 也不会减少前面层的体积\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__128\" style=\"text-align: justify;\">\u003Cspan>优化后（单层）：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__55 js_darkmode__129\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get update &amp;&amp; apt-get install -y \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; python3 \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; python3-pip \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; libpq-dev \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &amp;&amp; apt-get clean \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &amp;&amp;&nbsp;\u003C/span>\u003Cspan leaf=\"\">rm\u003C/span>\u003Cspan leaf=\"\">&nbsp;-rf /var/lib/apt/lists/* &nbsp;\u003C/span>\u003Cspan leaf=\"\"># 删除 apt 缓存\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 优势：一层完成，临时文件在同一层内删除，不占用最终镜像体积\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__56\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>4.2 使用 .dockerignore 文件\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__130\" style=\"text-align: justify;\">\u003Cspan>创建 .dockerignore：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__57 js_darkmode__131\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># .dockerignore（排除无关文件）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 版本控制\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.git\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.gitignore\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.github\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 开发文件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">*.md\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">*.\u003C/span>\u003Cspan leaf=\"\">log\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">*.pyc\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">__pycache__/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.pytest_cache/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.vscode/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.idea/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 测试文件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">tests/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">test_*.py\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 构建产物\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">build/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">dist/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">*.egg-info/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 环境文件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.\u003C/span>\u003Cspan leaf=\"\">env\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.env.local\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">venv/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">env\u003C/span>\u003Cspan leaf=\"\">/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 文档\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docs/\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">README.md\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">LICENSE\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># CI/CD\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">.gitlab-ci.yml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">Jenkinsfile\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__132\" style=\"text-align: justify;\">\u003Cspan>效果验证：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__58 js_darkmode__133\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 对比 COPY 指令复制的文件大小\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 未使用 .dockerignore：COPY . . 复制 50MB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 使用后：COPY . . 复制 15MB（减少 70%）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__59\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>4.3 启用 Docker BuildKit\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__134\" style=\"text-align: justify;\">\u003Cspan>启用方法：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__60 js_darkmode__135\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 方法1：环境变量\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">export\u003C/span>\u003Cspan leaf=\"\">&nbsp;DOCKER_BUILDKIT=1\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker build -t my-app:v2.0 .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 方法2：守护进程配置（持久化）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># /etc/docker/daemon.json\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">{\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\"features\"\u003C/span>\u003Cspan leaf=\"\">: {\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\"buildkit\"\u003C/span>\u003Cspan leaf=\"\">:&nbsp;\u003C/span>\u003Cspan leaf=\"\">true\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; }\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 重启 Docker\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">sudo\u003C/span>\u003Cspan leaf=\"\">&nbsp;systemctl restart docker\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__136\" style=\"text-align: justify;\">\u003Cspan>BuildKit 优势：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__137\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 并行构建多个层（性能提升 2-5 倍）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 自动跳过未使用的阶段（多阶段构建优化）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 更好的缓存机制（修改代码不重新下载依赖）\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cp class=\"js_darkmode__138\" style=\"text-align: justify;\">\u003Cspan>验证 BuildKit 启用：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__61 js_darkmode__139\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">docker build -t test-buildkit .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 输出包含 [buildkit] 标识\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># [buildkit] [1/5] FROM docker.io/library/python:3.11-alpine3.18\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__62 js_darkmode__140\" style=\"text-align: justify;\">\u003Ch3 class=\"js_darkmode__bg__63\" style=\"text-align: justify;\">\u003Cspan>Step 5: 安全扫描与漏洞修复\u003C/span>\u003C/h3>\u003Cp class=\"js_darkmode__141\" style=\"text-align: justify;\">\u003Cspan>目标：\u003C/span>\u003Cspan leaf=\"\">&nbsp;扫描优化后的镜像，修复高危漏洞至零\u003C/span>\u003C/p>\u003Ch4 class=\"js_darkmode__bg__64\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>5.1 扫描优化后的镜像\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__65 js_darkmode__142\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 扫描多阶段构建的镜像\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy image --severity HIGH,CRITICAL my-python-app:v1.0-multistage\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 示例输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Total: 12 (HIGH: 8, CRITICAL: 4) &nbsp;# 仍有漏洞（来自基础镜像或依赖）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">#\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># +--------------+------------------+----------+-------------------+---------------+\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | LIBRARY &nbsp; &nbsp; &nbsp;| VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># +--------------+------------------+----------+-------------------+---------------+\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | libcrypto3 &nbsp; | CVE-2023-5678 &nbsp; &nbsp;| CRITICAL | 3.0.10-r0 &nbsp; &nbsp; &nbsp; &nbsp; | 3.0.12-r0 &nbsp; &nbsp; |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | python3.11 &nbsp; | CVE-2023-9999 &nbsp; &nbsp;| HIGH &nbsp; &nbsp; | 3.11.6-r0 &nbsp; &nbsp; &nbsp; &nbsp; | 3.11.7-r1 &nbsp; &nbsp; |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># +--------------+------------------+----------+-------------------+---------------+\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__66\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>5.2 修复漏洞 - 升级基础镜像\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__67 js_darkmode__143\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 原基础镜像（存在漏洞）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">FROM\u003C/span>\u003Cspan leaf=\"\">&nbsp;python:\u003C/span>\u003Cspan leaf=\"\">3.11\u003C/span>\u003Cspan leaf=\"\">-alpine3.\u003C/span>\u003Cspan leaf=\"\">18\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 修复方法1：升级到最新版本\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">FROM\u003C/span>\u003Cspan leaf=\"\">&nbsp;python:\u003C/span>\u003Cspan leaf=\"\">3.11\u003C/span>\u003Cspan leaf=\"\">-alpine3.\u003C/span>\u003Cspan leaf=\"\">19\u003C/span>\u003Cspan leaf=\"\"># 更新的基础镜像通常包含安全补丁\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 修复方法2：在 Dockerfile 中手动升级受影响的包\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">FROM\u003C/span>\u003Cspan leaf=\"\">&nbsp;python:\u003C/span>\u003Cspan leaf=\"\">3.11\u003C/span>\u003Cspan leaf=\"\">-alpine3.\u003C/span>\u003Cspan leaf=\"\">18\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apk upgrade --no-cache libcrypto3 libssl3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__68\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>5.3 修复漏洞 - 更新 Python 依赖\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__69 js_darkmode__144\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 检查 Python 依赖的漏洞\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">pip install safety\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">safety check --file requirements.txt\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 示例输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | package &nbsp; &nbsp; | installed | affected &nbsp; &nbsp; | source &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># | requests &nbsp; &nbsp;| 2.28.0 &nbsp; &nbsp;| &lt;2.31.0 &nbsp; &nbsp; &nbsp;| https://pyup.io/vulnerabilities/CVE-2023-32681/ |\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 修复：更新 requirements.txt\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 原：requests==2.28.0\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 新：requests==2.31.0\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__70\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>5.4 再次扫描验证\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__71 js_darkmode__145\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 重新构建镜像\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker build -t my-python-app:v1.0-secure .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 再次扫描\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy image --severity HIGH,CRITICAL my-python-app:v1.0-secure\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 预期输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Total: 0 (HIGH: 0, CRITICAL: 0) &nbsp;# ✅ 无高危漏洞\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__72 js_darkmode__146\" style=\"text-align: justify;\">\u003Ch3 class=\"js_darkmode__bg__73\" style=\"text-align: justify;\">\u003Cspan>Step 6: 安全加固措施\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__74\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>6.1 非 root 用户运行\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__75 js_darkmode__147\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 创建专用用户（UID/GID 固定，便于权限管理）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;addgroup -g 1001 -S appuser &amp;&amp; \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; adduser -u 1001 -S appuser -G appuser\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 设置文件所有者\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">COPY\u003C/span>\u003Cspan leaf=\"\">&nbsp;--\u003C/span>\u003Cspan leaf=\"\">chown\u003C/span>\u003Cspan leaf=\"\">=appuser:appuser . /app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 切换用户\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">USER\u003C/span>\u003Cspan leaf=\"\">&nbsp;appuser\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__148\" style=\"text-align: justify;\">\u003Cspan>验证：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__76 js_darkmode__149\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 检查容器内运行用户\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker run --\u003C/span>\u003Cspan leaf=\"\">rm\u003C/span>\u003Cspan leaf=\"\">&nbsp;my-python-app:v1.0-secure&nbsp;\u003C/span>\u003Cspan leaf=\"\">id\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 预期输出：uid=1001(appuser) gid=1001(appuser)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__77\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>6.2 移除 SUID 二进制文件\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__78 js_darkmode__150\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 移除可能被利用的 SUID 文件（如 su/sudo）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;find / -perm /6000 -\u003C/span>\u003Cspan leaf=\"\">type\u003C/span>\u003Cspan leaf=\"\">&nbsp;f -\u003C/span>\u003Cspan leaf=\"\">exec\u003C/span>\u003Cspan leaf=\"\">chmod\u003C/span>\u003Cspan leaf=\"\">&nbsp;a-s {} \\; ||&nbsp;\u003C/span>\u003Cspan leaf=\"\">true\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__79\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>6.3 只读根文件系统\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__80 js_darkmode__151\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 运行容器时启用只读根文件系统\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker run --read-only --tmpfs /tmp my-python-app:v1.0-secure\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__81\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>6.4 镜像签名（Docker Content Trust）\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__82 js_darkmode__152\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 启用 Content Trust\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">export\u003C/span>\u003Cspan leaf=\"\">&nbsp;DOCKER_CONTENT_TRUST=1\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 推送镜像（会自动签名）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker push myregistry.com/my-python-app:v1.0-secure\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 拉取镜像时自动验证签名\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">docker pull myregistry.com/my-python-app:v1.0-secure\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__83 js_darkmode__153\" style=\"text-align: justify;\">\u003Ch3 class=\"js_darkmode__bg__84\" style=\"text-align: justify;\">\u003Cspan>Step 7: 最终对比与验证\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__85\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>7.1 体积对比\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__86 js_darkmode__154\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">docker images | grep my-python-app\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 输出：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># REPOSITORY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SIZE\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app &nbsp; &nbsp; &nbsp; v1.0-ubuntu &nbsp; &nbsp; &nbsp;1.2GB &nbsp; # 原始版本\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app &nbsp; &nbsp; &nbsp; v1.0-alpine &nbsp; &nbsp; &nbsp;350MB &nbsp; # Alpine 基础镜像\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app &nbsp; &nbsp; &nbsp; v1.0-multistage &nbsp;120MB &nbsp; # 多阶段构建\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># my-python-app &nbsp; &nbsp; &nbsp; v1.0-secure &nbsp; &nbsp; &nbsp;115MB &nbsp; # 最终优化版（体积减少 90.4%！）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__87\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>7.2 安全对比\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__88 js_darkmode__155\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 扫描对比\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy image --severity HIGH,CRITICAL my-python-app:v1.0-ubuntu\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 输出：Total: 72 (HIGH: 50, CRITICAL: 22)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">trivy image --severity HIGH,CRITICAL my-python-app:v1.0-secure\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 输出：Total: 0 (HIGH: 0, CRITICAL: 0) &nbsp;# ✅ 零高危漏洞\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__89\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆&nbsp;\u003C/span>\u003Cspan>7.3 构建时间对比\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__90 js_darkmode__156\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 未启用 BuildKit\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">time\u003C/span>\u003Cspan leaf=\"\">&nbsp;docker build -t test-nobuildkit .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># real &nbsp; &nbsp;8m32s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 启用 BuildKit\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">export\u003C/span>\u003Cspan leaf=\"\">&nbsp;DOCKER_BUILDKIT=1\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">time\u003C/span>\u003Cspan leaf=\"\">&nbsp;docker build -t test-buildkit .\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># real &nbsp; &nbsp;2m15s &nbsp;# 提升 73.6%\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp style=\"text-align: left;\">\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003C/p>\u003Cp style=\"text-align: left;\">\u003Cspan leaf=\"\">\u003Cb>最小必要原理\u003C/b>\u003C/span>\u003C/p>\u003Cp class=\"js_darkmode__158\" style=\"text-align: justify;\">\u003Cspan>Docker 镜像分层机制：\u003C/span>\u003C/p>\u003Cp class=\"js_darkmode__159\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">Docker 使用&nbsp;\u003C/span>\u003Cspan>联合文件系统（Union File System）\u003C/span>\u003Cspan leaf=\"\">&nbsp;实现镜像分层：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__160\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">1. 每个 Dockerfile 指令（FROM/RUN/COPY/ADD）创建一个只读层\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">2. 层之间通过 Copy-on-Write（COW）机制堆叠\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">3. 容器运行时在最顶层添加可写层（Container Layer）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">4. 所有层的累加 = 最终镜像体积\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cp class=\"js_darkmode__161\" style=\"text-align: justify;\">\u003Cspan>为什么删除文件不减少镜像体积？\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__93 js_darkmode__162\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 错误示例\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get update &amp;&amp; apt-get install -y build-essential &nbsp;\u003C/span>\u003Cspan leaf=\"\"># Layer 1: +200MB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get clean &nbsp;\u003C/span>\u003Cspan leaf=\"\"># Layer 2: 删除缓存，但 Layer 1 的 200MB 仍存在！\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 最终镜像 = Layer 1 (200MB) + Layer 2 (0MB) = 200MB\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 正确示例\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">RUN\u003C/span>\u003Cspan leaf=\"\">&nbsp;apt-get update &amp;&amp; apt-get install -y build-essential \\\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &amp;&amp; apt-get clean &nbsp;\u003C/span>\u003Cspan leaf=\"\"># 在同一层完成安装与清理\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 最终镜像 = Layer 1 (150MB，已清理缓存)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__163\" style=\"text-align: justify;\">\u003Cspan>多阶段构建原理：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__164\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>阶段1（builder）\u003C/span>\u003Cspan leaf=\"\">：包含完整工具链，生成二进制或编译依赖\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>阶段2（运行时）\u003C/span>\u003Cspan leaf=\"\">：使用&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">COPY --from=builder\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;仅复制必要文件\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>丢弃的内容\u003C/span>\u003Cspan leaf=\"\">：阶段1的所有中间层（编译工具、临时文件）不会进入最终镜像\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cp class=\"js_darkmode__165\" style=\"text-align: justify;\">\u003Cspan>Alpine vs Ubuntu 体积差异：\u003C/span>\u003C/p>\u003Cp>\u003Ccode>\u003Cspan leaf=\"\">\u003C/span>\u003C/code>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__166\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>Ubuntu\u003C/span>\u003Cspan leaf=\"\">：基于 glibc，包含完整 GNU 工具链（bash/coreutils），适合通用场景\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>Alpine\u003C/span>\u003Cspan leaf=\"\">：基于 musl libc + BusyBox，极致精简，但可能遇到兼容性问题（如某些 Python C 扩展）\u003C/span>\u003C/section>\u003C/li>\u003C/ul>","### 架构与数据流说明\n\nDocker 镜像分层架构：\n\n```\n镜像 = 基础镜像层 + 依赖层 + 应用层 + 配置层    ↓每个 Dockerfile 指令（RUN/COPY/ADD）创建新层（Layer）    ↓层累加形成最终镜像（Union File System，联合文件系统）    ↓容器运行时在镜像顶部添加可写层（Container Layer）\n```\n\n镜像体积构成：\n\n```\n总体积 = 基础镜像（如 Ubuntu:22.04 = 77MB）       + 系统依赖（apt install = 100-500MB）       + 应用依赖（Python packages = 50-200MB）       + 应用代码（10-50MB）       + 缓存与临时文件（50-200MB）\n```\n\n优化策略：\n\n1. 1. 替换基础镜像：Ubuntu（77MB）→ Alpine（5MB）→ Distroless（\u003C 2MB）→ Scratch（0MB，仅静态二进制）\n2. 2. 多阶段构建：构建阶段（完整工具链）→ 运行时阶段（仅复制二进制与依赖）\n3. 3. 层合并：多个 RUN 指令合并为一个（减少层数，清理临时文件）\n4. 4. 依赖精简：仅安装运行时必需依赖，移除构建工具\n\n安全扫描流程：\n\n```\n构建镜像 → Trivy 扫描 → 发现漏洞（CVE列表）    ↓分析漏洞来源（基础镜像 / 依赖包 / 应用代码）    ↓修复措施：升级基础镜像 / 更新依赖 / 打补丁    ↓重新构建 → 再次扫描 → 确认修复\n```\n\n---\n\n### Step 1: 评估当前镜像（基线测量）\n\n目标：\n\n 获取优化前的镜像大小、层数、漏洞数量作为对比基线\n\n#### ◆ 1.1 检查镜像大小与层数\n\n```\n# 查看镜像列表与大小docker images# 示例输出：# REPOSITORY          TAG       IMAGE ID       CREATED         SIZE# my-python-app       v1.0      a1b2c3d4e5f6   2 hours ago     1.2GB  # ⚠️ 过大# 查看镜像构建历史（每层大小）docker history my-python-app:v1.0# 示例输出：# IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT# a1b2c3d4e5f6   2 hours ago   /bin/sh -c pip install -r requirements.txt      350MB     # ⚠️ 依赖层过大# b2c3d4e5f6a7   3 hours ago   /bin/sh -c apt-get install -y build-essential   250MB     # ⚠️ 构建工具未清理# c3d4e5f6a7b8   1 day ago     /bin/sh -c #(nop) FROM ubuntu:22.04              77MB# 统计总层数docker history my-python-app:v1.0 --no-trunc | wc -l# 预期输出：25 层（正常应 \u003C 15 层）\n```\n\n#### ◆ 1.2 安装并运行 Trivy 安全扫描\n\n安装 Trivy（Ubuntu/Debian）：\n\n```\n# 方法1：使用官方脚本curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin# 方法2：使用 aptsudo apt-get install wget apt-transport-https gnupg lsb-releasewget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -echo\"deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main\" | sudotee -a /etc/apt/sources.list.d/trivy.listsudo apt-get update && sudo apt-get install trivy\n```\n\n安装 Trivy（RHEL/CentOS）：\n\n```\n# 使用 rpmrpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.48.3/trivy_0.48.3_Linux-64bit.rpm# 或使用二进制文件wget https://github.com/aquasecurity/trivy/releases/download/v0.48.3/trivy_0.48.3_Linux-64bit.tar.gztar -zxvf trivy_0.48.3_Linux-64bit.tar.gzsudomv trivy /usr/local/bin/\n```\n\n扫描镜像漏洞：\n\n```\n# 扫描镜像并输出报告trivy image my-python-app:v1.0# 示例输出（截取）：# my-python-app:v1.0 (ubuntu 22.04)## Total: 342 (UNKNOWN: 0, LOW: 150, MEDIUM: 120, HIGH: 50, CRITICAL: 22)  # ⚠️ 22个严重漏洞！## +--------------+------------------+----------+-------------------+---------------+# | LIBRARY      | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |# +--------------+------------------+----------+-------------------+---------------+# | libc6        | CVE-2023-4911    | CRITICAL | 2.35-0ubuntu3.1   | 2.35-0ubuntu3.4 |# | openssl      | CVE-2023-5678    | HIGH     | 3.0.2-0ubuntu1.10 | 3.0.2-0ubuntu1.12 |# | python3.10   | CVE-2023-9999    | HIGH     | 3.10.12-1         | 3.10.12-2 |# +--------------+------------------+----------+-------------------+---------------+# 仅显示高危及以上漏洞trivy image --severity HIGH,CRITICAL my-python-app:v1.0# 导出 JSON 格式报告（用于 CI/CD）trivy image --format json --output report.json my-python-app:v1.0\n```\n\n执行前验证：\n\n```\n# 确认 Docker 已安装docker --version# 预期输出：Docker version 24.0.7# 确认镜像存在docker images | grep my-python-app\n```\n\n执行后验证：\n\n```\n# 确认 Trivy 安装成功trivy --version# 预期输出：Version: 0.48.3# 检查扫描报告文件ls -lh report.json\n```\n\n---\n\n### Step 2: 优化 Dockerfile - 切换基础镜像\n\n目标：\n\n 将基础镜像从 Ubuntu 替换为 Alpine Linux，减少 70-90% 体积\n\n#### ◆ 2.1 原 Dockerfile（未优化）\n\n```\n# 原 Dockerfile（Python 应用示例）FROM ubuntu:22.04# 安装系统依赖RUN apt-get update && apt-get install -y \\    python3 \\    python3-pip \\    build-essential \\    libpq-dev \\    curl \\    vim# 安装 Python 依赖COPY requirements.txt /app/WORKDIR /appRUN pip3 install -r requirements.txt# 复制应用代码COPY . /app/# 暴露端口EXPOSE8000# 启动命令CMD [\"python3\", \"app.py\"]# 问题分析：# 1. 基础镜像过大（Ubuntu 77MB）# 2. 安装了不必要的工具（vim/curl）# 3. 未清理 apt 缓存# 4. 未使用多阶段构建# 5. 以 root 用户运行（安全风险）\n```\n\n构建并测量：\n\n```\ndocker build -t my-python-app:v1.0-ubuntu .docker images my-python-app:v1.0-ubuntu# 输出：SIZE = 1.2GB\n```\n\n#### ◆ 2.2 优化版 Dockerfile（Alpine 基础镜像）\n\n```\n# 优化 Dockerfile（Alpine Linux）FROM python:3.11-alpine3.18# 设置工作目录WORKDIR /app# 安装运行时依赖（仅必需的库）RUN apk add --no-cache \\    libpq \\    && rm -rf /var/cache/apk/*  # 清理apk缓存# 安装 Python 依赖（使用虚拟环境）COPY requirements.txt .RUN apk add --no-cache --virtual .build-deps \\    gcc \\    musl-dev \\    postgresql-dev \\    && pip install --no-cache-dir -r requirements.txt \\    && apk del .build-deps  # 删除构建依赖# 复制应用代码COPY --chown=appuser:appuser . .# 创建非 root 用户RUN addgroup -S appuser && adduser -S appuser -G appuser# 切换到非 root 用户USER appuser# 暴露端口EXPOSE8000# 健康检查HEALTHCHECK --interval=30s --timeout=3s \\    CMD wget --quiet --tries=1 --spider http://localhost:8000/health || exit 1# 启动命令CMD [\"python\", \"app.py\"]\n```\n\n关键优化点解释：\n\n1. 1. python:3.11-alpine3.18：官方 Alpine 基础镜像（约 50MB，比 Ubuntu 小 35%）\n2. 2. apk add --no-cache：不保留 apk 索引缓存（减少 5-10MB）\n3. 3. –virtual .build-deps：构建依赖打包为虚拟包，安装后可整体删除\n4. 4. –no-cache-dir：pip 不缓存下载的包（减少 50-100MB）\n5. 5. USER appuser：非 root 用户运行（安全加固）\n\n构建并对比：\n\n```\ndocker build -t my-python-app:v1.0-alpine .docker images | grep my-python-app# 输出：# my-python-app:v1.0-ubuntu   1.2GB# my-python-app:v1.0-alpine   350MB  # 减少 70.8%\n```\n\n---\n\n### Step 3: 优化 Dockerfile - 多阶段构建\n\n目标：\n\n 将构建环境与运行时环境分离，进一步减少 50-70% 体积\n\n#### ◆ 3.1 多阶段构建 Dockerfile（最终优化版）\n\n```\n# ============ 阶段1：构建阶段 ============FROM python:3.11-alpine3.18 AS builderWORKDIR /app# 安装构建依赖RUN apk add --no-cache \\    gcc \\    musl-dev \\    postgresql-dev \\    libffi-dev# 安装 Python 依赖到虚拟环境COPY requirements.txt .RUN python -m venv /opt/venv && \\    /opt/venv/bin/pip install --no-cache-dir -r requirements.txt# ============ 阶段2：运行时阶段 ============FROM python:3.11-alpine3.18WORKDIR /app# 仅安装运行时库（无需编译工具）RUN apk add --no-cache \\    libpq \\    libffi \\    && rm -rf /var/cache/apk/*# 从构建阶段复制虚拟环境COPY --from=builder /opt/venv /opt/venv# 复制应用代码COPY --chown=appuser:appuser . .# 创建非 root 用户RUN addgroup -S appuser && adduser -S appuser -G appuser# 设置环境变量（使用虚拟环境）ENV PATH=\"/opt/venv/bin:$PATH\"USER appuserEXPOSE8000HEALTHCHECK --interval=30s --timeout=3s \\    CMD wget --quiet --tries=1 --spider http://localhost:8000/health || exit 1CMD [\"python\", \"app.py\"]\n```\n\n多阶段构建优势：\n\n- • 阶段1（builder）：包含完整编译工具链（gcc/make），用于编译 C 扩展依赖\n- • 阶段2（运行时）：仅复制编译好的二进制与依赖，不包含编译工具\n- • 体积减少：编译工具约占 150-200MB，通过多阶段构建完全删除\n\n构建并对比：\n\n```\ndocker build -t my-python-app:v1.0-multistage .docker images | grep my-python-app# 输出：# my-python-app:v1.0-ubuntu      1.2GB# my-python-app:v1.0-alpine      350MB# my-python-app:v1.0-multistage  120MB  # 减少 90%！\n```\n\n验证功能完整性：\n\n```\n# 启动容器docker run -d -p 8000:8000 --name test-app my-python-app:v1.0-multistage# 测试应用curl http://localhost:8000/health# 预期输出：{\"status\": \"healthy\"}# 检查容器日志docker logs test-app# 清理测试容器docker stop test-app && docker rm test-app\n```\n\n---\n\n### Step 4: 层合并与缓存清理\n\n目标：\n\n 减少镜像层数，清理构建缓存与临时文件\n\n#### ◆ 4.1 合并 RUN 指令\n\n未优化（多层）：\n\n```\nRUN apt-get updateRUN apt-get install -y python3RUN apt-get install -y python3-pipRUN apt-get install -y libpq-devRUN apt-get clean# 问题：每个 RUN 创建一层，即使最后 clean 也不会减少前面层的体积\n```\n\n优化后（单层）：\n\n```\nRUN apt-get update && apt-get install -y \\    python3 \\    python3-pip \\    libpq-dev \\    && apt-get clean \\    && rm -rf /var/lib/apt/lists/*  # 删除 apt 缓存# 优势：一层完成，临时文件在同一层内删除，不占用最终镜像体积\n```\n\n#### ◆ 4.2 使用 .dockerignore 文件\n\n创建 .dockerignore：\n\n```\n# .dockerignore（排除无关文件）# 版本控制.git.gitignore.github# 开发文件*.md*.log*.pyc__pycache__/.pytest_cache/.vscode/.idea/# 测试文件tests/test_*.py# 构建产物build/dist/*.egg-info/# 环境文件.env.env.localvenv/env/# 文档docs/README.mdLICENSE# CI/CD.gitlab-ci.ymlJenkinsfile\n```\n\n效果验证：\n\n```\n# 对比 COPY 指令复制的文件大小# 未使用 .dockerignore：COPY . . 复制 50MB# 使用后：COPY . . 复制 15MB（减少 70%）\n```\n\n#### ◆ 4.3 启用 Docker BuildKit\n\n启用方法：\n\n```\n# 方法1：环境变量export DOCKER_BUILDKIT=1docker build -t my-app:v2.0 .# 方法2：守护进程配置（持久化）# /etc/docker/daemon.json{\"features\": {\"buildkit\": true  }}# 重启 Dockersudo systemctl restart docker\n```\n\nBuildKit 优势：\n\n- • 并行构建多个层（性能提升 2-5 倍）\n- • 自动跳过未使用的阶段（多阶段构建优化）\n- • 更好的缓存机制（修改代码不重新下载依赖）\n\n验证 BuildKit 启用：\n\n```\ndocker build -t test-buildkit .# 输出包含 [buildkit] 标识# [buildkit] [1/5] FROM docker.io/library/python:3.11-alpine3.18\n```\n\n---\n\n### Step 5: 安全扫描与漏洞修复\n\n目标：\n\n 扫描优化后的镜像，修复高危漏洞至零\n\n#### ◆ 5.1 扫描优化后的镜像\n\n```\n# 扫描多阶段构建的镜像trivy image --severity HIGH,CRITICAL my-python-app:v1.0-multistage# 示例输出：# Total: 12 (HIGH: 8, CRITICAL: 4)  # 仍有漏洞（来自基础镜像或依赖）## +--------------+------------------+----------+-------------------+---------------+# | LIBRARY      | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |# +--------------+------------------+----------+-------------------+---------------+# | libcrypto3   | CVE-2023-5678    | CRITICAL | 3.0.10-r0         | 3.0.12-r0     |# | python3.11   | CVE-2023-9999    | HIGH     | 3.11.6-r0         | 3.11.7-r1     |# +--------------+------------------+----------+-------------------+---------------+\n```\n\n#### ◆ 5.2 修复漏洞 - 升级基础镜像\n\n```\n# 原基础镜像（存在漏洞）FROM python:3.11-alpine3.18# 修复方法1：升级到最新版本FROM python:3.11-alpine3.19# 更新的基础镜像通常包含安全补丁# 修复方法2：在 Dockerfile 中手动升级受影响的包FROM python:3.11-alpine3.18RUN apk upgrade --no-cache libcrypto3 libssl3\n```\n\n#### ◆ 5.3 修复漏洞 - 更新 Python 依赖\n\n```\n# 检查 Python 依赖的漏洞pip install safetysafety check --file requirements.txt# 示例输出：# | package     | installed | affected     | source                                    |# | requests    | 2.28.0    |\n```\n\n#### ◆ 5.4 再次扫描验证\n\n```\n# 重新构建镜像docker build -t my-python-app:v1.0-secure .# 再次扫描trivy image --severity HIGH,CRITICAL my-python-app:v1.0-secure# 预期输出：# Total: 0 (HIGH: 0, CRITICAL: 0)  # ✅ 无高危漏洞\n```\n\n---\n\n### Step 6: 安全加固措施\n\n#### ◆ 6.1 非 root 用户运行\n\n```\n# 创建专用用户（UID/GID 固定，便于权限管理）RUN addgroup -g 1001 -S appuser && \\    adduser -u 1001 -S appuser -G appuser# 设置文件所有者COPY --chown=appuser:appuser . /app# 切换用户USER appuser\n```\n\n验证：\n\n```\n# 检查容器内运行用户docker run --rm my-python-app:v1.0-secure id# 预期输出：uid=1001(appuser) gid=1001(appuser)\n```\n\n#### ◆ 6.2 移除 SUID 二进制文件\n\n```\n# 移除可能被利用的 SUID 文件（如 su/sudo）RUN find / -perm /6000 -type f -execchmod a-s {} \\; || true\n```\n\n#### ◆ 6.3 只读根文件系统\n\n```\n# 运行容器时启用只读根文件系统docker run --read-only --tmpfs /tmp my-python-app:v1.0-secure\n```\n\n#### ◆ 6.4 镜像签名（Docker Content Trust）\n\n```\n# 启用 Content Trustexport DOCKER_CONTENT_TRUST=1# 推送镜像（会自动签名）docker push myregistry.com/my-python-app:v1.0-secure# 拉取镜像时自动验证签名docker pull myregistry.com/my-python-app:v1.0-secure\n```\n\n---\n\n### Step 7: 最终对比与验证\n\n#### ◆ 7.1 体积对比\n\n```\ndocker images | grep my-python-app# 输出：# REPOSITORY          TAG              SIZE# my-python-app       v1.0-ubuntu      1.2GB   # 原始版本# my-python-app       v1.0-alpine      350MB   # Alpine 基础镜像# my-python-app       v1.0-multistage  120MB   # 多阶段构建# my-python-app       v1.0-secure      115MB   # 最终优化版（体积减少 90.4%！）\n```\n\n#### ◆ 7.2 安全对比\n\n```\n# 扫描对比trivy image --severity HIGH,CRITICAL my-python-app:v1.0-ubuntu# 输出：Total: 72 (HIGH: 50, CRITICAL: 22)trivy image --severity HIGH,CRITICAL my-python-app:v1.0-secure# 输出：Total: 0 (HIGH: 0, CRITICAL: 0)  # ✅ 零高危漏洞\n```\n\n#### ◆ 7.3 构建时间对比\n\n```\n# 未启用 BuildKittime docker build -t test-nobuildkit .# real    8m32s# 启用 BuildKitexport DOCKER_BUILDKIT=1time docker build -t test-buildkit .# real    2m15s  # 提升 73.6%\n```\n\n \n\n**最小必要原理**\n\nDocker 镜像分层机制：\n\nDocker 使用 \n\n联合文件系统（Union File System）\n\n 实现镜像分层：\n\n1. 1. 每个 Dockerfile 指令（FROM/RUN/COPY/ADD）创建一个只读层\n2. 2. 层之间通过 Copy-on-Write（COW）机制堆叠\n3. 3. 容器运行时在最顶层添加可写层（Container Layer）\n4. 4. 所有层的累加 = 最终镜像体积\n\n为什么删除文件不减少镜像体积？\n\n```\n# 错误示例RUN apt-get update && apt-get install -y build-essential  # Layer 1: +200MBRUN apt-get clean  # Layer 2: 删除缓存，但 Layer 1 的 200MB 仍存在！# 最终镜像 = Layer 1 (200MB) + Layer 2 (0MB) = 200MB# 正确示例RUN apt-get update && apt-get install -y build-essential \\    && apt-get clean  # 在同一层完成安装与清理# 最终镜像 = Layer 1 (150MB，已清理缓存)\n```\n\n多阶段构建原理：\n\n- • 阶段1（builder）：包含完整工具链，生成二进制或编译依赖\n- • 阶段2（运行时）：使用 COPY --from=builder 仅复制必要文件\n- • 丢弃的内容：阶段1的所有中间层（编译工具、临时文件）不会进入最终镜像\n\nAlpine vs Ubuntu 体积差异：\n\n`\n\n`\n\n- • Ubuntu：基于 glibc，包含完整 GNU 工具链（bash/coreutils），适合通用场景\n- • Alpine：基于 musl libc + BusyBox，极致精简，但可能遇到兼容性问题（如某些 Python C 扩展）","/article/121",309,"2026-01-06 11:54:35","2026-01-06 12:01:59",{"id":170,"category_id":44,"title":171,"keywords":6,"description":172,"image_url":6,"content":173,"content_md":174,"url":175,"hits":176,"is_recommend":73,"is_top":73,"create_time":177,"update_time":178},120,"用 Prometheus Recording Rules 把告警噪声砍掉 70%(二)","五、故障排查和监控5.1 故障排查◆ 5.1.1 日志查看# 查看 Prometheus 日志中的规则评估错误journalctl -u prometheus | grep -i&nbsp;\"rule\"&nbsp;|&nbsp;tail&nbsp;-50# 查看规则评估耗时curl -s http://localhost:9090/api/v1/rules | jq&nbsp;'.data.groups[].rules[] | select(.health != \"ok\")'# Kubernet","\u003Ch2 class=\"js_darkmode__bg__65\" style=\"text-align: center;\">\u003Cspan leaf=\"\">五、故障排查和监控\u003C/span>\u003C/h2>\u003Ch3 class=\"js_darkmode__bg__66\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">5.1 故障排查\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__67\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.1.1 日志查看\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__68 js_darkmode__77\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 查看 Prometheus 日志中的规则评估错误\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">journalctl -u prometheus | grep -i&nbsp;\u003C/span>\u003Cspan leaf=\"\">\"rule\"\u003C/span>\u003Cspan leaf=\"\">&nbsp;|&nbsp;\u003C/span>\u003Cspan leaf=\"\">tail\u003C/span>\u003Cspan leaf=\"\">&nbsp;-50\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 查看规则评估耗时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s http://localhost:9090/api/v1/rules | jq&nbsp;\u003C/span>\u003Cspan leaf=\"\">'.data.groups[].rules[] | select(.health != \"ok\")'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Kubernetes 环境\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">kubectl logs -n monitoring prometheus-server-0 | grep -i&nbsp;\u003C/span>\u003Cspan leaf=\"\">\"recording\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__69\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.1.2 常见问题排查\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__78\" style=\"text-align: justify;\">\u003Cspan>问题一：Recording Rule 显示 “no data”\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__70 js_darkmode__79\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 诊断命令\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 1. 确认源指标存在\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s&nbsp;\u003C/span>\u003Cspan leaf=\"\">'http://localhost:9090/api/v1/query?query=node_cpu_seconds_total'\u003C/span>\u003Cspan leaf=\"\">&nbsp;| jq&nbsp;\u003C/span>\u003Cspan leaf=\"\">'.data.result | length'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 2. 测试表达式\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s&nbsp;\u003C/span>\u003Cspan leaf=\"\">'http://localhost:9090/api/v1/query?query=rate(node_cpu_seconds_total[5m])'\u003C/span>\u003Cspan leaf=\"\">&nbsp;| jq&nbsp;\u003C/span>\u003Cspan leaf=\"\">'.data.result | length'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__80\" style=\"text-align: justify;\">\u003Cspan>解决方案\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__81\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">1. 确认源指标正在被采集\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">2. 检查标签选择器是否匹配\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">3. 验证时间窗口是否合理（数据量是否足够）\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cp class=\"js_darkmode__82\" style=\"text-align: justify;\">\u003Cspan>问题二：Recording Rules 计算结果与预期不符\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__71 js_darkmode__83\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 诊断命令\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 对比 Recording Rule 结果与手动查询结果\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s&nbsp;\u003C/span>\u003Cspan leaf=\"\">'http://localhost:9090/api/v1/query?query=instance:node_cpu_utilization:avg5m{instance=\"node1:9100\"}'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s&nbsp;\u003C/span>\u003Cspan leaf=\"\">'http://localhost:9090/api/v1/query?query=1-avg(rate(node_cpu_seconds_total{instance=\"node1:9100\",mode=\"idle\"}[5m]))'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__84\" style=\"text-align: justify;\">\u003Cspan>解决方案\u003C/span>\u003Cspan leaf=\"\">：检查 by 子句是否包含了所有需要保留的标签\u003C/span>\u003C/p>\u003Cp class=\"js_darkmode__85\" style=\"text-align: justify;\">\u003Cspan>问题三：规则评估超时\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__86\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>症状\u003C/span>\u003Cspan leaf=\"\">：Prometheus 日志出现 “rule group took longer than interval”\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>排查\u003C/span>\u003Cspan leaf=\"\">：检查规则复杂度和数据量\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>解决\u003C/span>\u003Cspan leaf=\"\">：拆分规则组、增大 interval、优化表达式\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 class=\"js_darkmode__bg__72\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.1.3 调试模式\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__73 js_darkmode__87\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 开启 Prometheus 查询日志\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 在启动参数中添加\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">--query.log-queries\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 查看慢查询\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">grep&nbsp;\u003C/span>\u003Cspan leaf=\"\">\"slow\"\u003C/span>\u003Cspan leaf=\"\">&nbsp;/var/log/prometheus/query.log\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 使用 Prometheus 内置指标分析规则评估\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">prometheus_rule_evaluation_duration_seconds\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">prometheus_rule_group_last_duration_seconds\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch3 class=\"js_darkmode__bg__74\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">5.2 性能监控\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__75\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.2.1 关键指标监控\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__76 js_darkmode__88\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># Recording Rules 评估耗时\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">histogram_quantile(0.99, rate(prometheus_rule_evaluation_duration_seconds_bucket[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 规则评估失败次数\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rate(prometheus_rule_evaluation_failures_total[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 规则产生的时序数量\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">prometheus_tsdb_head_series\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 内存使用\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">process_resident_memory_bytes{job=\u003C/span>\u003Cspan leaf=\"\">\"prometheus\"\u003C/span>\u003Cspan leaf=\"\">}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__77\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.2.2 监控指标说明\u003C/span>\u003C/h4>\u003Ctable class=\"js_darkmode__89 layui-table\" style=\"text-align: justify;\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__bg__78\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">指标名称\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__79\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">正常范围\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__80\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">告警阈值\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__81\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">说明\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd class=\"js_darkmode__90\">\u003Csection>\u003Cspan leaf=\"\">rule_evaluation_duration_seconds\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__91\">\u003Csection>\u003Cspan leaf=\"\">&lt; 1s\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__92\">\u003Csection>\u003Cspan leaf=\"\">&gt; 5s\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__93\">\u003Csection>\u003Cspan leaf=\"\">规则评估耗时，过长说明规则复杂或数据量大\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__94\">\u003Csection>\u003Cspan leaf=\"\">rule_evaluation_failures_total\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__95\">\u003Csection>\u003Cspan leaf=\"\">0\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__96\">\u003Csection>\u003Cspan leaf=\"\">&gt; 0\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__97\">\u003Csection>\u003Cspan leaf=\"\">规则评估失败，需要检查表达式\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__98\">\u003Csection>\u003Cspan leaf=\"\">tsdb_head_series\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__99\">\u003Csection>\u003Cspan leaf=\"\">视环境而定\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__100\">\u003Csection>\u003Cspan leaf=\"\">增长率 &gt; 10%/h\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__101\">\u003Csection>\u003Cspan leaf=\"\">时序数量，Recording Rules 会增加时序\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__102\">\u003Csection>\u003Cspan leaf=\"\">process_resident_memory_bytes\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__103\">\u003Csection>\u003Cspan leaf=\"\">&lt; 80% 配置内存\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__104\">\u003Csection>\u003Cspan leaf=\"\">&gt; 90%\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__105\">\u003Csection>\u003Cspan leaf=\"\">内存使用，时序增加会占用更多内存\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003Ch4 class=\"js_darkmode__bg__82\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.2.3 Recording Rules 自身监控\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__83 js_darkmode__106\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 监控 Recording Rules 健康状态\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">recording_rules_health\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">RecordingRuleEvaluationSlow\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prometheus_rule_group_last_duration_seconds &gt;\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prometheus_rule_group_interval_seconds\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">labels:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">severity:\u003C/span>\u003Cspan leaf=\"\">warning\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">annotations:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">summary:\u003C/span>\u003Cspan leaf=\"\">\"Recording Rule 组&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $labels.rule_group }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;评估超时\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">RecordingRuleEvaluationFailure\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">rate(prometheus_rule_evaluation_failures_total[5m])\u003C/span>\u003Cspan leaf=\"\">&gt;\u003C/span>\u003Cspan leaf=\"\">0\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">labels:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">severity:\u003C/span>\u003Cspan leaf=\"\">critical\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">annotations:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">summary:\u003C/span>\u003Cspan leaf=\"\">\"Recording Rule 评估失败\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch3 class=\"js_darkmode__bg__84\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">5.3 备份与恢复\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__85\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.3.1 配置备份\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__86 js_darkmode__107\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">#!/bin/bash\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Recording Rules 配置备份脚本\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 文件名：backup_recording_rules.sh\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">BACKUP_DIR=\u003C/span>\u003Cspan leaf=\"\">\"/backup/prometheus/rules\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">PROMETHEUS_RULES_DIR=\u003C/span>\u003Cspan leaf=\"\">\"/etc/prometheus/rules\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">DATE=$(\u003C/span>\u003Cspan leaf=\"\">date\u003C/span>\u003Cspan leaf=\"\">&nbsp;+%Y%m%d_%H%M%S)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">mkdir\u003C/span>\u003Cspan leaf=\"\">&nbsp;-p&nbsp;\u003C/span>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 备份所有规则文件\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">tar -czvf&nbsp;\u003C/span>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003Cspan leaf=\"\">/rules_\u003C/span>\u003Cspan leaf=\"\">${DATE}\u003C/span>\u003Cspan leaf=\"\">.tar.gz -C&nbsp;\u003C/span>\u003Cspan leaf=\"\">${PROMETHEUS_RULES_DIR}\u003C/span>\u003Cspan leaf=\"\">&nbsp;.\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 保留最近30天的备份\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">find&nbsp;\u003C/span>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003Cspan leaf=\"\">&nbsp;-name&nbsp;\u003C/span>\u003Cspan leaf=\"\">\"rules_*.tar.gz\"\u003C/span>\u003Cspan leaf=\"\">&nbsp;-mtime +30 -delete\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 验证备份\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">tar -tzf&nbsp;\u003C/span>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003Cspan leaf=\"\">/rules_\u003C/span>\u003Cspan leaf=\"\">${DATE}\u003C/span>\u003Cspan leaf=\"\">.tar.gz\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__87\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 5.3.2 恢复流程\u003C/span>\u003C/h4>\u003Col class=\"list-paddingleft-1 js_darkmode__108\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">1.&nbsp;\u003C/span>\u003Cspan>停止 Prometheus\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">systemctl stop prometheus\u003C/span>\u003C/code>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">2.&nbsp;\u003C/span>\u003Cspan>恢复配置\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">tar -xzvf /backup/prometheus/rules/rules_xxx.tar.gz -C /etc/prometheus/rules/\u003C/span>\u003C/code>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">3.&nbsp;\u003C/span>\u003Cspan>验证配置\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">promtool check rules /etc/prometheus/rules/*.yml\u003C/span>\u003C/code>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">4.&nbsp;\u003C/span>\u003Cspan>启动服务\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">systemctl start prometheus\u003C/span>\u003C/code>\u003C/section>\u003C/li>\u003C/ol>\u003Chr class=\"js_darkmode__bg__88 js_darkmode__109\" style=\"text-align: justify;\">\u003Ch2 class=\"js_darkmode__bg__89\" style=\"text-align: center;\">\u003Cspan leaf=\"\">六、总结\u003C/span>\u003C/h2>\u003Ch3 class=\"js_darkmode__bg__90\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">6.1 技术要点回顾\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__110\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>要点一\u003C/span>\u003Cspan leaf=\"\">：Recording Rules 的核心价值在于预计算和聚合，通过时间窗口平滑消除瞬时抖动，通过层级聚合实现告警收敛\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>要点二\u003C/span>\u003Cspan leaf=\"\">：命名规范至关重要，采用&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">level:metric_name:aggregation\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;格式，便于理解和维护\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>要点三\u003C/span>\u003Cspan leaf=\"\">：分层设计是大规模环境的最佳实践，从原始指标到基础设施指标到业务指标，逐层抽象\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>要点四\u003C/span>\u003Cspan leaf=\"\">：Recording Rules 需要持续监控和优化，关注评估耗时、失败次数、时序增长等指标\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 class=\"js_darkmode__bg__91\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">6.2 进阶学习方向\u003C/span>\u003C/h3>\u003Col class=\"list-paddingleft-1 js_darkmode__111\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">1.&nbsp;\u003C/span>\u003Cspan>告警分级与智能降噪\u003C/span>\u003Cspan leaf=\"\">：结合机器学习算法实现异常检测，替代固定阈值\u003C/span>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__112\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 学习资源：Prometheus 社区的 anomaly detection proposals\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 实践建议：从简单的动态基线开始，逐步引入更复杂的算法\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">2.&nbsp;\u003C/span>\u003Cspan>大规模 Prometheus 架构\u003C/span>\u003Cspan leaf=\"\">：联邦集群、远程存储、Thanos/Cortex\u003C/span>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__113\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 学习资源：Thanos 官方文档、CNCF 相关演讲\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 实践建议：在测试环境搭建联邦架构，理解 Recording Rules 在不同层级的分工\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">3.&nbsp;\u003C/span>\u003Cspan>PromQL 高级技巧\u003C/span>\u003Cspan leaf=\"\">：子查询、偏移量、复杂聚合\u003C/span>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__114\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 学习资源：PromLabs 博客、Prometheus 官方文档\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 实践建议：多在 Prometheus UI 练习，理解不同函数的计算逻辑\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003C/ol>\u003Ch3 class=\"js_darkmode__bg__92\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">6.3 参考资料\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__115\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;Prometheus Recording Rules 官方文档&nbsp;- 权威参考\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;Robust Perception 博客&nbsp;- Brian Brazil（Prometheus 核心开发者）的博客\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;PromLabs 博客&nbsp;- 深入的 PromQL 教程\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;Awesome Prometheus Alerts&nbsp;- 社区维护的告警规则集合\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Chr class=\"js_darkmode__bg__93 js_darkmode__116\" style=\"text-align: justify;\">\u003Ch2 class=\"js_darkmode__bg__94\" style=\"text-align: center;\">\u003Cspan leaf=\"\">附录\u003C/span>\u003C/h2>\u003Ch3 class=\"js_darkmode__bg__95\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">A. Recording Rules 命令速查表\u003C/span>\u003C/h3>\u003Cpre class=\"js_darkmode__bg__96 js_darkmode__117\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 检查规则语法\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">promtool check rules /etc/prometheus/rules/*.yml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 热加载配置\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -X POST http://localhost:9090/-/reload\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 查看规则状态\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s http://localhost:9090/api/v1/rules | jq&nbsp;\u003C/span>\u003Cspan leaf=\"\">'.data.groups[].rules[] | {record, health}'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 测试表达式\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s&nbsp;\u003C/span>\u003Cspan leaf=\"\">'http://localhost:9090/api/v1/query?query=YOUR_EXPRESSION'\u003C/span>\u003Cspan leaf=\"\">&nbsp;| jq\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 查看规则评估指标\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s&nbsp;\u003C/span>\u003Cspan leaf=\"\">'http://localhost:9090/api/v1/query?query=prometheus_rule_evaluation_duration_seconds'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch3 class=\"js_darkmode__bg__97\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">B. 常用聚合函数说明\u003C/span>\u003C/h3>\u003Ctable class=\"js_darkmode__118 layui-table\" style=\"text-align: justify;\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__bg__98\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">函数\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__99\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">用途\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__100\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">示例\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd class=\"js_darkmode__119\">\u003Csection>\u003Cspan leaf=\"\">avg_over_time\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__120\">\u003Csection>\u003Cspan leaf=\"\">时间窗口内平均值，平滑抖动\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__121\">\u003Csection>\u003Cspan leaf=\"\">avg_over_time(cpu[5m])\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__122\">\u003Csection>\u003Cspan leaf=\"\">max_over_time\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__123\">\u003Csection>\u003Cspan leaf=\"\">时间窗口内最大值，捕获峰值\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__124\">\u003Csection>\u003Cspan leaf=\"\">max_over_time(cpu[15m])\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__125\">\u003Csection>\u003Cspan leaf=\"\">min_over_time\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__126\">\u003Csection>\u003Cspan leaf=\"\">时间窗口内最小值\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__127\">\u003Csection>\u003Cspan leaf=\"\">min_over_time(available[5m])\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__128\">\u003Csection>\u003Cspan leaf=\"\">rate\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__129\">\u003Csection>\u003Cspan leaf=\"\">计数器每秒增长率\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__130\">\u003Csection>\u003Cspan leaf=\"\">rate(requests_total[5m])\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__131\">\u003Csection>\u003Cspan leaf=\"\">increase\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__132\">\u003Csection>\u003Cspan leaf=\"\">时间窗口内增量\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__133\">\u003Csection>\u003Cspan leaf=\"\">increase(restarts[1h])\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__134\">\u003Csection>\u003Cspan leaf=\"\">histogram_quantile\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__135\">\u003Csection>\u003Cspan leaf=\"\">直方图分位数\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__136\">\u003Csection>\u003Cspan leaf=\"\">histogram_quantile(0.99, rate(bucket[5m]))\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__137\">\u003Csection>\u003Cspan leaf=\"\">clamp_max/clamp_min\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__138\">\u003Csection>\u003Cspan leaf=\"\">限制值范围\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__139\">\u003Csection>\u003Cspan leaf=\"\">clamp_max(ratio, 1)\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003Ch3 class=\"js_darkmode__bg__101\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">C. 术语表\u003C/span>\u003C/h3>\u003Ctable class=\"js_darkmode__140 layui-table\" style=\"text-align: justify;\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__bg__102\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">术语\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__103\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">英文\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__104\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">解释\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd class=\"js_darkmode__141\">\u003Csection>\u003Cspan leaf=\"\">Recording Rules\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__142\">\u003Csection>\u003Cspan leaf=\"\">Recording Rules\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__143\">\u003Csection>\u003Cspan leaf=\"\">Prometheus 的预计算规则，将复杂查询结果存储为新时间序列\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__144\">\u003Csection>\u003Cspan leaf=\"\">告警噪声\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__145\">\u003Csection>\u003Cspan leaf=\"\">Alert Noise\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__146\">\u003Csection>\u003Cspan leaf=\"\">非关键性、重复性或误报的告警，会导致告警疲劳\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__147\">\u003Csection>\u003Cspan leaf=\"\">时间窗口\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__148\">\u003Csection>\u003Cspan leaf=\"\">Time Window\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__149\">\u003Csection>\u003Cspan leaf=\"\">PromQL 中用方括号指定的时间范围，如 [5m]\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__150\">\u003Csection>\u003Cspan leaf=\"\">基数\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__151\">\u003Csection>\u003Cspan leaf=\"\">Cardinality\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__152\">\u003Csection>\u003Cspan leaf=\"\">时间序列的数量，由指标名和标签组合决定\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__153\">\u003Csection>\u003Cspan leaf=\"\">告警收敛\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__154\">\u003Csection>\u003Cspan leaf=\"\">Alert Aggregation\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__155\">\u003Csection>\u003Cspan leaf=\"\">将多个相关告警合并为一个，减少告警数量\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>","## 五、故障排查和监控\n\n### 5.1 故障排查\n\n#### ◆ 5.1.1 日志查看\n\n```\n# 查看 Prometheus 日志中的规则评估错误journalctl -u prometheus | grep -i \"rule\" | tail -50# 查看规则评估耗时curl -s http://localhost:9090/api/v1/rules | jq '.data.groups[].rules[] | select(.health != \"ok\")'# Kubernetes 环境kubectl logs -n monitoring prometheus-server-0 | grep -i \"recording\"\n```\n\n#### ◆ 5.1.2 常见问题排查\n\n问题一：Recording Rule 显示 “no data”\n\n```\n# 诊断命令# 1. 确认源指标存在curl -s 'http://localhost:9090/api/v1/query?query=node_cpu_seconds_total' | jq '.data.result | length'# 2. 测试表达式curl -s 'http://localhost:9090/api/v1/query?query=rate(node_cpu_seconds_total[5m])' | jq '.data.result | length'\n```\n\n解决方案\n\n：\n\n1. 1. 确认源指标正在被采集\n2. 2. 检查标签选择器是否匹配\n3. 3. 验证时间窗口是否合理（数据量是否足够）\n\n问题二：Recording Rules 计算结果与预期不符\n\n```\n# 诊断命令# 对比 Recording Rule 结果与手动查询结果curl -s 'http://localhost:9090/api/v1/query?query=instance:node_cpu_utilization:avg5m{instance=\"node1:9100\"}'curl -s 'http://localhost:9090/api/v1/query?query=1-avg(rate(node_cpu_seconds_total{instance=\"node1:9100\",mode=\"idle\"}[5m]))'\n```\n\n解决方案\n\n：检查 by 子句是否包含了所有需要保留的标签\n\n问题三：规则评估超时\n\n- • 症状：Prometheus 日志出现 “rule group took longer than interval”\n- • 排查：检查规则复杂度和数据量\n- • 解决：拆分规则组、增大 interval、优化表达式\n\n#### ◆ 5.1.3 调试模式\n\n```\n# 开启 Prometheus 查询日志# 在启动参数中添加--query.log-queries# 查看慢查询grep \"slow\" /var/log/prometheus/query.log# 使用 Prometheus 内置指标分析规则评估prometheus_rule_evaluation_duration_secondsprometheus_rule_group_last_duration_seconds\n```\n\n### 5.2 性能监控\n\n#### ◆ 5.2.1 关键指标监控\n\n```\n# Recording Rules 评估耗时histogram_quantile(0.99, rate(prometheus_rule_evaluation_duration_seconds_bucket[5m]))# 规则评估失败次数rate(prometheus_rule_evaluation_failures_total[5m])# 规则产生的时序数量prometheus_tsdb_head_series# 内存使用process_resident_memory_bytes{job=\"prometheus\"}\n```\n\n#### ◆ 5.2.2 监控指标说明\n\n指标名称\n\n正常范围\n\n告警阈值\n\n说明\n\nrule_evaluation_duration_seconds\n\n\u003C 1s\n\n> 5s\n\n规则评估耗时，过长说明规则复杂或数据量大\n\nrule_evaluation_failures_total\n\n0\n\n> 0\n\n规则评估失败，需要检查表达式\n\ntsdb_head_series\n\n视环境而定\n\n增长率 > 10%/h\n\n时序数量，Recording Rules 会增加时序\n\nprocess_resident_memory_bytes\n\n\u003C 80% 配置内存\n\n> 90%\n\n内存使用，时序增加会占用更多内存\n\n#### ◆ 5.2.3 Recording Rules 自身监控\n\n```\n# 监控 Recording Rules 健康状态groups:-name:recording_rules_healthrules:-alert:RecordingRuleEvaluationSlowexpr:|          prometheus_rule_group_last_duration_seconds >          prometheus_rule_group_interval_secondsfor:5mlabels:severity:warningannotations:summary:\"Recording Rule 组 {{ $labels.rule_group }} 评估超时\"-alert:RecordingRuleEvaluationFailureexpr:rate(prometheus_rule_evaluation_failures_total[5m])>0for:5mlabels:severity:criticalannotations:summary:\"Recording Rule 评估失败\"\n```\n\n### 5.3 备份与恢复\n\n#### ◆ 5.3.1 配置备份\n\n```\n#!/bin/bash# Recording Rules 配置备份脚本# 文件名：backup_recording_rules.shBACKUP_DIR=\"/backup/prometheus/rules\"PROMETHEUS_RULES_DIR=\"/etc/prometheus/rules\"DATE=$(date +%Y%m%d_%H%M%S)mkdir -p ${BACKUP_DIR}# 备份所有规则文件tar -czvf ${BACKUP_DIR}/rules_${DATE}.tar.gz -C ${PROMETHEUS_RULES_DIR} .# 保留最近30天的备份find ${BACKUP_DIR} -name \"rules_*.tar.gz\" -mtime +30 -delete# 验证备份tar -tzf ${BACKUP_DIR}/rules_${DATE}.tar.gz\n```\n\n#### ◆ 5.3.2 恢复流程\n\n1. 1. 停止 Prometheus：systemctl stop prometheus\n2. 2. 恢复配置：tar -xzvf /backup/prometheus/rules/rules_xxx.tar.gz -C /etc/prometheus/rules/\n3. 3. 验证配置：promtool check rules /etc/prometheus/rules/*.yml\n4. 4. 启动服务：systemctl start prometheus\n\n---\n\n## 六、总结\n\n### 6.1 技术要点回顾\n\n- • 要点一：Recording Rules 的核心价值在于预计算和聚合，通过时间窗口平滑消除瞬时抖动，通过层级聚合实现告警收敛\n- • 要点二：命名规范至关重要，采用 level:metric_name:aggregation 格式，便于理解和维护\n- • 要点三：分层设计是大规模环境的最佳实践，从原始指标到基础设施指标到业务指标，逐层抽象\n- • 要点四：Recording Rules 需要持续监控和优化，关注评估耗时、失败次数、时序增长等指标\n\n### 6.2 进阶学习方向\n\n1. 1. 告警分级与智能降噪：结合机器学习算法实现异常检测，替代固定阈值\n2. 2. 大规模 Prometheus 架构：联邦集群、远程存储、Thanos/Cortex\n3. 3. PromQL 高级技巧：子查询、偏移量、复杂聚合\n\n### 6.3 参考资料\n\n- • Prometheus Recording Rules 官方文档 - 权威参考\n- • Robust Perception 博客 - Brian Brazil（Prometheus 核心开发者）的博客\n- • PromLabs 博客 - 深入的 PromQL 教程\n- • Awesome Prometheus Alerts - 社区维护的告警规则集合\n\n---\n\n## 附录\n\n### A. Recording Rules 命令速查表\n\n```\n# 检查规则语法promtool check rules /etc/prometheus/rules/*.yml# 热加载配置curl -X POST http://localhost:9090/-/reload# 查看规则状态curl -s http://localhost:9090/api/v1/rules | jq '.data.groups[].rules[] | {record, health}'# 测试表达式curl -s 'http://localhost:9090/api/v1/query?query=YOUR_EXPRESSION' | jq# 查看规则评估指标curl -s 'http://localhost:9090/api/v1/query?query=prometheus_rule_evaluation_duration_seconds'\n```\n\n### B. 常用聚合函数说明\n\n函数\n\n用途\n\n示例\n\navg_over_time\n\n时间窗口内平均值，平滑抖动\n\navg_over_time(cpu[5m])\n\nmax_over_time\n\n时间窗口内最大值，捕获峰值\n\nmax_over_time(cpu[15m])\n\nmin_over_time\n\n时间窗口内最小值\n\nmin_over_time(available[5m])\n\nrate\n\n计数器每秒增长率\n\nrate(requests_total[5m])\n\nincrease\n\n时间窗口内增量\n\nincrease(restarts[1h])\n\nhistogram_quantile\n\n直方图分位数\n\nhistogram_quantile(0.99, rate(bucket[5m]))\n\nclamp_max/clamp_min\n\n限制值范围\n\nclamp_max(ratio, 1)\n\n### C. 术语表\n\n术语\n\n英文\n\n解释\n\nRecording Rules\n\nRecording Rules\n\nPrometheus 的预计算规则，将复杂查询结果存储为新时间序列\n\n告警噪声\n\nAlert Noise\n\n非关键性、重复性或误报的告警，会导致告警疲劳\n\n时间窗口\n\nTime Window\n\nPromQL 中用方括号指定的时间范围，如 [5m]\n\n基数\n\nCardinality\n\n时间序列的数量，由指标名和标签组合决定\n\n告警收敛\n\nAlert Aggregation\n\n将多个相关告警合并为一个，减少告警数量","/article/120",282,"2026-01-06 11:53:50","2026-01-06 11:54:33",{"id":180,"category_id":44,"title":181,"keywords":6,"description":182,"image_url":6,"content":183,"content_md":184,"url":185,"hits":186,"is_recommend":73,"is_top":73,"create_time":187,"update_time":188},119,"用 Prometheus Recording Rules 把告警噪声砍掉 70%(一)","一、概述1.1 背景介绍在大规模微服务架构下，Prometheus 告警系统往往会陷入一个尴尬的境地：告警太多，运维团队开始选择性忽略；告警太少，真正的故障又可能漏掉。我在某电商平台负责监控体系建设时，团队每天要处理超过 2000 条告警，其中 70% 以上是重复的、关联的或者短暂抖动产生的噪声。Recording Rules 是 Prometheus 提供的预计算机制，可以将复杂的查询表达式预先计算并存储为新的时间序列。通过合理设计 Recording Rules，我们不仅能显著降低 Prom","\u003Ch2 class=\"js_darkmode__bg__2\" style=\"text-align: center;\">\u003Cspan leaf=\"\">一、概述\u003C/span>\u003C/h2>\u003Ch3 class=\"js_darkmode__bg__3\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">1.1 背景介绍\u003C/span>\u003C/h3>\u003Cp class=\"js_darkmode__1\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">在大规模微服务架构下，Prometheus 告警系统往往会陷入一个尴尬的境地：告警太多，运维团队开始选择性忽略；告警太少，真正的故障又可能漏掉。我在某电商平台负责监控体系建设时，团队每天要处理超过 2000 条告警，其中 70% 以上是重复的、关联的或者短暂抖动产生的噪声。\u003C/span>\u003C/p>\u003Cp class=\"js_darkmode__2\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">Recording Rules 是 Prometheus 提供的预计算机制，可以将复杂的查询表达式预先计算并存储为新的时间序列。通过合理设计 Recording Rules，我们不仅能显著降低 PromQL 查询压力，更重要的是可以实现告警聚合、去重、平滑，从根本上减少告警噪声。\u003C/span>\u003C/p>\u003Ch3 class=\"js_darkmode__bg__4\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">1.2 技术特点\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__3\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>预计算优化\u003C/span>\u003Cspan leaf=\"\">：将复杂的聚合查询预先计算，避免告警规则重复计算相同的表达式，降低 Prometheus 负载\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>时间窗口平滑\u003C/span>\u003Cspan leaf=\"\">：通过&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">avg_over_time\u003C/span>\u003C/code>\u003Cspan leaf=\"\">、\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">max_over_time\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;等函数消除瞬时抖动，避免单点毛刺触发告警\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>多维度聚合\u003C/span>\u003Cspan leaf=\"\">：支持按 namespace、service、pod 等维度聚合指标，实现告警收敛\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>层级化告警\u003C/span>\u003Cspan leaf=\"\">：基于 Recording Rules 构建指标层级，实现从基础指标到业务指标的逐层抽象\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 class=\"js_darkmode__bg__5\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">1.3 适用场景\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__4\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 场景一：大规模 Kubernetes 集群监控，Pod 数量超过 1000，原生指标产生的告警风暴需要收敛\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 场景二：微服务架构下，服务间依赖复杂，需要将底层告警聚合为服务级别的健康状态\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 场景三：业务高峰期流量抖动频繁，需要平滑处理避免误告警\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 场景四：多租户环境下，需要按租户/业务线聚合告警，避免一个故障触发上百条告警\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 class=\"js_darkmode__bg__6\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">1.4 环境要求\u003C/span>\u003C/h3>\u003Ctable class=\"js_darkmode__5 layui-table\" style=\"text-align: justify;\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__bg__7\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">组件\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__8\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">版本要求\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__9\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">说明\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd class=\"js_darkmode__6\">\u003Csection>\u003Cspan leaf=\"\">Prometheus\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__7\">\u003Csection>\u003Cspan leaf=\"\">2.28+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__8\">\u003Csection>\u003Cspan leaf=\"\">支持 Recording Rules 分组和 limit 特性\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__9\">\u003Csection>\u003Cspan leaf=\"\">Alertmanager\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__10\">\u003Csection>\u003Cspan leaf=\"\">0.23+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__11\">\u003Csection>\u003Cspan leaf=\"\">配合使用告警抑制和分组功能\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__12\">\u003Csection>\u003Cspan leaf=\"\">Kubernetes\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__13\">\u003Csection>\u003Cspan leaf=\"\">1.21+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__14\">\u003Csection>\u003Cspan leaf=\"\">如果使用 kube-prometheus-stack\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__15\">\u003Csection>\u003Cspan leaf=\"\">内存配置\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__16\">\u003Csection>\u003Cspan leaf=\"\">建议 8GB+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__17\">\u003Csection>\u003Cspan leaf=\"\">Recording Rules 会增加时序存储量\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003Chr class=\"js_darkmode__bg__10 js_darkmode__18\" style=\"text-align: justify;\">\u003Ch2 class=\"js_darkmode__bg__11\" style=\"text-align: center;\">\u003Cspan leaf=\"\">二、详细步骤\u003C/span>\u003C/h2>\u003Ch3 class=\"js_darkmode__bg__12\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">2.1 准备工作\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__13\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.1.1 现状分析\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__19\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">在动手之前，先要搞清楚当前告警噪声的分布。我习惯用下面这个查询来分析过去一周的告警触发情况：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__14 js_darkmode__20\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 查看 Prometheus 配置\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">kubectl get configmap prometheus-server -n monitoring -o yaml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 分析告警触发频次（在 Prometheus UI 执行）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 统计过去7天各告警规则触发次数\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">count_over_time(ALERTS{alertstate=\u003C/span>\u003Cspan leaf=\"\">\"firing\"\u003C/span>\u003Cspan leaf=\"\">}[7d])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 查看当前活跃告警数量\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">count(ALERTS{alertstate=\u003C/span>\u003Cspan leaf=\"\">\"firing\"\u003C/span>\u003Cspan leaf=\"\">})\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__15\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.1.2 识别噪声来源\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__21\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">根据我的经验，告警噪声主要来自以下几类：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__16 js_darkmode__22\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 检查高频告警（每分钟触发超过10次的规则）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 在 Prometheus 执行\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">topk(20, count by (alertname) (count_over_time(ALERTS{alertstate=\u003C/span>\u003Cspan leaf=\"\">\"firing\"\u003C/span>\u003Cspan leaf=\"\">}[1h])))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 检查短暂告警（持续时间小于5分钟的）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 这类告警往往是抖动产生的噪声\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__23\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">通常会发现以下几类高频噪声：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__24\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• CPU/内存使用率瞬时超阈值\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• Pod 重启计数器误报\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 网络延迟抖动\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 磁盘 IO 突增\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 class=\"js_darkmode__bg__17\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">2.2 核心配置\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__18\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.2.1 Recording Rules 基础结构\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__19 js_darkmode__25\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 文件路径：/etc/prometheus/rules/recording_rules.yml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">node_recording_rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">interval:\u003C/span>\u003Cspan leaf=\"\">30s\u003C/span>\u003Cspan leaf=\"\"># 计算间隔，根据需求调整\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 规则定义\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">job:node_cpu_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - avg by (job, instance) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rate(node_cpu_seconds_total{mode=\"idle\"}[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__26\" style=\"text-align: justify;\">\u003Cspan>说明\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">interval\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;参数控制 Recording Rules 的计算频率。设置过小会增加计算压力，过大则可能错过关键变化。一般建议设置为告警评估间隔的一半。\u003C/span>\u003C/p>\u003Ch4 class=\"js_darkmode__bg__20\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.2.2 CPU 使用率平滑处理\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__27\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">这是最常见的噪声来源。原始告警规则可能是这样的：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__21 js_darkmode__28\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 原始告警规则（噪声大）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">HighCPUUsage\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">100\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">(avg\u003C/span>\u003Cspan leaf=\"\">by(instance)\u003C/span>\u003Cspan leaf=\"\">(rate(node_cpu_seconds_total{mode=\"idle\"}[1m]))\u003C/span>\u003Cspan leaf=\"\">*\u003C/span>\u003Cspan leaf=\"\">100\u003C/span>\u003Cspan leaf=\"\">)\u003C/span>\u003Cspan leaf=\"\">&gt;\u003C/span>\u003Cspan leaf=\"\">80\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">1m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__29\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">使用 Recording Rules 优化后：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__22 js_darkmode__30\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># recording_rules.yml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">cpu_smoothing\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">interval:\u003C/span>\u003Cspan leaf=\"\">30s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 第一层：5分钟平均 CPU 使用率\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - avg by (instance) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rate(node_cpu_seconds_total{mode=\"idle\"}[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 第二层：基于5分钟均值的15分钟最大值\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 这样可以捕获持续性高负载，过滤掉短暂峰值\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:max15m_avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; max_over_time(instance:node_cpu_utilization:avg5m[15m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 第三层：按集群聚合的 CPU 使用率\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">cluster:node_cpu_utilization:avg\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; avg(instance:node_cpu_utilization:avg5m)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__31\" style=\"text-align: justify;\">\u003Cspan>参数说明\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__32\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">avg5m\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：使用 5 分钟窗口计算平均值，消除秒级抖动\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">max15m_avg5m\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：在 5 分钟均值基础上取 15 分钟最大值，只有持续性高负载才会触发\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">cluster:\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;前缀：表示集群级别聚合，便于识别层级\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 class=\"js_darkmode__bg__23\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.2.3 内存使用率分层聚合\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__24 js_darkmode__33\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">memory_recording_rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">interval:\u003C/span>\u003Cspan leaf=\"\">30s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 节点级别内存使用率\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_memory_utilization:ratio\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node_memory_MemAvailable_bytes\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / node_memory_MemTotal_bytes\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 应用级别内存使用（Kubernetes 环境）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">namespace_pod:container_memory_usage:sum\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (namespace, pod) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 服务级别内存使用率\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">namespace_service:memory_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; avg by (namespace, service) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; avg_over_time(\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container_memory_working_set_bytes{container!=\"\"}[5m]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) / avg by (namespace, service) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kube_pod_container_resource_limits{resource=\"memory\"}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__25\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.2.4 请求错误率聚合\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__34\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">对于微服务场景，HTTP 错误率告警是另一个噪声重灾区：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__26 js_darkmode__35\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">http_error_rate_rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">interval:\u003C/span>\u003Cspan leaf=\"\">15s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 服务级别错误率（5分钟窗口）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_requests_total:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (namespace, service) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rate(http_requests_total[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_requests_errors:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (namespace, service) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rate(http_requests_total{status=~\"5..\"}[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 错误率计算\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_error_rate:ratio5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; service:http_requests_errors:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / service:http_requests_total:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 加权错误率：流量越大权重越高\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 避免低流量服务的单个错误触发高错误率告警\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_error_rate:weighted5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (service:http_requests_errors:rate5m + 1)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / (service:http_requests_total:rate5m + 10)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch3 class=\"js_darkmode__bg__27\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">2.3 启动和验证\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__28\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.3.1 配置热加载\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__29 js_darkmode__36\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 检查配置语法\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">promtool check rules /etc/prometheus/rules/recording_rules.yml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 热加载 Prometheus 配置\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -X POST http://localhost:9090/-/reload\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 或者发送 SIGHUP 信号\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">kill\u003C/span>\u003Cspan leaf=\"\">&nbsp;-HUP $(pgrep prometheus)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__30\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 2.3.2 验证 Recording Rules 生效\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__31 js_darkmode__37\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 在 Prometheus UI 查询新生成的指标\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 应该能看到数据\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 检查 Recording Rules 状态\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">curl -s http://localhost:9090/api/v1/rules | jq&nbsp;\u003C/span>\u003Cspan leaf=\"\">'.data.groups[] | select(.name==\"cpu_smoothing\")'\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 预期输出应显示规则状态为 \"health\": \"ok\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__32 js_darkmode__38\" style=\"text-align: justify;\">\u003Ch2 class=\"js_darkmode__bg__33\" style=\"text-align: center;\">\u003Cspan leaf=\"\">三、示例代码和配置\u003C/span>\u003C/h2>\u003Ch3 class=\"js_darkmode__bg__34\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">3.1 完整配置示例\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__35\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 3.1.1 完整的 Recording Rules 配置\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__36 js_darkmode__39\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 文件路径：/etc/prometheus/rules/recording_rules.yml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># ============ 基础设施层 ============\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">infrastructure_recording_rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">interval:\u003C/span>\u003Cspan leaf=\"\">30s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># CPU\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">1\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">avg\u003C/span>\u003Cspan leaf=\"\">by\u003C/span>\u003Cspan leaf=\"\">(instance)\u003C/span>\u003Cspan leaf=\"\">(rate(node_cpu_seconds_total{mode=\"idle\"}[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:max_avg5m_over_15m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">max_over_time(instance:node_cpu_utilization:avg5m[15m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Memory\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_memory_utilization:ratio\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">1\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">(node_memory_MemAvailable_bytes\u003C/span>\u003Cspan leaf=\"\">/\u003C/span>\u003Cspan leaf=\"\">node_memory_MemTotal_bytes)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_memory_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">avg_over_time(instance:node_memory_utilization:ratio[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Disk\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_disk_utilization:ratio\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node_filesystem_avail_bytes{fstype=~\"ext4|xfs\"}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / node_filesystem_size_bytes{fstype=~\"ext4|xfs\"}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Network\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_network_receive:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">sum\u003C/span>\u003Cspan leaf=\"\">by\u003C/span>\u003Cspan leaf=\"\">(instance)\u003C/span>\u003Cspan leaf=\"\">(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|br.*\"}[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_network_transmit:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">sum\u003C/span>\u003Cspan leaf=\"\">by\u003C/span>\u003Cspan leaf=\"\">(instance)\u003C/span>\u003Cspan leaf=\"\">(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|br.*\"}[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># ============ Kubernetes 层 ============\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">kubernetes_recording_rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">interval:\u003C/span>\u003Cspan leaf=\"\">30s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Pod 资源使用聚合到 namespace\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">namespace:container_cpu_usage:sum\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (namespace) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\"}[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">namespace:container_memory_usage:sum\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (namespace) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Pod 重启率（1小时窗口，避免单次重启告警）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">namespace_pod:container_restarts:increase1h\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; increase(kube_pod_container_status_restarts_total[1h])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Deployment 可用性\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">namespace_deployment:replicas_unavailable:ratio\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kube_deployment_status_replicas_unavailable\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / kube_deployment_spec_replicas\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># ============ 应用层 ============\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">application_recording_rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">interval:\u003C/span>\u003Cspan leaf=\"\">15s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># HTTP 请求速率\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_requests:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">sum\u003C/span>\u003Cspan leaf=\"\">by\u003C/span>\u003Cspan leaf=\"\">(namespace,\u003C/span>\u003Cspan leaf=\"\">service,\u003C/span>\u003Cspan leaf=\"\">method)\u003C/span>\u003Cspan leaf=\"\">(rate(http_requests_total[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># HTTP 错误率\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_errors:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">sum\u003C/span>\u003Cspan leaf=\"\">by\u003C/span>\u003Cspan leaf=\"\">(namespace,\u003C/span>\u003Cspan leaf=\"\">service)\u003C/span>\u003Cspan leaf=\"\">(rate(http_requests_total{status=~\"5..\"}[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># HTTP P99 延迟\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_latency_p99:5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; histogram_quantile(0.99,\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (namespace, service, le) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rate(http_request_duration_seconds_bucket[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 服务健康评分（综合指标）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:health_score:5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - clamp_max(service:http_errors:rate5m / service:http_requests:rate5m, 1)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) * 0.4\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - clamp_max(service:http_latency_p99:5m / 2, 1)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) * 0.3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clamp_max(service:http_requests:rate5m / 100, 1)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) * 0.3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__37\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 3.1.2 基于 Recording Rules 的告警规则\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__38 js_darkmode__40\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 文件路径：/etc/prometheus/rules/alert_rules.yml\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">infrastructure_alerts\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 使用预计算指标，更稳定\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">NodeHighCPU\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:max_avg5m_over_15m\u003C/span>\u003Cspan leaf=\"\">&gt;\u003C/span>\u003Cspan leaf=\"\">0.85\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">labels:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">severity:\u003C/span>\u003Cspan leaf=\"\">warning\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">annotations:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">summary:\u003C/span>\u003Cspan leaf=\"\">\"节点&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $labels.instance }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;CPU 持续高负载\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">description:\u003C/span>\u003Cspan leaf=\"\">\"15分钟内 CPU 使用率峰值超过 85%，当前值&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $value | humanizePercentage }}\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">NodeHighMemory\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">instance:node_memory_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">&gt;\u003C/span>\u003Cspan leaf=\"\">0.9\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">10m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">labels:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">severity:\u003C/span>\u003Cspan leaf=\"\">warning\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">annotations:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">summary:\u003C/span>\u003Cspan leaf=\"\">\"节点&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $labels.instance }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;内存使用率过高\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">description:\u003C/span>\u003Cspan leaf=\"\">\"内存使用率持续超过 90%\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">application_alerts\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 基于聚合指标的服务健康告警\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">ServiceUnhealthy\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">service:health_score:5m\u003C/span>\u003Cspan leaf=\"\">&lt;\u003C/span>\u003Cspan leaf=\"\">0.6\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">labels:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">severity:\u003C/span>\u003Cspan leaf=\"\">critical\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">annotations:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">summary:\u003C/span>\u003Cspan leaf=\"\">\"服务&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $labels.namespace }}\u003C/span>\u003Cspan leaf=\"\">/\u003C/span>\u003Cspan leaf=\"\">{{ $labels.service }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;健康状态异常\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">description:\u003C/span>\u003Cspan leaf=\"\">\"服务健康评分低于 0.6，当前值&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $value }}\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># Pod 频繁重启（使用1小时窗口）\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">PodFrequentRestart\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">namespace_pod:container_restarts:increase1h\u003C/span>\u003Cspan leaf=\"\">&gt;\u003C/span>\u003Cspan leaf=\"\">3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">0m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">labels:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">severity:\u003C/span>\u003Cspan leaf=\"\">warning\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">annotations:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">summary:\u003C/span>\u003Cspan leaf=\"\">\"Pod&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $labels.namespace }}\u003C/span>\u003Cspan leaf=\"\">/\u003C/span>\u003Cspan leaf=\"\">{{ $labels.pod }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;频繁重启\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">description:\u003C/span>\u003Cspan leaf=\"\">\"过去1小时重启&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $value }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;次\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch3 class=\"js_darkmode__bg__39\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">3.2 实际应用案例\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__40\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 案例一：电商大促告警收敛\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__41\" style=\"text-align: justify;\">\u003Cspan>场景描述\u003C/span>\u003Cspan leaf=\"\">：双11大促期间，订单服务 QPS 从日常 1000 飙升到 50000，原有的错误率告警（错误数/总请求数 &gt; 1%）频繁触发，因为即使错误率只有 0.5%，绝对错误数也达到了 250/秒。\u003C/span>\u003C/p>\u003Cp class=\"js_darkmode__42\" style=\"text-align: justify;\">\u003Cspan>实现代码\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__41 js_darkmode__43\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># Recording Rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">ecommerce_rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 动态基线：使用过去1小时的错误率作为基线\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_error_rate:baseline1h\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; avg_over_time(\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (service) (rate(http_requests_total{status=~\"5..\"}[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / sum by (service) (rate(http_requests_total[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )[1h:]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 当前错误率与基线的比值\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:http_error_rate:ratio_to_baseline\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (service) (rate(http_requests_total{status=~\"5..\"}[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / sum by (service) (rate(http_requests_total[5m]))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / service:http_error_rate:baseline1h\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 告警规则\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">alert:\u003C/span>\u003Cspan leaf=\"\">ServiceErrorRateSpike\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">service:http_error_rate:ratio_to_baseline\u003C/span>\u003Cspan leaf=\"\">&gt;\u003C/span>\u003Cspan leaf=\"\">3\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">for:\u003C/span>\u003Cspan leaf=\"\">5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">annotations:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">summary:\u003C/span>\u003Cspan leaf=\"\">\"服务&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $labels.service }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;错误率异常飙升\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">description:\u003C/span>\u003Cspan leaf=\"\">\"当前错误率是基线的&nbsp;\u003C/span>\u003Cspan leaf=\"\">{{ $value | humanize }}\u003C/span>\u003Cspan leaf=\"\">&nbsp;倍\"\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__44\" style=\"text-align: justify;\">\u003Cspan>运行结果\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__42 js_darkmode__45\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\">大促期间告警数量对比：\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">- 优化前：每小时平均 150+ 条告警\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">- 优化后：每小时平均 5-10 条告警\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">- 误告警率：从 85% 降低到 15%\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__43\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 案例二：多租户环境告警聚合\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__46\" style=\"text-align: justify;\">\u003Cspan>场景描述\u003C/span>\u003Cspan leaf=\"\">：SaaS 平台有 200+ 租户，每个租户有独立的命名空间。当某个底层节点故障时，原有配置会触发 200+ 条 Pod 不可用告警。\u003C/span>\u003C/p>\u003Cp class=\"js_darkmode__47\" style=\"text-align: justify;\">\u003Cspan>实现步骤\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__48\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">1. 创建租户级别的聚合指标\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">2. 实现告警收敛，只告警受影响的节点，附带影响的租户列表\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">3. 配合 Alertmanager 的 group_by 实现进一步收敛\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre class=\"js_darkmode__bg__44 js_darkmode__49\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># Recording Rules\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">groups:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">name:\u003C/span>\u003Cspan leaf=\"\">tenant_aggregation\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 按租户聚合不可用 Pod 数量\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">tenant:pods_unavailable:count\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count by (tenant) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kube_pod_status_phase{phase!=\"Running\", phase!=\"Succeeded\"}\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 租户服务可用性\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">tenant:service_availability:ratio\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum by (tenant) (kube_deployment_status_replicas_available)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / sum by (tenant) (kube_deployment_spec_replicas)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 故障影响范围\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">node:affected_tenants:count\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count by (node) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count by (node, tenant) (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kube_pod_info * on(pod, namespace) group_left(tenant)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kube_namespace_labels\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__bg__45 js_darkmode__50\" style=\"text-align: justify;\">\u003Ch2 class=\"js_darkmode__bg__46\" style=\"text-align: center;\">\u003Cspan leaf=\"\">四、最佳实践和注意事项\u003C/span>\u003C/h2>\u003Ch3 class=\"js_darkmode__bg__47\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">4.1 最佳实践\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__48\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 4.1.1 Recording Rules 命名规范\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__51\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">遵循一致的命名规范对于维护大规模 Recording Rules 至关重要：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__bg__49 js_darkmode__52\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 命名格式：level:metric_name:aggregation_window\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># level: 聚合级别，如 instance, namespace, cluster\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># metric_name: 指标名称\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># aggregation_window: 时间窗口和聚合方式\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 好的命名示例\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">namespace:container_memory:\u003C/span>\u003Cspan leaf=\"\">sum\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">cluster:http_requests:rate15m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 避免的命名方式\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">cpu_high &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan leaf=\"\"># 缺少层级和时间窗口信息\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">recording_rule_1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan leaf=\"\"># 无意义的名称\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__50\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 4.1.2 分层设计\u003C/span>\u003C/h4>\u003Cpre class=\"js_darkmode__bg__51 js_darkmode__53\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># 三层架构设计\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 第一层：原始指标清洗和标准化\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_seconds:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">rate(node_cpu_seconds_total[5m])\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 第二层：指标聚合\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">instance:node_cpu_utilization:avg5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">1\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">avg\u003C/span>\u003Cspan leaf=\"\">by\u003C/span>\u003Cspan leaf=\"\">(instance)\u003C/span>\u003Cspan leaf=\"\">(instance:node_cpu_seconds:rate5m{mode=\"idle\"})\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 第三层：业务指标\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">service:availability:ratio\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">|\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; (\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; sum(instance:node_cpu_utilization:avg5m &lt; 0.9)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; / count(instance:node_cpu_utilization:avg5m)\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; )\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch4 class=\"js_darkmode__bg__52\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 4.1.3 性能优化\u003C/span>\u003C/h4>\u003Cul class=\"list-paddingleft-1 js_darkmode__54\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>控制 Recording Rules 数量\u003C/span>\u003Cspan leaf=\"\">：每增加一条规则，就会产生新的时间序列\u003C/span>\u003Cpre class=\"js_darkmode__bg__53 js_darkmode__55\">\u003Ccode>\u003Cspan leaf=\"\"># 检查 Recording Rules 产生的时序数量\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">prometheus_tsdb_head_series\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 建议：单个 Prometheus 实例的 Recording Rules 产生的时序不超过总时序的 20%\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>合理设置 interval\u003C/span>\u003Cspan leaf=\"\">：根据指标变化频率设置\u003C/span>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__56\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 基础设施指标：30s\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 应用指标：15s\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 业务指标：60s\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>使用 limit 防止基数爆炸\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003Cpre class=\"js_darkmode__bg__54 js_darkmode__57\">\u003Ccode>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">record:\u003C/span>\u003Cspan leaf=\"\">topk_services:http_requests:rate5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">expr:\u003C/span>\u003Cspan leaf=\"\">topk(100,\u003C/span>\u003Cspan leaf=\"\">sum\u003C/span>\u003Cspan leaf=\"\">by\u003C/span>\u003Cspan leaf=\"\">(service)\u003C/span>\u003Cspan leaf=\"\">(rate(http_requests_total[5m])))\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 class=\"js_darkmode__bg__55\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 4.1.4 高可用配置\u003C/span>\u003C/h4>\u003Cul class=\"list-paddingleft-1 js_darkmode__58\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>多副本一致性\u003C/span>\u003Cspan leaf=\"\">：Recording Rules 在多个 Prometheus 副本上执行，确保配置完全相同\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>告警去重\u003C/span>\u003Cspan leaf=\"\">：配合 Alertmanager 的&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">group_by\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;和&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">inhibit_rules\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;进一步去重\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>联邦集群\u003C/span>\u003Cspan leaf=\"\">：在联邦架构中，Recording Rules 应该在被采集端执行，减少联邦查询压力\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cpre class=\"js_darkmode__bg__56 js_darkmode__59\" style=\"text-align: justify;\">\u003Ccode>\u003Cspan leaf=\"\"># Alertmanager 配置配合\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">route:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">group_by:\u003C/span>\u003Cspan leaf=\"\">&nbsp;[\u003C/span>\u003Cspan leaf=\"\">'alertname'\u003C/span>\u003Cspan leaf=\"\">,&nbsp;\u003C/span>\u003Cspan leaf=\"\">'cluster'\u003C/span>\u003Cspan leaf=\"\">,&nbsp;\u003C/span>\u003Cspan leaf=\"\">'service'\u003C/span>\u003Cspan leaf=\"\">]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">group_wait:\u003C/span>\u003Cspan leaf=\"\">30s\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">group_interval:\u003C/span>\u003Cspan leaf=\"\">5m\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">repeat_interval:\u003C/span>\u003Cspan leaf=\"\">4h\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">inhibit_rules:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\"># 节点故障时抑制该节点上的所有 Pod 告警\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan leaf=\"\">source_match:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">alertname:\u003C/span>\u003Cspan leaf=\"\">NodeDown\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">target_match_re:\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">alertname:\u003C/span>\u003Cspan leaf=\"\">Pod.*\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">equal:\u003C/span>\u003Cspan leaf=\"\">&nbsp;[\u003C/span>\u003Cspan leaf=\"\">'node'\u003C/span>\u003Cspan leaf=\"\">]\u003C/span>\u003Cspan leaf=\"\">\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch3 class=\"js_darkmode__bg__57\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">4.2 注意事项\u003C/span>\u003C/h3>\u003Ch4 class=\"js_darkmode__bg__58\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 4.2.1 配置注意事项\u003C/span>\u003C/h4>\u003Cp class=\"js_darkmode__60\" style=\"text-align: justify;\">\u003Cspan>警告\u003C/span>\u003Cspan leaf=\"\">：Recording Rules 配置错误可能导致 Prometheus 无法启动或产生错误数据\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__61\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 注意事项一：Recording Rules 的&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">record\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;字段必须是合法的指标名称，不能包含特殊字符\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 注意事项二：避免 Recording Rules 之间的循环依赖，虽然 Prometheus 会检测，但可能导致计算延迟\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">• 注意事项三：修改已有 Recording Rules 的表达式时，注意下游依赖的告警规则可能需要同步调整阈值\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 class=\"js_darkmode__bg__59\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 4.2.2 常见错误\u003C/span>\u003C/h4>\u003Ctable class=\"js_darkmode__62 layui-table\" style=\"text-align: justify;\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__bg__60\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">错误现象\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__61\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">原因分析\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__bg__62\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">解决方案\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd class=\"js_darkmode__63\">\u003Csection>\u003Cspan leaf=\"\">Recording Rule 显示 health: unknown\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__64\">\u003Csection>\u003Cspan leaf=\"\">表达式语法错误或引用的指标不存在\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__65\">\u003Csection>\u003Cspan leaf=\"\">使用 promtool check rules 验证语法，确认源指标存在\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__66\">\u003Csection>\u003Cspan leaf=\"\">新指标无数据\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__67\">\u003Csection>\u003Cspan leaf=\"\">interval 设置过长或表达式结果为空\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__68\">\u003Csection>\u003Cspan leaf=\"\">检查 interval 配置，在 Prometheus UI 测试表达式\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__69\">\u003Csection>\u003Cspan leaf=\"\">Prometheus OOM\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__70\">\u003Csection>\u003Cspan leaf=\"\">Recording Rules 产生的时序过多\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__71\">\u003Csection>\u003Cspan leaf=\"\">添加 limit、优化标签基数、增加内存\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd class=\"js_darkmode__72\">\u003Csection>\u003Cspan leaf=\"\">告警延迟增加\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__73\">\u003Csection>\u003Cspan leaf=\"\">Recording Rules 计算压力过大\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__74\">\u003Csection>\u003Cspan leaf=\"\">减少规则数量、增大 interval、升级硬件\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003Ch4 class=\"js_darkmode__bg__63\" style=\"text-align: justify;\">\u003Cspan leaf=\"\">◆ 4.2.3 兼容性问题\u003C/span>\u003C/h4>\u003Cul class=\"list-paddingleft-1 js_darkmode__75\" style=\"text-align: justify;\">\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>版本兼容\u003C/span>\u003Cspan leaf=\"\">：\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">limit\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;功能需要 Prometheus 2.28+，低版本需要在表达式中使用&nbsp;\u003C/span>\u003Ccode>\u003Cspan leaf=\"\">topk\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;替代\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>平台兼容\u003C/span>\u003Cspan leaf=\"\">：使用 Prometheus Operator 时，Recording Rules 需要通过 PrometheusRule CRD 管理\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection>\u003Cspan leaf=\"\">•&nbsp;\u003C/span>\u003Cspan>组件依赖\u003C/span>\u003Cspan leaf=\"\">：Recording Rules 依赖的源指标（如 node_exporter、kube-state-metrics）版本变更可能导致表达式失效\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Chr class=\"js_darkmode__bg__64 js_darkmode__76\" style=\"text-align: justify;\">\u003Ch2 class=\"js_darkmode__bg__65\" style=\"text-align: center;\">\u003Cbr>\u003C/h2>","## 一、概述\n\n### 1.1 背景介绍\n\n在大规模微服务架构下，Prometheus 告警系统往往会陷入一个尴尬的境地：告警太多，运维团队开始选择性忽略；告警太少，真正的故障又可能漏掉。我在某电商平台负责监控体系建设时，团队每天要处理超过 2000 条告警，其中 70% 以上是重复的、关联的或者短暂抖动产生的噪声。\n\nRecording Rules 是 Prometheus 提供的预计算机制，可以将复杂的查询表达式预先计算并存储为新的时间序列。通过合理设计 Recording Rules，我们不仅能显著降低 PromQL 查询压力，更重要的是可以实现告警聚合、去重、平滑，从根本上减少告警噪声。\n\n### 1.2 技术特点\n\n- • 预计算优化：将复杂的聚合查询预先计算，避免告警规则重复计算相同的表达式，降低 Prometheus 负载\n- • 时间窗口平滑：通过 avg_over_time、max_over_time 等函数消除瞬时抖动，避免单点毛刺触发告警\n- • 多维度聚合：支持按 namespace、service、pod 等维度聚合指标，实现告警收敛\n- • 层级化告警：基于 Recording Rules 构建指标层级，实现从基础指标到业务指标的逐层抽象\n\n### 1.3 适用场景\n\n- • 场景一：大规模 Kubernetes 集群监控，Pod 数量超过 1000，原生指标产生的告警风暴需要收敛\n- • 场景二：微服务架构下，服务间依赖复杂，需要将底层告警聚合为服务级别的健康状态\n- • 场景三：业务高峰期流量抖动频繁，需要平滑处理避免误告警\n- • 场景四：多租户环境下，需要按租户/业务线聚合告警，避免一个故障触发上百条告警\n\n### 1.4 环境要求\n\n组件\n\n版本要求\n\n说明\n\nPrometheus\n\n2.28+\n\n支持 Recording Rules 分组和 limit 特性\n\nAlertmanager\n\n0.23+\n\n配合使用告警抑制和分组功能\n\nKubernetes\n\n1.21+\n\n如果使用 kube-prometheus-stack\n\n内存配置\n\n建议 8GB+\n\nRecording Rules 会增加时序存储量\n\n---\n\n## 二、详细步骤\n\n### 2.1 准备工作\n\n#### ◆ 2.1.1 现状分析\n\n在动手之前，先要搞清楚当前告警噪声的分布。我习惯用下面这个查询来分析过去一周的告警触发情况：\n\n```\n# 查看 Prometheus 配置kubectl get configmap prometheus-server -n monitoring -o yaml# 分析告警触发频次（在 Prometheus UI 执行）# 统计过去7天各告警规则触发次数count_over_time(ALERTS{alertstate=\"firing\"}[7d])# 查看当前活跃告警数量count(ALERTS{alertstate=\"firing\"})\n```\n\n#### ◆ 2.1.2 识别噪声来源\n\n根据我的经验，告警噪声主要来自以下几类：\n\n```\n# 检查高频告警（每分钟触发超过10次的规则）# 在 Prometheus 执行topk(20, count by (alertname) (count_over_time(ALERTS{alertstate=\"firing\"}[1h])))# 检查短暂告警（持续时间小于5分钟的）# 这类告警往往是抖动产生的噪声\n```\n\n通常会发现以下几类高频噪声：\n\n- • CPU/内存使用率瞬时超阈值\n- • Pod 重启计数器误报\n- • 网络延迟抖动\n- • 磁盘 IO 突增\n\n### 2.2 核心配置\n\n#### ◆ 2.2.1 Recording Rules 基础结构\n\n```\n# 文件路径：/etc/prometheus/rules/recording_rules.ymlgroups:-name:node_recording_rulesinterval:30s# 计算间隔，根据需求调整rules:# 规则定义-record:job:node_cpu_utilization:avg5mexpr:|          1 - avg by (job, instance) (            rate(node_cpu_seconds_total{mode=\"idle\"}[5m])          )\n```\n\n说明\n\n：\n`\ninterval\n`\n 参数控制 Recording Rules 的计算频率。设置过小会增加计算压力，过大则可能错过关键变化。一般建议设置为告警评估间隔的一半。\n\n#### ◆ 2.2.2 CPU 使用率平滑处理\n\n这是最常见的噪声来源。原始告警规则可能是这样的：\n\n```\n# 原始告警规则（噪声大）-alert:HighCPUUsageexpr:100-(avgby(instance)(rate(node_cpu_seconds_total{mode=\"idle\"}[1m]))*100)>80for:1m\n```\n\n使用 Recording Rules 优化后：\n\n```\n# recording_rules.ymlgroups:-name:cpu_smoothinginterval:30srules:# 第一层：5分钟平均 CPU 使用率-record:instance:node_cpu_utilization:avg5mexpr:|          1 - avg by (instance) (            rate(node_cpu_seconds_total{mode=\"idle\"}[5m])          )# 第二层：基于5分钟均值的15分钟最大值# 这样可以捕获持续性高负载，过滤掉短暂峰值-record:instance:node_cpu_utilization:max15m_avg5mexpr:|          max_over_time(instance:node_cpu_utilization:avg5m[15m])# 第三层：按集群聚合的 CPU 使用率-record:cluster:node_cpu_utilization:avgexpr:|          avg(instance:node_cpu_utilization:avg5m)\n```\n\n参数说明\n\n：\n\n- • avg5m：使用 5 分钟窗口计算平均值，消除秒级抖动\n- • max15m_avg5m：在 5 分钟均值基础上取 15 分钟最大值，只有持续性高负载才会触发\n- • cluster: 前缀：表示集群级别聚合，便于识别层级\n\n#### ◆ 2.2.3 内存使用率分层聚合\n\n```\ngroups:-name:memory_recording_rulesinterval:30srules:# 节点级别内存使用率-record:instance:node_memory_utilization:ratioexpr:|          1 - (            node_memory_MemAvailable_bytes            / node_memory_MemTotal_bytes          )# 应用级别内存使用（Kubernetes 环境）-record:namespace_pod:container_memory_usage:sumexpr:|          sum by (namespace, pod) (            container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}          )# 服务级别内存使用率-record:namespace_service:memory_utilization:avg5mexpr:|          avg by (namespace, service) (            avg_over_time(              container_memory_working_set_bytes{container!=\"\"}[5m]            )          ) / avg by (namespace, service) (            kube_pod_container_resource_limits{resource=\"memory\"}          )\n```\n\n#### ◆ 2.2.4 请求错误率聚合\n\n对于微服务场景，HTTP 错误率告警是另一个噪声重灾区：\n\n```\ngroups:-name:http_error_rate_rulesinterval:15srules:# 服务级别错误率（5分钟窗口）-record:service:http_requests_total:rate5mexpr:|          sum by (namespace, service) (            rate(http_requests_total[5m])          )-record:service:http_requests_errors:rate5mexpr:|          sum by (namespace, service) (            rate(http_requests_total{status=~\"5..\"}[5m])          )# 错误率计算-record:service:http_error_rate:ratio5mexpr:|          service:http_requests_errors:rate5m          / service:http_requests_total:rate5m# 加权错误率：流量越大权重越高# 避免低流量服务的单个错误触发高错误率告警-record:service:http_error_rate:weighted5mexpr:|          (service:http_requests_errors:rate5m + 1)          / (service:http_requests_total:rate5m + 10)\n```\n\n### 2.3 启动和验证\n\n#### ◆ 2.3.1 配置热加载\n\n```\n# 检查配置语法promtool check rules /etc/prometheus/rules/recording_rules.yml# 热加载 Prometheus 配置curl -X POST http://localhost:9090/-/reload# 或者发送 SIGHUP 信号kill -HUP $(pgrep prometheus)\n```\n\n#### ◆ 2.3.2 验证 Recording Rules 生效\n\n```\n# 在 Prometheus UI 查询新生成的指标# 应该能看到数据instance:node_cpu_utilization:avg5m# 检查 Recording Rules 状态curl -s http://localhost:9090/api/v1/rules | jq '.data.groups[] | select(.name==\"cpu_smoothing\")'# 预期输出应显示规则状态为 \"health\": \"ok\"\n```\n\n---\n\n## 三、示例代码和配置\n\n### 3.1 完整配置示例\n\n#### ◆ 3.1.1 完整的 Recording Rules 配置\n\n```\n# 文件路径：/etc/prometheus/rules/recording_rules.ymlgroups:# ============ 基础设施层 ============-name:infrastructure_recording_rulesinterval:30srules:# CPU-record:instance:node_cpu_utilization:avg5mexpr:1-avgby(instance)(rate(node_cpu_seconds_total{mode=\"idle\"}[5m]))-record:instance:node_cpu_utilization:max_avg5m_over_15mexpr:max_over_time(instance:node_cpu_utilization:avg5m[15m])# Memory-record:instance:node_memory_utilization:ratioexpr:1-(node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes)-record:instance:node_memory_utilization:avg5mexpr:avg_over_time(instance:node_memory_utilization:ratio[5m])# Disk-record:instance:node_disk_utilization:ratioexpr:|          1 - (            node_filesystem_avail_bytes{fstype=~\"ext4|xfs\"}            / node_filesystem_size_bytes{fstype=~\"ext4|xfs\"}          )# Network-record:instance:node_network_receive:rate5mexpr:sumby(instance)(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|br.*\"}[5m]))-record:instance:node_network_transmit:rate5mexpr:sumby(instance)(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|br.*\"}[5m]))# ============ Kubernetes 层 ============-name:kubernetes_recording_rulesinterval:30srules:# Pod 资源使用聚合到 namespace-record:namespace:container_cpu_usage:sumexpr:|          sum by (namespace) (            rate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\"}[5m])          )-record:namespace:container_memory_usage:sumexpr:|          sum by (namespace) (            container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}          )# Pod 重启率（1小时窗口，避免单次重启告警）-record:namespace_pod:container_restarts:increase1hexpr:|          increase(kube_pod_container_status_restarts_total[1h])# Deployment 可用性-record:namespace_deployment:replicas_unavailable:ratioexpr:|          kube_deployment_status_replicas_unavailable          / kube_deployment_spec_replicas# ============ 应用层 ============-name:application_recording_rulesinterval:15srules:# HTTP 请求速率-record:service:http_requests:rate5mexpr:sumby(namespace,service,method)(rate(http_requests_total[5m]))# HTTP 错误率-record:service:http_errors:rate5mexpr:sumby(namespace,service)(rate(http_requests_total{status=~\"5..\"}[5m]))# HTTP P99 延迟-record:service:http_latency_p99:5mexpr:|          histogram_quantile(0.99,            sum by (namespace, service, le) (              rate(http_request_duration_seconds_bucket[5m])            )          )# 服务健康评分（综合指标）-record:service:health_score:5mexpr:|          (            1 - clamp_max(service:http_errors:rate5m / service:http_requests:rate5m, 1)          ) * 0.4          +          (            1 - clamp_max(service:http_latency_p99:5m / 2, 1)          ) * 0.3          +          (            clamp_max(service:http_requests:rate5m / 100, 1)          ) * 0.3\n```\n\n#### ◆ 3.1.2 基于 Recording Rules 的告警规则\n\n```\n# 文件路径：/etc/prometheus/rules/alert_rules.ymlgroups:-name:infrastructure_alertsrules:# 使用预计算指标，更稳定-alert:NodeHighCPUexpr:instance:node_cpu_utilization:max_avg5m_over_15m>0.85for:5mlabels:severity:warningannotations:summary:\"节点 {{ $labels.instance }} CPU 持续高负载\"description:\"15分钟内 CPU 使用率峰值超过 85%，当前值 {{ $value | humanizePercentage }}\"-alert:NodeHighMemoryexpr:instance:node_memory_utilization:avg5m>0.9for:10mlabels:severity:warningannotations:summary:\"节点 {{ $labels.instance }} 内存使用率过高\"description:\"内存使用率持续超过 90%\"-name:application_alertsrules:# 基于聚合指标的服务健康告警-alert:ServiceUnhealthyexpr:service:health_score:5m3for:0mlabels:severity:warningannotations:summary:\"Pod {{ $labels.namespace }}/{{ $labels.pod }} 频繁重启\"description:\"过去1小时重启 {{ $value }} 次\"\n```\n\n### 3.2 实际应用案例\n\n#### ◆ 案例一：电商大促告警收敛\n\n场景描述\n\n：双11大促期间，订单服务 QPS 从日常 1000 飙升到 50000，原有的错误率告警（错误数/总请求数 > 1%）频繁触发，因为即使错误率只有 0.5%，绝对错误数也达到了 250/秒。\n\n实现代码\n\n：\n\n```\n# Recording Rulesgroups:-name:ecommerce_rulesrules:# 动态基线：使用过去1小时的错误率作为基线-record:service:http_error_rate:baseline1hexpr:|          avg_over_time(            (              sum by (service) (rate(http_requests_total{status=~\"5..\"}[5m]))              / sum by (service) (rate(http_requests_total[5m]))            )[1h:]          )# 当前错误率与基线的比值-record:service:http_error_rate:ratio_to_baselineexpr:|          (            sum by (service) (rate(http_requests_total{status=~\"5..\"}[5m]))            / sum by (service) (rate(http_requests_total[5m]))          )          / service:http_error_rate:baseline1h# 告警规则-alert:ServiceErrorRateSpikeexpr:service:http_error_rate:ratio_to_baseline>3for:5mannotations:summary:\"服务 {{ $labels.service }} 错误率异常飙升\"description:\"当前错误率是基线的 {{ $value | humanize }} 倍\"\n```\n\n运行结果\n\n：\n\n```\n大促期间告警数量对比：- 优化前：每小时平均 150+ 条告警- 优化后：每小时平均 5-10 条告警- 误告警率：从 85% 降低到 15%\n```\n\n#### ◆ 案例二：多租户环境告警聚合\n\n场景描述\n\n：SaaS 平台有 200+ 租户，每个租户有独立的命名空间。当某个底层节点故障时，原有配置会触发 200+ 条 Pod 不可用告警。\n\n实现步骤\n\n：\n\n1. 1. 创建租户级别的聚合指标\n2. 2. 实现告警收敛，只告警受影响的节点，附带影响的租户列表\n3. 3. 配合 Alertmanager 的 group_by 实现进一步收敛\n\n```\n# Recording Rulesgroups:-name:tenant_aggregationrules:# 按租户聚合不可用 Pod 数量-record:tenant:pods_unavailable:countexpr:|          count by (tenant) (            kube_pod_status_phase{phase!=\"Running\", phase!=\"Succeeded\"}          )# 租户服务可用性-record:tenant:service_availability:ratioexpr:|          sum by (tenant) (kube_deployment_status_replicas_available)          / sum by (tenant) (kube_deployment_spec_replicas)# 故障影响范围-record:node:affected_tenants:countexpr:|          count by (node) (            count by (node, tenant) (              kube_pod_info * on(pod, namespace) group_left(tenant)              kube_namespace_labels            )          )\n```\n\n---\n\n## 四、最佳实践和注意事项\n\n### 4.1 最佳实践\n\n#### ◆ 4.1.1 Recording Rules 命名规范\n\n遵循一致的命名规范对于维护大规模 Recording Rules 至关重要：\n\n```\n# 命名格式：level:metric_name:aggregation_window# level: 聚合级别，如 instance, namespace, cluster# metric_name: 指标名称# aggregation_window: 时间窗口和聚合方式# 好的命名示例instance:node_cpu_utilization:avg5mnamespace:container_memory:sumcluster:http_requests:rate15m# 避免的命名方式cpu_high                    # 缺少层级和时间窗口信息recording_rule_1            # 无意义的名称\n```\n\n#### ◆ 4.1.2 分层设计\n\n```\n# 三层架构设计# 第一层：原始指标清洗和标准化-record:instance:node_cpu_seconds:rate5mexpr:rate(node_cpu_seconds_total[5m])# 第二层：指标聚合-record:instance:node_cpu_utilization:avg5mexpr:1-avgby(instance)(instance:node_cpu_seconds:rate5m{mode=\"idle\"})# 第三层：业务指标-record:service:availability:ratioexpr:|    (      sum(instance:node_cpu_utilization:avg5m \u003C 0.9)      / count(instance:node_cpu_utilization:avg5m)    )\n```\n\n#### ◆ 4.1.3 性能优化\n\n- • 控制 Recording Rules 数量：每增加一条规则，就会产生新的时间序列\n```\n# 检查 Recording Rules 产生的时序数量prometheus_tsdb_head_series# 建议：单个 Prometheus 实例的 Recording Rules 产生的时序不超过总时序的 20%\n```\n- • 合理设置 interval：根据指标变化频率设置\n- • 基础设施指标：30s\n- • 应用指标：15s\n- • 业务指标：60s\n\n• \n\n使用 limit 防止基数爆炸\n\n：\n\n```\n-record:topk_services:http_requests:rate5mexpr:topk(100,sumby(service)(rate(http_requests_total[5m])))\n```\n\n#### ◆ 4.1.4 高可用配置\n\n- • 多副本一致性：Recording Rules 在多个 Prometheus 副本上执行，确保配置完全相同\n- • 告警去重：配合 Alertmanager 的 group_by 和 inhibit_rules 进一步去重\n- • 联邦集群：在联邦架构中，Recording Rules 应该在被采集端执行，减少联邦查询压力\n\n```\n# Alertmanager 配置配合route:group_by: ['alertname', 'cluster', 'service']group_wait:30sgroup_interval:5mrepeat_interval:4hinhibit_rules:# 节点故障时抑制该节点上的所有 Pod 告警-source_match:alertname:NodeDowntarget_match_re:alertname:Pod.*equal: ['node']\n```\n\n### 4.2 注意事项\n\n#### ◆ 4.2.1 配置注意事项\n\n警告\n\n：Recording Rules 配置错误可能导致 Prometheus 无法启动或产生错误数据\n\n- • 注意事项一：Recording Rules 的 record 字段必须是合法的指标名称，不能包含特殊字符\n- • 注意事项二：避免 Recording Rules 之间的循环依赖，虽然 Prometheus 会检测，但可能导致计算延迟\n- • 注意事项三：修改已有 Recording Rules 的表达式时，注意下游依赖的告警规则可能需要同步调整阈值\n\n#### ◆ 4.2.2 常见错误\n\n错误现象\n\n原因分析\n\n解决方案\n\nRecording Rule 显示 health: unknown\n\n表达式语法错误或引用的指标不存在\n\n使用 promtool check rules 验证语法，确认源指标存在\n\n新指标无数据\n\ninterval 设置过长或表达式结果为空\n\n检查 interval 配置，在 Prometheus UI 测试表达式\n\nPrometheus OOM\n\nRecording Rules 产生的时序过多\n\n添加 limit、优化标签基数、增加内存\n\n告警延迟增加\n\nRecording Rules 计算压力过大\n\n减少规则数量、增大 interval、升级硬件\n\n#### ◆ 4.2.3 兼容性问题\n\n- • 版本兼容：limit 功能需要 Prometheus 2.28+，低版本需要在表达式中使用 topk 替代\n- • 平台兼容：使用 Prometheus Operator 时，Recording Rules 需要通过 PrometheusRule CRD 管理\n- • 组件依赖：Recording Rules 依赖的源指标（如 node_exporter、kube-state-metrics）版本变更可能导致表达式失效\n\n---\n\n##","/article/119",301,"2026-01-06 11:51:58","2026-01-06 11:53:45",{"id":190,"category_id":44,"title":191,"keywords":6,"description":192,"image_url":6,"content":193,"content_md":194,"url":195,"hits":196,"is_recommend":73,"is_top":73,"create_time":197,"update_time":198},118,"GitOps 落地实践：ArgoCD + Kustomize 实现声明式基础设施管理(二)","四、最佳实践和注意事项4.1 最佳实践4.1.1 性能优化优化点一：减少 Git 轮询频率# argocd-cm ConfigMapapiVersion:&nbsp;v1kind:&nbsp;ConfigMapmetadata:&nbsp;&nbsp;name:&nbsp;argocd-cm&nbsp;&nbsp;namespace:&nbsp;argocddata:&nbsp;&nbsp;timeout.reconciliation:&nbsp;300s&nbsp;&nbsp;# 默认 180","\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__224\">\u003Cspan leaf=\"\">四、最佳实践和注意事项\u003C/span>\u003C/span>\u003C/h2>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__225\">\u003Cspan leaf=\"\">4.1 最佳实践\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__226\">\u003Cspan leaf=\"\">4.1.1 性能优化\u003C/span>\u003C/span>\u003C/h4>\u003Cul class=\"list-paddingleft-1 js_darkmode__227\">\u003Cli>\u003Csection class=\"js_darkmode__228\">\u003Cp class=\"js_darkmode__229\">\u003Cstrong class=\"js_darkmode__230\">优化点一：减少 Git 轮询频率\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__231\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__20 js_darkmode__232\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__233\">\u003Cspan class=\"js_darkmode__234\"># argocd-cm ConfigMap\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>v1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ConfigMap\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd-cm\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan>data:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>timeout.reconciliation:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>300s\u003C/span>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__235\"># 默认 180s，大规模集群建议 300s+\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>timeout.reconciliation.jitter:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>30s\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__236\">\u003Cspan leaf=\"\">说明：默认每 3 分钟轮询一次 Git 仓库，大规模部署建议延长间隔并配置 Webhook 实现事件驱动同步。\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__237\">\u003Cp class=\"js_darkmode__238\">\u003Cstrong class=\"js_darkmode__239\">优化点二：启用资源缓存\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__240\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__21 js_darkmode__241\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__242\">\u003Cspan class=\"js_darkmode__243\"># 编辑 argocd-application-controller StatefulSet\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl edit statefulset argocd-application-controller -n argocd\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__244\"># 添加环境变量\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">env:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">- name: ARGOCD_APPLICATION_CONTROLLER_REPLICAS\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; value:&nbsp;\u003C/span>\u003Cspan>\"3\"\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">- name: ARGOCD_APPLICATION_CONTROLLER_SHARD\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; valueFrom:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; fieldRef:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; fieldPath: metadata.name\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__245\">\u003Cli>\u003Csection class=\"js_darkmode__246\">\u003Cspan leaf=\"\">配置 Redis HA 提升缓存性能\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__247\">\u003Cspan leaf=\"\">启用 Application Controller 分片（处理 1000+ Application）\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cli>\u003Csection class=\"js_darkmode__248\">\u003Cp class=\"js_darkmode__249\">\u003Cstrong class=\"js_darkmode__250\">优化点三：优化 Diff 计算\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__251\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__22 js_darkmode__252\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__253\">\u003Cspan class=\"js_darkmode__254\"># Application 配置\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>ignoreDifferences:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>apps\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Deployment\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>jsonPointers:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>/spec/replicas\u003C/span>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__255\"># 忽略 HPA 自动调整的副本数\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\"\"\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Secret\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>jsonPointers:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>/data\u003C/span>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__256\"># 忽略 External Secrets Operator 动态更新\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__257\">\u003Cspan leaf=\"\">4.1.2 安全加固\u003C/span>\u003C/span>\u003C/h4>\u003Cul class=\"list-paddingleft-1 js_darkmode__258\">\u003Cli>\u003Csection class=\"js_darkmode__259\">\u003Cp class=\"js_darkmode__260\">\u003Cstrong class=\"js_darkmode__261\">安全措施一：限制资源权限\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__262\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__23 js_darkmode__263\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__264\">\u003Cspan class=\"js_darkmode__265\"># AppProject 白名单机制\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>clusterResourceWhitelist:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>''\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Namespace\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>clusterResourceBlacklist:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>''\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ResourceQuota\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>'rbac.authorization.k8s.io'\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ClusterRole\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__266\">\u003Cspan leaf=\"\">说明：禁止应用创建 ClusterRole、PersistentVolume 等集群级资源，防止权限提升。\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__267\">\u003Cp class=\"js_darkmode__268\">\u003Cstrong class=\"js_darkmode__269\">安全措施二：启用 Admission Webhook\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__270\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__24 js_darkmode__271\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__272\">\u003Cspan class=\"js_darkmode__273\"># argocd-cm ConfigMap\u003C/span>\u003Cbr>\u003Cspan>data:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>resource.customizations:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">|\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; admissionregistration.k8s.io/MutatingWebhookConfiguration:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; health.lua: |\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; hs = {}\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; hs.status = \"Healthy\"\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; return hs\u003C/span>\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Cp class=\"js_darkmode__274\">\u003Cspan leaf=\"\">配合 OPA Gatekeeper 或 Kyverno 实现策略即代码，拦截不合规资源。\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__275\">\u003Cp class=\"js_darkmode__276\">\u003Cstrong class=\"js_darkmode__277\">安全措施三：Git 签名验证\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__278\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__25 js_darkmode__279\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__280\">\u003Cspan class=\"js_darkmode__281\"># 启用 GPG 签名验证\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo add https://github.com/your-org/your-repo.git \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --username git \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --password&nbsp;\u003C/span>\u003Cspan>$TOKEN\u003C/span>\u003Cspan leaf=\"\">&nbsp;\\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --\u003C/span>\u003Cspan>enable\u003C/span>\u003Cspan leaf=\"\">-lfs \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --gpg-key-id 0x1234567890ABCDEF\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__282\">\u003Cspan leaf=\"\">4.1.3 高可用配置\u003C/span>\u003C/span>\u003C/h4>\u003Cul class=\"list-paddingleft-1 js_darkmode__283\">\u003Cli>\u003Csection class=\"js_darkmode__284\">\u003Cp class=\"js_darkmode__285\">\u003Cstrong class=\"js_darkmode__286\">HA方案一：组件多副本部署\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__287\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__26 js_darkmode__288\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__289\">\u003Cspan class=\"js_darkmode__290\"># argocd-server 副本数调整\u003C/span>\u003Cbr>\u003Cspan>kubectl\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>scale\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>deployment\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd-server\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-n\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>--replicas=3\u003C/span>\u003Cbr>\u003Cspan>kubectl\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>scale\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>deployment\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd-repo-server\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-n\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>--replicas=3\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__291\"># Application Controller 使用 StatefulSet，启用分片\u003C/span>\u003Cbr>\u003Cspan>kubectl\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>scale\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>statefulset\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd-application-controller\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-n\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>--replicas=3\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__292\">\u003Cp class=\"js_darkmode__293\">\u003Cstrong class=\"js_darkmode__294\">HA方案二：Redis Sentinel 部署\u003C/strong>\u003C/p>\u003Cpre class=\"js_darkmode__295\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__27 js_darkmode__296\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__297\">\u003Cspan class=\"js_darkmode__298\"># 使用 Redis HA 替代单实例 Redis\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__299\"># 安装 Redis Sentinel\u003C/span>\u003Cbr>\u003Cspan>kubectl\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>apply\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-n\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-f\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/redis-ha/redis-ha.yaml\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__300\">\u003Cp class=\"js_darkmode__301\">\u003Cstrong class=\"js_darkmode__302\">备份策略\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__303\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__28 js_darkmode__304\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__305\">\u003Cspan>#!/bin/bash\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__306\"># 备份所有 Application 定义\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get applications -n argocd -o yaml &gt; applications-backup.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__307\"># 备份所有 AppProject 定义\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get appprojects -n argocd -o yaml &gt; appprojects-backup.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__308\"># 备份配置\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get cm argocd-cm argocd-rbac-cm argocd-cmd-params-cm -n argocd -o yaml &gt; argocd-config-backup.yaml\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__309\">\u003Cspan leaf=\"\">4.2 注意事项\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__310\">\u003Cspan leaf=\"\">4.2.1 配置注意事项\u003C/span>\u003C/span>\u003C/h4>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__311\">\u003Cspan leaf=\"\">⚠️&nbsp;\u003C/span>\u003Cstrong class=\"js_darkmode__312\">警告\u003C/strong>\u003Cspan leaf=\"\">：生产环境必须禁用 admin 账户，强制使用 SSO 认证，所有操作可追溯到个人账户。\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__313\">\u003Cli>\u003Csection class=\"js_darkmode__314\">\u003Cspan leaf=\"\">❗ 注意事项一：syncPolicy.automated 慎用于生产环境，建议仅对基础设施组件启用自动同步，业务应用采用手动审批\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__315\">\u003Cspan leaf=\"\">❗ 注意事项二：prune 和 selfHeal 同时启用可能导致误删资源，务必配置 ignoreDifferences 排除动态字段\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__316\">\u003Cspan leaf=\"\">❗ 注意事项三：Kustomize 的 namespace 字段会覆盖所有资源的 namespace，使用 overlay 时需注意命名空间冲突\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__317\">\u003Cspan leaf=\"\">4.2.2 常见错误\u003C/span>\u003C/span>\u003C/h4>\u003Csection data-tool=\"mdnice编辑器\">\u003Ctable class=\"layui-table\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__318\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">错误现象\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__319\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">原因分析\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__320\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">解决方案\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr class=\"js_darkmode__321\">\u003Ctd class=\"js_darkmode__322\">\u003Csection>\u003Cspan leaf=\"\">ComparisonError: failed to unmarshal\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__323\">\u003Csection>\u003Cspan leaf=\"\">Kustomize 构建失败，语法错误\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__324\">\u003Csection>\u003Cspan leaf=\"\">本地执行&nbsp;\u003C/span>\u003Ccode>kubectl kustomize overlays/prod\u003C/code>\u003Cspan leaf=\"\">&nbsp;验证配置\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__325\">\u003Ctd class=\"js_darkmode__326\">\u003Csection>\u003Cspan leaf=\"\">SyncFailed: PermissionDenied\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__327\">\u003Csection>\u003Cspan leaf=\"\">ServiceAccount 权限不足\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__328\">\u003Csection>\u003Cspan leaf=\"\">检查 AppProject 的 clusterResourceWhitelist 配置\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__329\">\u003Ctd class=\"js_darkmode__330\">\u003Csection>\u003Cspan leaf=\"\">OutOfSync 但实际已同步\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__331\">\u003Csection>\u003Cspan leaf=\"\">ignoreDifferences 配置不当\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__332\">\u003Csection>\u003Cspan leaf=\"\">添加动态字段到 ignoreDifferences 列表\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__333\">\u003Ctd class=\"js_darkmode__334\">\u003Csection>\u003Cspan leaf=\"\">Health status: Progressing\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__335\">\u003Csection>\u003Cspan leaf=\"\">资源健康检查超时\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__336\">\u003Csection>\u003Cspan leaf=\"\">检查 Pod 日志，调整 health check 参数\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__337\">\u003Ctd class=\"js_darkmode__338\">\u003Csection>\u003Cspan leaf=\"\">Webhook trigger failed\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__339\">\u003Csection>\u003Cspan leaf=\"\">Webhook Secret 不匹配\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__340\">\u003Csection>\u003Cspan leaf=\"\">重新生成 Webhook URL，更新 Git 仓库配置\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/section>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__341\">\u003Cspan leaf=\"\">4.2.3 兼容性问题\u003C/span>\u003C/span>\u003C/h4>\u003Cul class=\"list-paddingleft-1 js_darkmode__342\">\u003Cli>\u003Csection class=\"js_darkmode__343\">\u003Cstrong class=\"js_darkmode__344\">版本兼容\u003C/strong>\u003Cspan leaf=\"\">：ArgoCD 2.9+ 要求 Kubernetes 1.24+，使用旧版 K8s 需安装 ArgoCD 2.7 LTS\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__345\">\u003Cstrong class=\"js_darkmode__346\">平台兼容\u003C/strong>\u003Cspan leaf=\"\">：Helm Chart 需启用&nbsp;\u003C/span>\u003Ccode class=\"js_darkmode__347\">\u003Cspan leaf=\"\">--enable-helm\u003C/span>\u003C/code>\u003Cspan leaf=\"\">，Jsonnet 需安装&nbsp;\u003C/span>\u003Ccode class=\"js_darkmode__348\">\u003Cspan leaf=\"\">argocd-jsonnet\u003C/span>\u003C/code>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__349\">\u003Cstrong class=\"js_darkmode__350\">组件依赖\u003C/strong>\u003Cspan leaf=\"\">：Kustomize 版本与 kubectl 绑定，使用高级特性（replacements）需确保 Kustomize 5.0+\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Chr class=\"js_darkmode__351\">\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__352\">\u003Cspan leaf=\"\">五、故障排查和监控\u003C/span>\u003C/span>\u003C/h2>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__353\">\u003Cspan leaf=\"\">5.1 故障排查\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__354\">\u003Cspan leaf=\"\">5.1.1 日志查看\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__355\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__29 js_darkmode__356\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__357\">\u003Cspan class=\"js_darkmode__358\"># 查看 Application Controller 日志（核心组件）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl logs -n argocd deployment/argocd-application-controller --tail=100 -f\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__359\"># 查看 Repo Server 日志（Git 拉取和 Kustomize 构建）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl logs -n argocd deployment/argocd-repo-server --tail=100 -f\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__360\"># 查看 Server 日志（API 请求）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl logs -n argocd deployment/argocd-server --tail=100 -f\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__361\"># 查看特定 Application 的同步日志\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app logs myapp --follow\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__362\"># 查看详细错误信息\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl describe application myapp -n argocd\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__363\">\u003Cspan leaf=\"\">5.1.2 常见问题排查\u003C/span>\u003C/span>\u003C/h4>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__364\">\u003Cstrong class=\"js_darkmode__365\">问题一：Git 仓库连接失败\u003C/strong>\u003C/p>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__366\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__30 js_darkmode__367\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__368\">\u003Cspan class=\"js_darkmode__369\"># 诊断命令\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo list\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get secret -n argocd -l argocd.argoproj.io/secret-type=repository\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__370\"># 测试 Git 连接\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl&nbsp;\u003C/span>\u003Cspan>exec\u003C/span>\u003Cspan leaf=\"\">&nbsp;-it deployment/argocd-repo-server -n argocd -- sh\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">git ls-remote https://github.com/your-org/your-repo.git\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__371\">\u003Cstrong class=\"js_darkmode__372\">解决方案\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__373\">\u003Cli>\u003Csection class=\"js_darkmode__374\">\u003Cspan leaf=\"\">检查凭证是否过期（PAT、SSH Key）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__375\">\u003Cspan leaf=\"\">验证网络连通性（代理、防火墙）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__376\">\u003Cspan leaf=\"\">查看 Repo Server 日志确认具体错误\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__377\">\u003Cstrong class=\"js_darkmode__378\">问题二：Application 一直处于 Progressing 状态\u003C/strong>\u003C/p>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__379\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__31 js_darkmode__380\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__381\">\u003Cspan class=\"js_darkmode__382\"># 诊断命令\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app get myapp --refresh\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get pods -n myapp -o wide\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl describe pod &lt;pod-name&gt; -n myapp\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__383\">\u003Cstrong class=\"js_darkmode__384\">解决方案\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__385\">\u003Cli>\u003Csection class=\"js_darkmode__386\">\u003Cspan leaf=\"\">检查 Pod 事件（镜像拉取失败、资源不足）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__387\">\u003Cspan leaf=\"\">验证健康检查配置（存活探针、就绪探针）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__388\">\u003Cspan leaf=\"\">调整 Application 的健康检查超时时间\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__389\">\u003Cstrong class=\"js_darkmode__390\">问题三：Kustomize 构建失败\u003C/strong>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__391\">\u003Cli>\u003Csection class=\"js_darkmode__392\">\u003Cp class=\"js_darkmode__393\">\u003Cstrong class=\"js_darkmode__394\">症状\u003C/strong>\u003Cspan leaf=\"\">：Application 状态显示 ComparisonError\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__395\">\u003Cp class=\"js_darkmode__396\">\u003Cstrong class=\"js_darkmode__397\">排查\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cpre class=\"js_darkmode__398\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__32 js_darkmode__399\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__400\">\u003Cspan class=\"js_darkmode__401\"># 本地复现问题\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">git&nbsp;\u003C/span>\u003Cspan>clone\u003C/span>\u003Cspan leaf=\"\">&nbsp;&lt;repo-url&gt;\u003C/span>\u003Cbr>\u003Cspan>cd\u003C/span>\u003Cspan leaf=\"\">&nbsp;overlays/prod\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl kustomize . --\u003C/span>\u003Cspan>enable\u003C/span>\u003Cspan leaf=\"\">-helm\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__402\">\u003Cp class=\"js_darkmode__403\">\u003Cstrong class=\"js_darkmode__404\">解决\u003C/strong>\u003Cspan leaf=\"\">：修复 kustomization.yaml 语法错误，验证资源引用路径\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003C/ul>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__405\">\u003Cspan leaf=\"\">5.1.3 调试模式\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__406\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__33 js_darkmode__407\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__408\">\u003Cspan class=\"js_darkmode__409\"># 开启 Application Controller 调试日志\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl&nbsp;\u003C/span>\u003Cspan>set\u003C/span>\u003Cspan leaf=\"\">&nbsp;env deployment/argocd-application-controller \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; -n argocd \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; ARGOCD_LOG_LEVEL=debug\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__410\"># 开启 Repo Server 详细日志\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl&nbsp;\u003C/span>\u003Cspan>set\u003C/span>\u003Cspan leaf=\"\">&nbsp;env deployment/argocd-repo-server \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; -n argocd \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; ARGOCD_LOG_LEVEL=debug \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; ARGOCD_EXEC_TIMEOUT=180s\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__411\"># 禁用缓存强制重新构建\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app get myapp --hard-refresh\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__412\">\u003Cspan leaf=\"\">5.2 性能监控\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__413\">\u003Cspan leaf=\"\">5.2.1 关键指标监控\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__414\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__34 js_darkmode__415\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__416\">\u003Cspan class=\"js_darkmode__417\"># Application 同步时长\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app list -o json | jq&nbsp;\u003C/span>\u003Cspan>'.[] | {name: .metadata.name, syncTime: .status.operationState.finishedAt}'\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__418\"># Repo Server CPU/内存使用\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl top pod -n argocd -l app.kubernetes.io/name=argocd-repo-server\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__419\"># Application Controller 处理队列长度\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl logs -n argocd deployment/argocd-application-controller | grep&nbsp;\u003C/span>\u003Cspan>\"app reconciliation\"\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__420\"># Redis 连接数\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl&nbsp;\u003C/span>\u003Cspan>exec\u003C/span>\u003Cspan leaf=\"\">&nbsp;-n argocd deployment/argocd-redis -- redis-cli info clients\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__421\">\u003Cspan leaf=\"\">5.2.2 监控指标说明\u003C/span>\u003C/span>\u003C/h4>\u003Csection data-tool=\"mdnice编辑器\">\u003Ctable class=\"layui-table\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__422\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">指标名称\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__423\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">正常范围\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__424\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">告警阈值\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__425\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">说明\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr class=\"js_darkmode__426\">\u003Ctd class=\"js_darkmode__427\">\u003Csection>\u003Cspan leaf=\"\">argocd_app_sync_total\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__428\">\u003Csection>\u003Cspan leaf=\"\">-\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__429\">\u003Csection>\u003Cspan leaf=\"\">失败率 &gt;5%\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__430\">\u003Csection>\u003Cspan leaf=\"\">同步成功率，区分成功/失败\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__431\">\u003Ctd class=\"js_darkmode__432\">\u003Csection>\u003Cspan leaf=\"\">argocd_app_reconcile_duration\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__433\">\u003Csection>\u003Cspan leaf=\"\">&lt;30s\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__434\">\u003Csection>\u003Cspan leaf=\"\">&gt;60s\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__435\">\u003Csection>\u003Cspan leaf=\"\">应用对账耗时，反映性能瓶颈\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__436\">\u003Ctd class=\"js_darkmode__437\">\u003Csection>\u003Cspan leaf=\"\">argocd_git_request_duration\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__438\">\u003Csection>\u003Cspan leaf=\"\">&lt;5s\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__439\">\u003Csection>\u003Cspan leaf=\"\">&gt;15s\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__440\">\u003Csection>\u003Cspan leaf=\"\">Git 操作耗时，检测网络问题\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__441\">\u003Ctd class=\"js_darkmode__442\">\u003Csection>\u003Cspan leaf=\"\">argocd_kubectl_exec_pending\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__443\">\u003Csection>\u003Cspan leaf=\"\">&lt;10\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__444\">\u003Csection>\u003Cspan leaf=\"\">&gt;50\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__445\">\u003Csection>\u003Cspan leaf=\"\">kubectl 执行队列长度\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__446\">\u003Ctd class=\"js_darkmode__447\">\u003Csection>\u003Cspan leaf=\"\">argocd_redis_request_total\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__448\">\u003Csection>\u003Cspan leaf=\"\">-\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__449\">\u003Csection>\u003Cspan leaf=\"\">错误率 &gt;1%\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__450\">\u003Csection>\u003Cspan leaf=\"\">Redis 请求统计\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/section>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__451\">\u003Cspan leaf=\"\">5.2.3 监控告警配置\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__452\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__35 js_darkmode__453\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__454\">\u003Cspan class=\"js_darkmode__455\"># Prometheus PrometheusRule\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>monitoring.coreos.com/v1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>PrometheusRule\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd-alerts\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>groups:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>interval:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>30s\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>rules:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>alert:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ArgoCDAppSyncFailed\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>expr:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">|\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; sum(increase(argocd_app_sync_total{phase=\"Failed\"}[5m])) &gt; 3\u003C/span>\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>for:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>5m\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>labels:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>severity:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>warning\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>annotations:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>summary:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\"ArgoCD Application 同步失败过多\"\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>description:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"Application&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{ $labels.name }}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">&nbsp;同步失败次数&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{ $value }}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>alert:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ArgoCDAppOutOfSync\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>expr:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">|\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; argocd_app_info{sync_status=\"OutOfSync\"} == 1\u003C/span>\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>for:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>10m\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>labels:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>severity:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>warning\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>annotations:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>summary:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\"Application 长时间未同步\"\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>description:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{ $labels.name }}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">&nbsp;已超过 10 分钟未同步\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>alert:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ArgoCDRepoServerDown\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>expr:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">|\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; up{job=\"argocd-repo-server\"} == 0\u003C/span>\u003Cbr>\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>for:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>2m\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>labels:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>severity:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>critical\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>annotations:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>summary:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\"ArgoCD Repo Server 不可用\"\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__456\">\u003Cspan leaf=\"\">5.3 备份与恢复\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__457\">\u003Cspan leaf=\"\">5.3.1 备份策略\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__458\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__36 js_darkmode__459\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__460\">\u003Cspan>#!/bin/bash\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__461\"># 文件名：argocd-backup.sh\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__462\"># 功能：备份 ArgoCD 所有配置\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan leaf=\"\">BACKUP_DIR=\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"/backup/argocd/\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">$(date +%Y%m%d)\u003C/span>\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">mkdir -p&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__463\"># 备份 Application\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get applications -n argocd -o yaml &gt;&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">/applications.yaml\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__464\"># 备份 AppProject\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get appprojects -n argocd -o yaml &gt;&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">/appprojects.yaml\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__465\"># 备份 ApplicationSet\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get applicationsets -n argocd -o yaml &gt;&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">/applicationsets.yaml\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__466\"># 备份配置 ConfigMap\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get cm -n argocd argocd-cm argocd-rbac-cm argocd-cmd-params-cm -o yaml &gt;&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">/configmaps.yaml\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__467\"># 备份 Secret（不含敏感数据）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type -o yaml &gt;&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">/secrets.yaml\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__468\"># 备份到远程存储\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">tar -czf&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">.tar.gz\"\u003C/span>\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">aws s3 cp&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">.tar.gz\"\u003C/span>\u003C/span>\u003Cspan leaf=\"\">&nbsp;s3://backups/argocd/\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__469\"># 清理 7 天前的备份\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">find /backup/argocd -name&nbsp;\u003C/span>\u003Cspan>\"*.tar.gz\"\u003C/span>\u003Cspan leaf=\"\">&nbsp;-mtime +7 -delete\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>echo\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"Backup completed:&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${BACKUP_DIR}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">.tar.gz\"\u003C/span>\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__470\">\u003Cspan leaf=\"\">5.3.2 恢复流程\u003C/span>\u003C/span>\u003C/h4>\u003Col class=\"list-paddingleft-1 js_darkmode__471\">\u003Cli>\u003Csection class=\"js_darkmode__472\">\u003Cstrong class=\"js_darkmode__473\">停止 ArgoCD 同步\u003C/strong>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__474\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__37 js_darkmode__475\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__476\">\u003Cspan class=\"js_darkmode__477\"># 暂停所有 Application 自动同步\u003C/span>\u003Cbr>\u003Cspan>for\u003C/span>\u003Cspan leaf=\"\">&nbsp;app&nbsp;\u003C/span>\u003Cspan>in\u003C/span>\u003Cspan leaf=\"\">&nbsp;$(argocd app list -o name);&nbsp;\u003C/span>\u003Cspan>do\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; argocd app&nbsp;\u003C/span>\u003Cspan>set\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>$app\u003C/span>\u003Cspan leaf=\"\">&nbsp;--sync-policy none\u003C/span>\u003Cbr>\u003Cspan>done\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Col class=\"list-paddingleft-1 js_darkmode__478\" start=\"2\">\u003Cli>\u003Csection class=\"js_darkmode__479\">\u003Cstrong class=\"js_darkmode__480\">恢复配置\u003C/strong>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__481\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__38 js_darkmode__482\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__483\">\u003Cspan class=\"js_darkmode__484\"># 解压备份\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">tar -xzf /backup/argocd/20240315.tar.gz -C /tmp\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__485\"># 恢复 AppProject\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl apply -f /tmp/20240315/appprojects.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__486\"># 恢复 Application\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl apply -f /tmp/20240315/applications.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__487\"># 恢复配置\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl apply -f /tmp/20240315/configmaps.yaml\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Col class=\"list-paddingleft-1 js_darkmode__488\" start=\"3\">\u003Cli>\u003Csection class=\"js_darkmode__489\">\u003Cstrong class=\"js_darkmode__490\">验证恢复\u003C/strong>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__491\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__39 js_darkmode__492\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__493\">\u003Cspan class=\"js_darkmode__494\"># 检查 Application 状态\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app list\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__495\"># 触发同步验证\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app sync --dry-run guestbook\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Col class=\"list-paddingleft-1 js_darkmode__496\" start=\"4\">\u003Cli>\u003Csection class=\"js_darkmode__497\">\u003Cstrong class=\"js_darkmode__498\">重启服务\u003C/strong>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__499\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__40 js_darkmode__500\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__501\">\u003Cspan class=\"js_darkmode__502\"># 重启 ArgoCD 组件\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl rollout restart deployment -n argocd argocd-server\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl rollout restart deployment -n argocd argocd-repo-server\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl rollout restart statefulset -n argocd argocd-application-controller\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__503\">\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__504\">\u003Cspan leaf=\"\">六、总结\u003C/span>\u003C/span>\u003C/h2>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__505\">\u003Cspan leaf=\"\">6.1 技术要点回顾\u003C/span>\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__506\">\u003Cli>\u003Csection class=\"js_darkmode__507\">\u003Cspan leaf=\"\">✅&nbsp;\u003C/span>\u003Cstrong class=\"js_darkmode__508\">GitOps 核心价值\u003C/strong>\u003Cspan leaf=\"\">：Git 作为单一事实来源，实现配置的版本化、可审计、快速回滚，降低人为操作风险\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__509\">\u003Cspan leaf=\"\">✅&nbsp;\u003C/span>\u003Cstrong class=\"js_darkmode__510\">ArgoCD 架构\u003C/strong>\u003Cspan leaf=\"\">：拉模式实现持续同步，Application Controller 负责状态对账，Repo Server 处理 Git 和配置工具集成\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__511\">\u003Cspan leaf=\"\">✅&nbsp;\u003C/span>\u003Cstrong class=\"js_darkmode__512\">Kustomize 配置管理\u003C/strong>\u003Cspan leaf=\"\">：通过 base + overlay 机制优雅解决多环境配置差异，避免重复维护\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__513\">\u003Cspan leaf=\"\">✅&nbsp;\u003C/span>\u003Cstrong class=\"js_darkmode__514\">安全与权限\u003C/strong>\u003Cspan leaf=\"\">：AppProject 实现资源隔离，RBAC 配置细粒度权限控制，SSO 集成企业认证体系\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__515\">\u003Cspan leaf=\"\">✅&nbsp;\u003C/span>\u003Cstrong class=\"js_darkmode__516\">高可用与性能\u003C/strong>\u003Cspan leaf=\"\">：多副本部署、Redis HA、Application Controller 分片支持大规模集群管理\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__517\">\u003Cspan leaf=\"\">6.2 进阶学习方向\u003C/span>\u003C/span>\u003C/h3>\u003Col class=\"list-paddingleft-1 js_darkmode__518\">\u003Cli>\u003Csection class=\"js_darkmode__519\">\u003Cp class=\"js_darkmode__520\">\u003Cstrong class=\"js_darkmode__521\">Argo Rollouts 渐进式交付\u003C/strong>\u003Cspan leaf=\"\">：实现蓝绿部署、金丝雀发布，结合 Istio/Nginx 实现流量分析和自动回滚\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__522\">\u003Cli>\u003Csection class=\"js_darkmode__523\">\u003Cspan leaf=\"\">学习资源：https://argo-rollouts.readthedocs.io\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__524\">\u003Cspan leaf=\"\">实践建议：从蓝绿部署开始，逐步过渡到基于指标的自动化金丝雀发布\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cli>\u003Csection class=\"js_darkmode__525\">\u003Cp class=\"js_darkmode__526\">\u003Cstrong class=\"js_darkmode__527\">多租户与多集群管理\u003C/strong>\u003Cspan leaf=\"\">：使用 Cluster Secret、ApplicationSet 矩阵生成器管理数百个集群\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__528\">\u003Cli>\u003Csection class=\"js_darkmode__529\">\u003Cspan leaf=\"\">学习资源：https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__530\">\u003Cspan leaf=\"\">实践建议：设计租户隔离方案，配置跨集群资源配额和网络策略\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cli>\u003Csection class=\"js_darkmode__531\">\u003Cp class=\"js_darkmode__532\">\u003Cstrong class=\"js_darkmode__533\">策略即代码\u003C/strong>\u003Cspan leaf=\"\">：集成 OPA Gatekeeper 或 Kyverno 实现准入控制、镜像扫描、资源配额自动化\u003C/span>\u003C/p>\u003C/section>\u003C/li>\u003Cul class=\"list-paddingleft-1 js_darkmode__534\">\u003Cli>\u003Csection class=\"js_darkmode__535\">\u003Cspan leaf=\"\">学习资源：https://www.openpolicyagent.org/docs/latest/kubernetes-introduction/\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__536\">\u003Cspan leaf=\"\">实践建议：从镜像白名单、Label 强制策略开始，逐步覆盖安全基线\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003C/ol>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__537\">\u003Cspan leaf=\"\">6.3 参考资料\u003C/span>\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__538\">\u003Cli>\u003Csection class=\"js_darkmode__539\">\u003Cspan leaf=\"\">ArgoCD 官方文档&nbsp;- 完整的安装、配置、操作指南\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__540\">\u003Cspan leaf=\"\">Kustomize 官方文档&nbsp;- 配置管理最佳实践和高级特性\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__541\">\u003Cspan leaf=\"\">GitOps Working Group&nbsp;- CNCF GitOps 标准和原则\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__542\">\u003Cspan leaf=\"\">Argo CD Operator&nbsp;- Operator 方式管理 ArgoCD 生命周期\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__543\">\u003Cspan leaf=\"\">ArgoCD 最佳实践&nbsp;- 官方推荐的生产环境配置\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Chr class=\"js_darkmode__544\">\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__545\">\u003Cspan leaf=\"\">附录\u003C/span>\u003C/span>\u003C/h2>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__546\">\u003Cspan leaf=\"\">A. 命令速查表\u003C/span>\u003C/span>\u003C/h3>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__547\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__41 js_darkmode__548\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__549\">\u003Cspan class=\"js_darkmode__550\"># Application 管理\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app create &lt;name&gt; --repo &lt;url&gt; --path &lt;path&gt; --dest-server &lt;server&gt; --dest-namespace &lt;ns&gt;\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app get &lt;name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__551\"># 查看应用详情\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app sync &lt;name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__552\"># 手动同步\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app diff &lt;name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__553\"># 查看配置差异\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app&nbsp;\u003C/span>\u003Cspan>history\u003C/span>\u003Cspan leaf=\"\">&nbsp;&lt;name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__554\"># 查看同步历史\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app rollback &lt;name&gt; &lt;revision&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__555\"># 回滚到指定版本\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app delete &lt;name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__556\"># 删除应用\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app&nbsp;\u003C/span>\u003Cspan>set\u003C/span>\u003Cspan leaf=\"\">&nbsp;&lt;name&gt; --sync-policy automated &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__557\"># 配置自动同步\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__558\"># 仓库管理\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo add &lt;url&gt; --username &lt;user&gt; --password &lt;pass&gt;\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo list &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__559\"># 列出所有仓库\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo rm &lt;url&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__560\"># 删除仓库\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__561\"># 集群管理\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd cluster add &lt;context-name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__562\"># 添加集群\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd cluster list &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__563\"># 列出所有集群\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd cluster get &lt;server-url&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__564\"># 查看集群信息\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__565\"># 项目管理\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd proj create &lt;name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__566\"># 创建项目\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd proj add-source &lt;proj&gt; &lt;repo&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__567\"># 添加源仓库\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd proj add-destination &lt;proj&gt; &lt;server&gt; &lt;ns&gt; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__568\"># 添加目标集群\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__569\">\u003Cspan leaf=\"\">B. 配置参数详解\u003C/span>\u003C/span>\u003C/h3>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__570\">\u003Cstrong class=\"js_darkmode__571\">Application 核心参数\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__572\">\u003Cli>\u003Csection class=\"js_darkmode__573\">\u003Ccode class=\"js_darkmode__574\">\u003Cspan leaf=\"\">source.repoURL\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：Git 仓库地址，支持 HTTPS/SSH 协议\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__575\">\u003Ccode class=\"js_darkmode__576\">\u003Cspan leaf=\"\">source.targetRevision\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：分支/标签/Commit SHA，HEAD 表示默认分支\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__577\">\u003Ccode class=\"js_darkmode__578\">\u003Cspan leaf=\"\">source.path\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：仓库内配置文件路径，支持 Kustomize/Helm/Plain YAML\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__579\">\u003Ccode class=\"js_darkmode__580\">\u003Cspan leaf=\"\">destination.server\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：目标集群 API Server 地址，\u003C/span>\u003Ccode class=\"js_darkmode__581\">\u003Cspan leaf=\"\">https://kubernetes.default.svc\u003C/span>\u003C/code>\u003Cspan leaf=\"\">&nbsp;表示当前集群\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__582\">\u003Ccode class=\"js_darkmode__583\">\u003Cspan leaf=\"\">syncPolicy.automated.prune\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：自动删除 Git 中不存在的资源\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__584\">\u003Ccode class=\"js_darkmode__585\">\u003Cspan leaf=\"\">syncPolicy.automated.selfHeal\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：自动修复手动修改（每 5 秒检测一次）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__586\">\u003Ccode class=\"js_darkmode__587\">\u003Cspan leaf=\"\">syncPolicy.syncOptions\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：同步选项，如 CreateNamespace、PruneLast、RespectIgnoreDifferences\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__588\">\u003Cstrong class=\"js_darkmode__589\">AppProject 权限控制\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__590\">\u003Cli>\u003Csection class=\"js_darkmode__591\">\u003Ccode class=\"js_darkmode__592\">\u003Cspan leaf=\"\">sourceRepos\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：允许的 Git 仓库白名单，支持通配符\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__593\">\u003Ccode class=\"js_darkmode__594\">\u003Cspan leaf=\"\">destinations\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：允许部署的目标集群和命名空间\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__595\">\u003Ccode class=\"js_darkmode__596\">\u003Cspan leaf=\"\">clusterResourceWhitelist\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：允许创建的集群级资源（空数组表示禁止所有）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__597\">\u003Ccode class=\"js_darkmode__598\">\u003Cspan leaf=\"\">namespaceResourceWhitelist\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：允许创建的命名空间级资源\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__599\">\u003Cspan leaf=\"\">C. 术语表\u003C/span>\u003C/span>\u003C/h3>\u003Csection data-tool=\"mdnice编辑器\">\u003Ctable class=\"layui-table\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__600\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">术语\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__601\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">英文\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__602\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">解释\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr class=\"js_darkmode__603\">\u003Ctd class=\"js_darkmode__604\">\u003Csection>\u003Cspan leaf=\"\">声明式配置\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__605\">\u003Csection>\u003Cspan leaf=\"\">Declarative Configuration\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__606\">\u003Csection>\u003Cspan leaf=\"\">描述期望状态而非操作步骤，系统自动消除偏差\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__607\">\u003Ctd class=\"js_darkmode__608\">\u003Csection>\u003Cspan leaf=\"\">同步\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__609\">\u003Csection>\u003Cspan leaf=\"\">Sync\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__610\">\u003Csection>\u003Cspan leaf=\"\">将 Git 中的期望状态应用到 Kubernetes 集群\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__611\">\u003Ctd class=\"js_darkmode__612\">\u003Csection>\u003Cspan leaf=\"\">对账\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__613\">\u003Csection>\u003Cspan leaf=\"\">Reconciliation\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__614\">\u003Csection>\u003Cspan leaf=\"\">周期性比较实际状态与期望状态，检测漂移\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__615\">\u003Ctd class=\"js_darkmode__616\">\u003Csection>\u003Cspan leaf=\"\">修剪\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__617\">\u003Csection>\u003Cspan leaf=\"\">Prune\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__618\">\u003Csection>\u003Cspan leaf=\"\">删除 Git 中不存在但集群中存在的资源\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__619\">\u003Ctd class=\"js_darkmode__620\">\u003Csection>\u003Cspan leaf=\"\">自愈\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__621\">\u003Csection>\u003Cspan leaf=\"\">Self-Heal\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__622\">\u003Csection>\u003Cspan leaf=\"\">自动撤销手动修改，恢复到 Git 定义的状态\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__623\">\u003Ctd class=\"js_darkmode__624\">\u003Csection>\u003Cspan leaf=\"\">健康状态\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__625\">\u003Csection>\u003Cspan leaf=\"\">Health Status\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__626\">\u003Csection>\u003Cspan leaf=\"\">资源的运行状态（Healthy/Progressing/Degraded/Suspended）\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__627\">\u003Ctd class=\"js_darkmode__628\">\u003Csection>\u003Cspan leaf=\"\">同步状态\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__629\">\u003Csection>\u003Cspan leaf=\"\">Sync Status\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__630\">\u003Csection>\u003Cspan leaf=\"\">配置的同步状态（Synced/OutOfSync）\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__631\">\u003Ctd class=\"js_darkmode__632\">\u003Csection>\u003Cspan leaf=\"\">应用集\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__633\">\u003Csection>\u003Cspan leaf=\"\">ApplicationSet\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__634\">\u003Csection>\u003Cspan leaf=\"\">批量生成 Application，支持多集群/多租户场景\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/section>","## 四、最佳实践和注意事项\n\n### 4.1 最佳实践\n\n#### 4.1.1 性能优化\n\n- 优化点一：减少 Git 轮询频率\n```\n# argocd-cm ConfigMapapiVersion: v1kind: ConfigMapmetadata:  name: argocd-cm  namespace: argocddata:  timeout.reconciliation: 300s  # 默认 180s，大规模集群建议 300s+  timeout.reconciliation.jitter: 30s\n```\n说明：默认每 3 分钟轮询一次 Git 仓库，大规模部署建议延长间隔并配置 Webhook 实现事件驱动同步。\n- 优化点二：启用资源缓存\n```\n# 编辑 argocd-application-controller StatefulSetkubectl edit statefulset argocd-application-controller -n argocd# 添加环境变量env:- name: ARGOCD_APPLICATION_CONTROLLER_REPLICAS  value: \"3\"- name: ARGOCD_APPLICATION_CONTROLLER_SHARD  valueFrom:    fieldRef:      fieldPath: metadata.name\n```\n- 配置 Redis HA 提升缓存性能\n- 启用 Application Controller 分片（处理 1000+ Application）\n\n**优化点三：优化 Diff 计算**\n\n```\n# Application 配置spec:  ignoreDifferences:  - group: apps    kind: Deployment    jsonPointers:    - /spec/replicas  # 忽略 HPA 自动调整的副本数  - group: \"\"    kind: Secret    jsonPointers:    - /data  # 忽略 External Secrets Operator 动态更新\n```\n\n#### 4.1.2 安全加固\n\n- 安全措施一：限制资源权限\n```\n# AppProject 白名单机制spec:  clusterResourceWhitelist:  - group: ''    kind: Namespace  clusterResourceBlacklist:  - group: ''    kind: ResourceQuota  - group: 'rbac.authorization.k8s.io'    kind: ClusterRole\n```\n说明：禁止应用创建 ClusterRole、PersistentVolume 等集群级资源，防止权限提升。\n- 安全措施二：启用 Admission Webhook\n```\n# argocd-cm ConfigMapdata:  resource.customizations: |    admissionregistration.k8s.io/MutatingWebhookConfiguration:      health.lua: |        hs = {}        hs.status = \"Healthy\"        return hs\n```\n配合 OPA Gatekeeper 或 Kyverno 实现策略即代码，拦截不合规资源。\n- 安全措施三：Git 签名验证\n```\n# 启用 GPG 签名验证argocd repo add https://github.com/your-org/your-repo.git \\  --username git \\  --password $TOKEN \\  --enable-lfs \\  --gpg-key-id 0x1234567890ABCDEF\n```\n\n#### 4.1.3 高可用配置\n\n- HA方案一：组件多副本部署\n```\n# argocd-server 副本数调整kubectl scale deployment argocd-server -n argocd --replicas=3kubectl scale deployment argocd-repo-server -n argocd --replicas=3# Application Controller 使用 StatefulSet，启用分片kubectl scale statefulset argocd-application-controller -n argocd --replicas=3\n```\n- HA方案二：Redis Sentinel 部署\n```\n# 使用 Redis HA 替代单实例 Redis# 安装 Redis Sentinelkubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/redis-ha/redis-ha.yaml\n```\n- 备份策略：\n```\n#!/bin/bash# 备份所有 Application 定义kubectl get applications -n argocd -o yaml > applications-backup.yaml# 备份所有 AppProject 定义kubectl get appprojects -n argocd -o yaml > appprojects-backup.yaml# 备份配置kubectl get cm argocd-cm argocd-rbac-cm argocd-cmd-params-cm -n argocd -o yaml > argocd-config-backup.yaml\n```\n\n### 4.2 注意事项\n\n#### 4.2.1 配置注意事项\n\n⚠️ \n**警告**\n：生产环境必须禁用 admin 账户，强制使用 SSO 认证，所有操作可追溯到个人账户。\n\n- ❗ 注意事项一：syncPolicy.automated 慎用于生产环境，建议仅对基础设施组件启用自动同步，业务应用采用手动审批\n- ❗ 注意事项二：prune 和 selfHeal 同时启用可能导致误删资源，务必配置 ignoreDifferences 排除动态字段\n- ❗ 注意事项三：Kustomize 的 namespace 字段会覆盖所有资源的 namespace，使用 overlay 时需注意命名空间冲突\n\n#### 4.2.2 常见错误\n\n错误现象\n\n原因分析\n\n解决方案\n\nComparisonError: failed to unmarshal\n\nKustomize 构建失败，语法错误\n\n本地执行 \n`kubectl kustomize overlays/prod`\n 验证配置\n\nSyncFailed: PermissionDenied\n\nServiceAccount 权限不足\n\n检查 AppProject 的 clusterResourceWhitelist 配置\n\nOutOfSync 但实际已同步\n\nignoreDifferences 配置不当\n\n添加动态字段到 ignoreDifferences 列表\n\nHealth status: Progressing\n\n资源健康检查超时\n\n检查 Pod 日志，调整 health check 参数\n\nWebhook trigger failed\n\nWebhook Secret 不匹配\n\n重新生成 Webhook URL，更新 Git 仓库配置\n\n#### 4.2.3 兼容性问题\n\n- 版本兼容：ArgoCD 2.9+ 要求 Kubernetes 1.24+，使用旧版 K8s 需安装 ArgoCD 2.7 LTS\n- 平台兼容：Helm Chart 需启用 --enable-helm，Jsonnet 需安装 argocd-jsonnet\n- 组件依赖：Kustomize 版本与 kubectl 绑定，使用高级特性（replacements）需确保 Kustomize 5.0+\n\n---\n\n## 五、故障排查和监控\n\n### 5.1 故障排查\n\n#### 5.1.1 日志查看\n\n```\n# 查看 Application Controller 日志（核心组件）kubectl logs -n argocd deployment/argocd-application-controller --tail=100 -f# 查看 Repo Server 日志（Git 拉取和 Kustomize 构建）kubectl logs -n argocd deployment/argocd-repo-server --tail=100 -f# 查看 Server 日志（API 请求）kubectl logs -n argocd deployment/argocd-server --tail=100 -f# 查看特定 Application 的同步日志argocd app logs myapp --follow# 查看详细错误信息kubectl describe application myapp -n argocd\n```\n\n#### 5.1.2 常见问题排查\n\n**问题一：Git 仓库连接失败**\n\n```\n# 诊断命令argocd repo listkubectl get secret -n argocd -l argocd.argoproj.io/secret-type=repository# 测试 Git 连接kubectl exec -it deployment/argocd-repo-server -n argocd -- shgit ls-remote https://github.com/your-org/your-repo.git\n```\n\n**解决方案**\n：\n\n1. 检查凭证是否过期（PAT、SSH Key）\n2. 验证网络连通性（代理、防火墙）\n3. 查看 Repo Server 日志确认具体错误\n\n**问题二：Application 一直处于 Progressing 状态**\n\n```\n# 诊断命令argocd app get myapp --refreshkubectl get pods -n myapp -o widekubectl describe pod  -n myapp\n```\n\n**解决方案**\n：\n\n1. 检查 Pod 事件（镜像拉取失败、资源不足）\n2. 验证健康检查配置（存活探针、就绪探针）\n3. 调整 Application 的健康检查超时时间\n\n**问题三：Kustomize 构建失败**\n\n- 症状：Application 状态显示 ComparisonError\n- 排查：\n```\n# 本地复现问题git clone cd overlays/prodkubectl kustomize . --enable-helm\n```\n- 解决：修复 kustomization.yaml 语法错误，验证资源引用路径\n\n#### 5.1.3 调试模式\n\n```\n# 开启 Application Controller 调试日志kubectl set env deployment/argocd-application-controller \\  -n argocd \\  ARGOCD_LOG_LEVEL=debug# 开启 Repo Server 详细日志kubectl set env deployment/argocd-repo-server \\  -n argocd \\  ARGOCD_LOG_LEVEL=debug \\  ARGOCD_EXEC_TIMEOUT=180s# 禁用缓存强制重新构建argocd app get myapp --hard-refresh\n```\n\n### 5.2 性能监控\n\n#### 5.2.1 关键指标监控\n\n```\n# Application 同步时长argocd app list -o json | jq '.[] | {name: .metadata.name, syncTime: .status.operationState.finishedAt}'# Repo Server CPU/内存使用kubectl top pod -n argocd -l app.kubernetes.io/name=argocd-repo-server# Application Controller 处理队列长度kubectl logs -n argocd deployment/argocd-application-controller | grep \"app reconciliation\"# Redis 连接数kubectl exec -n argocd deployment/argocd-redis -- redis-cli info clients\n```\n\n#### 5.2.2 监控指标说明\n\n指标名称\n\n正常范围\n\n告警阈值\n\n说明\n\nargocd_app_sync_total\n\n-\n\n失败率 >5%\n\n同步成功率，区分成功/失败\n\nargocd_app_reconcile_duration\n\n60s\n\n应用对账耗时，反映性能瓶颈\n\nargocd_git_request_duration\n\n15s\n\nGit 操作耗时，检测网络问题\n\nargocd_kubectl_exec_pending\n\n50\n\nkubectl 执行队列长度\n\nargocd_redis_request_total\n\n-\n\n错误率 >1%\n\nRedis 请求统计\n\n#### 5.2.3 监控告警配置\n\n```\n# Prometheus PrometheusRuleapiVersion: monitoring.coreos.com/v1kind: PrometheusRulemetadata:  name: argocd-alerts  namespace: argocdspec:  groups:  - name: argocd    interval: 30s    rules:    - alert: ArgoCDAppSyncFailed      expr: |        sum(increase(argocd_app_sync_total{phase=\"Failed\"}[5m])) > 3      for: 5m      labels:        severity: warning      annotations:        summary: \"ArgoCD Application 同步失败过多\"        description: \"Application {{ $labels.name }} 同步失败次数 {{ $value }}\"    - alert: ArgoCDAppOutOfSync      expr: |        argocd_app_info{sync_status=\"OutOfSync\"} == 1      for: 10m      labels:        severity: warning      annotations:        summary: \"Application 长时间未同步\"        description: \"{{ $labels.name }} 已超过 10 分钟未同步\"    - alert: ArgoCDRepoServerDown      expr: |        up{job=\"argocd-repo-server\"} == 0      for: 2m      labels:        severity: critical      annotations:        summary: \"ArgoCD Repo Server 不可用\"\n```\n\n### 5.3 备份与恢复\n\n#### 5.3.1 备份策略\n\n```\n#!/bin/bash# 文件名：argocd-backup.sh# 功能：备份 ArgoCD 所有配置BACKUP_DIR=\"/backup/argocd/$(date +%Y%m%d)\"mkdir -p \"${BACKUP_DIR}\"# 备份 Applicationkubectl get applications -n argocd -o yaml > \"${BACKUP_DIR}/applications.yaml\"# 备份 AppProjectkubectl get appprojects -n argocd -o yaml > \"${BACKUP_DIR}/appprojects.yaml\"# 备份 ApplicationSetkubectl get applicationsets -n argocd -o yaml > \"${BACKUP_DIR}/applicationsets.yaml\"# 备份配置 ConfigMapkubectl get cm -n argocd argocd-cm argocd-rbac-cm argocd-cmd-params-cm -o yaml > \"${BACKUP_DIR}/configmaps.yaml\"# 备份 Secret（不含敏感数据）kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type -o yaml > \"${BACKUP_DIR}/secrets.yaml\"# 备份到远程存储tar -czf \"${BACKUP_DIR}.tar.gz\" \"${BACKUP_DIR}\"aws s3 cp \"${BACKUP_DIR}.tar.gz\" s3://backups/argocd/# 清理 7 天前的备份find /backup/argocd -name \"*.tar.gz\" -mtime +7 -deleteecho \"Backup completed: ${BACKUP_DIR}.tar.gz\"\n```\n\n#### 5.3.2 恢复流程\n\n1. 停止 ArgoCD 同步\n\n```\n# 暂停所有 Application 自动同步for app in $(argocd app list -o name); do  argocd app set $app --sync-policy nonedone\n```\n\n1. 恢复配置\n\n```\n# 解压备份tar -xzf /backup/argocd/20240315.tar.gz -C /tmp# 恢复 AppProjectkubectl apply -f /tmp/20240315/appprojects.yaml# 恢复 Applicationkubectl apply -f /tmp/20240315/applications.yaml# 恢复配置kubectl apply -f /tmp/20240315/configmaps.yaml\n```\n\n1. 验证恢复\n\n```\n# 检查 Application 状态argocd app list# 触发同步验证argocd app sync --dry-run guestbook\n```\n\n1. 重启服务\n\n```\n# 重启 ArgoCD 组件kubectl rollout restart deployment -n argocd argocd-serverkubectl rollout restart deployment -n argocd argocd-repo-serverkubectl rollout restart statefulset -n argocd argocd-application-controller\n```\n\n---\n\n## 六、总结\n\n### 6.1 技术要点回顾\n\n- ✅ GitOps 核心价值：Git 作为单一事实来源，实现配置的版本化、可审计、快速回滚，降低人为操作风险\n- ✅ ArgoCD 架构：拉模式实现持续同步，Application Controller 负责状态对账，Repo Server 处理 Git 和配置工具集成\n- ✅ Kustomize 配置管理：通过 base + overlay 机制优雅解决多环境配置差异，避免重复维护\n- ✅ 安全与权限：AppProject 实现资源隔离，RBAC 配置细粒度权限控制，SSO 集成企业认证体系\n- ✅ 高可用与性能：多副本部署、Redis HA、Application Controller 分片支持大规模集群管理\n\n### 6.2 进阶学习方向\n\n1. Argo Rollouts 渐进式交付：实现蓝绿部署、金丝雀发布，结合 Istio/Nginx 实现流量分析和自动回滚\n2. 多租户与多集群管理：使用 Cluster Secret、ApplicationSet 矩阵生成器管理数百个集群\n3. 策略即代码：集成 OPA Gatekeeper 或 Kyverno 实现准入控制、镜像扫描、资源配额自动化\n\n### 6.3 参考资料\n\n- ArgoCD 官方文档 - 完整的安装、配置、操作指南\n- Kustomize 官方文档 - 配置管理最佳实践和高级特性\n- GitOps Working Group - CNCF GitOps 标准和原则\n- Argo CD Operator - Operator 方式管理 ArgoCD 生命周期\n- ArgoCD 最佳实践 - 官方推荐的生产环境配置\n\n---\n\n## 附录\n\n### A. 命令速查表\n\n```\n# Application 管理argocd app create  --repo  --path  --dest-server  --dest-namespace argocd app get                           # 查看应用详情argocd app sync                          # 手动同步argocd app diff                          # 查看配置差异argocd app history                       # 查看同步历史argocd app rollback            # 回滚到指定版本argocd app delete                        # 删除应用argocd app set  --sync-policy automated  # 配置自动同步# 仓库管理argocd repo add  --username  --password argocd repo list                               # 列出所有仓库argocd repo rm                            # 删除仓库# 集群管理argocd cluster add               # 添加集群argocd cluster list                            # 列出所有集群argocd cluster get                 # 查看集群信息# 项目管理argocd proj create                       # 创建项目argocd proj add-source             # 添加源仓库argocd proj add-destination     # 添加目标集群\n```\n\n### B. 配置参数详解\n\n**Application 核心参数**\n：\n\n- source.repoURL：Git 仓库地址，支持 HTTPS/SSH 协议\n- source.targetRevision：分支/标签/Commit SHA，HEAD 表示默认分支\n- source.path：仓库内配置文件路径，支持 Kustomize/Helm/Plain YAML\n- destination.server：目标集群 API Server 地址，https://kubernetes.default.svc 表示当前集群\n- syncPolicy.automated.prune：自动删除 Git 中不存在的资源\n- syncPolicy.automated.selfHeal：自动修复手动修改（每 5 秒检测一次）\n- syncPolicy.syncOptions：同步选项，如 CreateNamespace、PruneLast、RespectIgnoreDifferences\n\n**AppProject 权限控制**\n：\n\n- sourceRepos：允许的 Git 仓库白名单，支持通配符\n- destinations：允许部署的目标集群和命名空间\n- clusterResourceWhitelist：允许创建的集群级资源（空数组表示禁止所有）\n- namespaceResourceWhitelist：允许创建的命名空间级资源\n\n### C. 术语表\n\n术语\n\n英文\n\n解释\n\n声明式配置\n\nDeclarative Configuration\n\n描述期望状态而非操作步骤，系统自动消除偏差\n\n同步\n\nSync\n\n将 Git 中的期望状态应用到 Kubernetes 集群\n\n对账\n\nReconciliation\n\n周期性比较实际状态与期望状态，检测漂移\n\n修剪\n\nPrune\n\n删除 Git 中不存在但集群中存在的资源\n\n自愈\n\nSelf-Heal\n\n自动撤销手动修改，恢复到 Git 定义的状态\n\n健康状态\n\nHealth Status\n\n资源的运行状态（Healthy/Progressing/Degraded/Suspended）\n\n同步状态\n\nSync Status\n\n配置的同步状态（Synced/OutOfSync）\n\n应用集\n\nApplicationSet\n\n批量生成 Application，支持多集群/多租户场景","/article/118",305,"2026-01-06 11:49:00","2026-01-06 11:49:34",{"id":200,"category_id":44,"title":201,"keywords":6,"description":202,"image_url":6,"content":203,"content_md":204,"url":205,"hits":206,"is_recommend":73,"is_top":73,"create_time":207,"update_time":208},117,"GitOps 落地实践：ArgoCD + Kustomize 实现声明式基础设施管理(一)","一、概述1.1 背景介绍GitOps 作为云原生时代的运维范式，将 Git 作为基础设施和应用配置的单一事实来源，通过声明式配置和自动化同步机制，实现了配置管理的版本控制、审计追溯和快速回滚。ArgoCD 作为 CNCF 毕业项目，提供了完整的 GitOps 工作流，支持多集群管理、RBAC 权限控制、SSO 集成等企业级特性。结合 Kustomize 的配置管理能力，能够优雅地解决多环境配置差异、敏感信息管理、配置复用等问题。在传统的 CI/CD 流程中，往往由 CI 工具直接执行 kubec","\u003Ch1 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__1\">\u003Cspan leaf=\"\">一、概述\u003C/span>\u003C/span>\u003C/h1>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__2\">\u003Cspan leaf=\"\">1.1 背景介绍\u003C/span>\u003C/span>\u003C/h3>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__3\">\u003Cspan leaf=\"\">GitOps 作为云原生时代的运维范式，将 Git 作为基础设施和应用配置的单一事实来源，通过声明式配置和自动化同步机制，实现了配置管理的版本控制、审计追溯和快速回滚。ArgoCD 作为 CNCF 毕业项目，提供了完整的 GitOps 工作流，支持多集群管理、RBAC 权限控制、SSO 集成等企业级特性。结合 Kustomize 的配置管理能力，能够优雅地解决多环境配置差异、敏感信息管理、配置复用等问题。\u003C/span>\u003C/p>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__4\">\u003Cspan leaf=\"\">在传统的 CI/CD 流程中，往往由 CI 工具直接执行 kubectl apply，这种推模式存在权限管理复杂、审计困难、状态漂移等问题。ArgoCD 采用拉模式，由运行在集群内的 Controller 主动从 Git 仓库拉取配置并应用，实现了部署权限的收敛和状态的持续同步。\u003C/span>\u003C/p>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__5\">\u003Cspan leaf=\"\">1.2 技术特点\u003C/span>\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__6\">\u003Cli>\u003Csection class=\"js_darkmode__7\">\u003Cstrong class=\"js_darkmode__8\">声明式部署\u003C/strong>\u003Cspan leaf=\"\">：基于 Kubernetes 资源清单定义期望状态，ArgoCD 自动检测并消除实际状态与期望状态的偏差\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__9\">\u003Cstrong class=\"js_darkmode__10\">多集群管理\u003C/strong>\u003Cspan leaf=\"\">：单个 ArgoCD 实例可管理数百个 Kubernetes 集群，支持集群级别的 RBAC 和资源隔离\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__11\">\u003Cstrong class=\"js_darkmode__12\">自动同步策略\u003C/strong>\u003Cspan leaf=\"\">：支持手动同步、自动同步、自动修剪(Prune)、自愈(Self-Heal)等多种策略组合\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__13\">\u003Cstrong class=\"js_darkmode__14\">回滚与审计\u003C/strong>\u003Cspan leaf=\"\">：完整记录每次同步操作，支持一键回滚到任意历史版本，所有变更可追溯到 Git commit\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__15\">\u003Cstrong class=\"js_darkmode__16\">健康检查\u003C/strong>\u003Cspan leaf=\"\">：内置对 Deployment、StatefulSet、Service、Ingress 等资源的健康检查，支持自定义健康检查脚本\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__17\">\u003Cstrong class=\"js_darkmode__18\">SSO 集成\u003C/strong>\u003Cspan leaf=\"\">：支持 OAuth2、OIDC、SAML、LDAP 等多种认证方式，可与企业统一认证系统集成\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__19\">\u003Cstrong class=\"js_darkmode__20\">渐进式交付\u003C/strong>\u003Cspan leaf=\"\">：集成 Argo Rollouts 实现蓝绿部署、金丝雀发布、流量分析等高级发布策略\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__21\">\u003Cspan leaf=\"\">1.3 适用场景\u003C/span>\u003C/span>\u003C/h3>\u003Cul class=\"list-paddingleft-1 js_darkmode__22\">\u003Cli>\u003Csection class=\"js_darkmode__23\">\u003Cspan leaf=\"\">场景一：多环境配置管理，通过 Kustomize overlay 机制管理 dev/staging/prod 等环境的配置差异，避免重复维护相似配置\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__24\">\u003Cspan leaf=\"\">场景二：多集群应用分发，使用 ApplicationSet 批量创建 Application，实现应用在多个集群、多个命名空间的标准化部署\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__25\">\u003Cspan leaf=\"\">场景三：基础设施即代码，将集群基础组件(Ingress Controller、监控栈、日志收集等)以 GitOps 方式管理，实现集群配置的版本化\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__26\">\u003Cspan leaf=\"\">场景四：合规审计与权限管控，所有变更通过 Git PR 审批，部署操作由 ArgoCD 执行，开发人员无需直接访问生产集群\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__27\">\u003Cspan leaf=\"\">场景五：灾难恢复，集群配置存储在 Git，可快速在新集群重建全部应用，Recovery Time 从小时级降至分钟级\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__28\">\u003Cspan leaf=\"\">1.4 环境要求\u003C/span>\u003C/span>\u003C/h3>\u003Csection data-tool=\"mdnice编辑器\">\u003Ctable class=\"layui-table\">\u003Cthead>\u003Ctr>\u003Cth class=\"js_darkmode__29\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">组件\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__30\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">版本要求\u003C/span>\u003C/section>\u003C/th>\u003Cth class=\"js_darkmode__31\" style=\"text-align: left;\">\u003Csection>\u003Cspan leaf=\"\">说明\u003C/span>\u003C/section>\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr class=\"js_darkmode__32\">\u003Ctd class=\"js_darkmode__33\">\u003Csection>\u003Cspan leaf=\"\">操作系统\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__34\">\u003Csection>\u003Cspan leaf=\"\">Linux 内核 4.x+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__35\">\u003Csection>\u003Cspan leaf=\"\">推荐 Ubuntu 20.04/22.04 或 RHEL 8+\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__36\">\u003Ctd class=\"js_darkmode__37\">\u003Csection>\u003Cspan leaf=\"\">Kubernetes\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__38\">\u003Csection>\u003Cspan leaf=\"\">1.24+\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__39\">\u003Csection>\u003Cspan leaf=\"\">ArgoCD 2.9+ 要求 Kubernetes 1.24+\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__40\">\u003Ctd class=\"js_darkmode__41\">\u003Csection>\u003Cspan leaf=\"\">kubectl\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__42\">\u003Csection>\u003Cspan leaf=\"\">与 K8s 版本匹配\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__43\">\u003Csection>\u003Cspan leaf=\"\">用于初始安装和手动干预\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__44\">\u003Ctd class=\"js_darkmode__45\">\u003Csection>\u003Cspan leaf=\"\">Git 仓库\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__46\">\u003Csection>\u003Cspan leaf=\"\">GitHub/GitLab/Gitea\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__47\">\u003Csection>\u003Cspan leaf=\"\">支持 HTTPS/SSH 认证，建议配置 Webhook\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__48\">\u003Ctd class=\"js_darkmode__49\">\u003Csection>\u003Cspan leaf=\"\">Kustomize\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__50\">\u003Csection>\u003Cspan leaf=\"\">内置于 kubectl\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__51\">\u003Csection>\u003Cspan leaf=\"\">ArgoCD 内置 Kustomize 5.0+\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003Ctr class=\"js_darkmode__52\">\u003Ctd class=\"js_darkmode__53\">\u003Csection>\u003Cspan leaf=\"\">硬件配置\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__54\">\u003Csection>\u003Cspan leaf=\"\">2C4G(最小)\u003C/span>\u003C/section>\u003C/td>\u003Ctd class=\"js_darkmode__55\">\u003Csection>\u003Cspan leaf=\"\">生产环境推荐 4C8G，HA 部署需 3 副本\u003C/span>\u003C/section>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/section>\u003Chr class=\"js_darkmode__56\">\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__57\">\u003Cspan leaf=\"\">二、详细步骤\u003C/span>\u003C/span>\u003C/h2>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__58\">\u003Cspan leaf=\"\">2.1 准备工作\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__59\">\u003Cspan leaf=\"\">2.1.1 系统检查\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__60\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__0 js_darkmode__61\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__62\">\u003Cspan class=\"js_darkmode__63\"># 验证 Kubernetes 集群状态\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl cluster-info\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get nodes\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl version --short\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__64\"># 检查集群资源配额\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl top nodes\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl describe quota --all-namespaces\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__65\"># 验证存储类（ArgoCD 需要持久化存储）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get storageclass\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__66\">\u003Cspan leaf=\"\">2.1.2 安装依赖\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__67\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__1 js_darkmode__68\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__69\">\u003Cspan class=\"js_darkmode__70\"># 创建 ArgoCD 命名空间\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl create namespace argocd\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__71\"># 安装 ArgoCD（使用官方稳定版本）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__72\"># 等待所有组件就绪\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl&nbsp;\u003C/span>\u003Cspan>wait\u003C/span>\u003Cspan leaf=\"\">&nbsp;--\u003C/span>\u003Cspan>for\u003C/span>\u003Cspan leaf=\"\">=condition=available --timeout=600s \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; deployment/argocd-server \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; deployment/argocd-repo-server \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; deployment/argocd-dex-server \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; deployment/argocd-redis \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; -n argocd\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__73\"># 安装 ArgoCD CLI\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">VERSION=$(curl -s https://api.github.com/repos/argoproj/argo-cd/releases/latest | grep tag_name | cut -d&nbsp;\u003C/span>\u003Cspan>'\"'\u003C/span>\u003Cspan leaf=\"\">&nbsp;-f 4)\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">curl -sSL -o argocd-linux-amd64&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"https://github.com/argoproj/argo-cd/releases/download/\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${VERSION}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">/argocd-linux-amd64\"\u003C/span>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">sudo install -m 555 argocd-linux-amd64 /usr/\u003C/span>\u003Cspan>local\u003C/span>\u003Cspan leaf=\"\">/bin/argocd\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">rm argocd-linux-amd64\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__74\"># 验证安装\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd version\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__75\">\u003Cspan leaf=\"\">2.2 核心配置\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__76\">\u003Cspan leaf=\"\">2.2.1 暴露 ArgoCD API Server\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__77\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__2 js_darkmode__78\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__79\">\u003Cspan class=\"js_darkmode__80\"># 方式一：LoadBalancer（云环境推荐）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl patch svc argocd-server -n argocd -p&nbsp;\u003C/span>\u003Cspan>'{\"spec\": {\"type\": \"LoadBalancer\"}}'\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__81\"># 方式二：Ingress（内网环境推荐）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">cat &lt;&lt;EOF | kubectl apply -f -\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">apiVersion: networking.k8s.io/v1\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kind: Ingress\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; name: argocd-server-ingress\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; namespace: argocd\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; annotations:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; nginx.ingress.kubernetes.io/ssl-passthrough:&nbsp;\u003C/span>\u003Cspan>\"true\"\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; nginx.ingress.kubernetes.io/backend-protocol:&nbsp;\u003C/span>\u003Cspan>\"HTTPS\"\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; ingressClassName: nginx\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; rules:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; - host: argocd.example.com\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; http:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; paths:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; - path: /\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; pathType: Prefix\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; backend:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; service:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: argocd-server\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; port:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: https\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; tls:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; - hosts:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; - argocd.example.com\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; secretName: argocd-server-tls\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">EOF\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__82\"># 方式三：端口转发（开发测试）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl port-forward svc/argocd-server -n argocd 8080:443\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__83\">\u003Cstrong class=\"js_darkmode__84\">说明\u003C/strong>\u003Cspan leaf=\"\">：生产环境建议使用 Ingress + TLS 证书，避免暴露 LoadBalancer 公网 IP。SSL Passthrough 保证端到端加密，ArgoCD Server 使用自签名证书或配置自定义证书。\u003C/span>\u003C/p>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__85\">\u003Cspan leaf=\"\">2.2.2 初始化 ArgoCD\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__86\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__3 js_darkmode__87\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__88\">\u003Cspan class=\"js_darkmode__89\"># 获取初始 admin 密码\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">ARGOCD_PASSWORD=$(kubectl -n argocd get secret argocd-initial-admin-secret \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; -o jsonpath=\u003C/span>\u003Cspan>\"{.data.password}\"\u003C/span>\u003Cspan leaf=\"\">&nbsp;| base64 -d)\u003C/span>\u003Cbr>\u003Cspan>echo\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"ArgoCD admin password:&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${ARGOCD_PASSWORD}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__90\"># 登录 ArgoCD\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd login argocd.example.com --username admin --password&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">\"\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">${ARGOCD_PASSWORD}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">\"\u003C/span>\u003C/span>\u003Cspan leaf=\"\">&nbsp;--grpc-web\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__91\"># 修改 admin 密码\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd account update-password\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__92\"># 删除初始密码 Secret（安全加固）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl -n argocd delete secret argocd-initial-admin-secret\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__93\">\u003Cspan leaf=\"\">2.2.3 配置 Git 仓库凭证\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__94\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__4 js_darkmode__95\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__96\">\u003Cspan class=\"js_darkmode__97\"># 方式一：HTTPS 认证（使用 Personal Access Token）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo add https://github.com/your-org/your-repo.git \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --username git \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --password ghp_xxxxxxxxxxxxxxxxxxxx \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --name my-repo\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__98\"># 方式二：SSH 认证（推荐）\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__99\"># 生成 SSH 密钥对\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">ssh-keygen -t ed25519 -C&nbsp;\u003C/span>\u003Cspan>\"argocd@example.com\"\u003C/span>\u003Cspan leaf=\"\">&nbsp;-f ~/.ssh/argocd_ed25519 -N&nbsp;\u003C/span>\u003Cspan>\"\"\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__100\"># 将公钥添加到 Git 仓库的 Deploy Keys\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">cat ~/.ssh/argocd_ed25519.pub\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__101\"># 添加私钥到 ArgoCD\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo add git@github.com:your-org/your-repo.git \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --ssh-private-key-path ~/.ssh/argocd_ed25519 \\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; --name my-repo\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__102\"># 验证仓库连接\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd repo list\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__103\">\u003Cstrong class=\"js_darkmode__104\">参数说明\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cul class=\"list-paddingleft-1 js_darkmode__105\">\u003Cli>\u003Csection class=\"js_darkmode__106\">\u003Ccode class=\"js_darkmode__107\">\u003Cspan leaf=\"\">--insecure-skip-server-verification\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：跳过 Git 服务器 TLS 验证（自签名证书场景）\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__108\">\u003Ccode class=\"js_darkmode__109\">\u003Cspan leaf=\"\">--proxy\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：配置代理服务器访问外部 Git 仓库\u003C/span>\u003C/section>\u003C/li>\u003Cli>\u003Csection class=\"js_darkmode__110\">\u003Ccode class=\"js_darkmode__111\">\u003Cspan leaf=\"\">--enable-lfs\u003C/span>\u003C/code>\u003Cspan leaf=\"\">：启用 Git LFS 支持大文件\u003C/span>\u003C/section>\u003C/li>\u003C/ul>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__112\">\u003Cspan leaf=\"\">2.3 启动和验证\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__113\">\u003Cspan leaf=\"\">2.3.1 创建 Application\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__114\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__5 js_darkmode__115\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__116\">\u003Cspan class=\"js_darkmode__117\"># application.yaml\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argoproj.io/v1alpha1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Application\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>guestbook\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__118\"># Finalizer 确保删除 Application 时同步删除已部署资源\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>finalizers:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>resources-finalizer.argocd.argoproj.io\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>project:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>default\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>source:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__119\"># Git 仓库地址\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>repoURL:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://github.com/argoproj/argocd-example-apps.git\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>targetRevision:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>HEAD\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>path:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>guestbook\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>destination:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>server:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://kubernetes.default.svc\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>default\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>syncPolicy:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>automated:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>prune:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>true\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__120\"># 自动删除 Git 中不存在的资源\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>selfHeal:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>true\u003C/span>\u003Cspan leaf=\"\">&nbsp; &nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__121\"># 自动修复手动修改\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>allowEmpty:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>false\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>syncOptions:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>CreateNamespace=true\u003C/span>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__122\"># 自动创建目标命名空间\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>retry:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>limit:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>5\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>backoff:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>duration:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>5s\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>factor:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>2\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>maxDuration:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>3m\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__123\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__6 js_darkmode__124\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__125\">\u003Cspan class=\"js_darkmode__126\"># 应用配置\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl apply -f application.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__127\"># 查看 Application 状态\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app get guestbook\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__128\"># 查看同步历史\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app&nbsp;\u003C/span>\u003Cspan>history\u003C/span>\u003Cspan leaf=\"\">&nbsp;guestbook\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__129\"># 手动触发同步\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app sync guestbook\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__130\"># 查看实时日志\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app logs guestbook --follow\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__131\">\u003Cspan leaf=\"\">2.3.2 功能验证\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__132\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__7 js_darkmode__133\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__134\">\u003Cspan class=\"js_darkmode__135\"># 验证 Application 健康状态\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app list\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__136\"># 预期输出：\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__137\"># NAME &nbsp; &nbsp; &nbsp; &nbsp;CLUSTER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NAMESPACE &nbsp;PROJECT &nbsp;STATUS &nbsp;HEALTH &nbsp; SYNCPOLICY\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__138\"># guestbook &nbsp; https://kubernetes.default.svc &nbsp;default &nbsp; &nbsp;default &nbsp;Synced &nbsp;Healthy &nbsp;Auto-Prune\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__139\"># 验证资源同步状态\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get all -n default -l app.kubernetes.io/instance=guestbook\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__140\"># 测试自愈功能（手动修改资源）\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl scale deployment guestbook-ui -n default --replicas=5\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__141\"># 等待 3 秒，ArgoCD 自动恢复副本数\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__142\"># 测试修剪功能（从 Git 删除资源）\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__143\"># 1. 从 Git 仓库删除某个 YAML 文件并提交\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__144\"># 2. 观察 ArgoCD 自动删除对应资源\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">argocd app&nbsp;\u003C/span>\u003Cspan>wait\u003C/span>\u003Cspan leaf=\"\">&nbsp;guestbook --health\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Chr class=\"js_darkmode__145\">\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__146\">\u003Cspan leaf=\"\">三、示例代码和配置\u003C/span>\u003C/span>\u003C/h2>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__147\">\u003Cspan leaf=\"\">3.1 完整配置示例\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__148\">\u003Cspan leaf=\"\">3.1.1 Kustomize 多环境配置结构\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__149\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__8 js_darkmode__150\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__151\">\u003Cspan class=\"js_darkmode__152\"># 仓库目录结构\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">├── base/\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; ├── kustomization.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; ├── deployment.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; ├── service.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; └── configmap.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">├── overlays/\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; ├── dev/\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; │ &nbsp; ├── kustomization.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; │ &nbsp; ├── replica-patch.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; │ &nbsp; └── configmap-patch.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; ├── staging/\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; │ &nbsp; ├── kustomization.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; │ &nbsp; └── resources-patch.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; └── prod/\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; &nbsp; &nbsp; ├── kustomization.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; &nbsp; &nbsp; ├── replica-patch.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; &nbsp; &nbsp; ├── hpa.yaml\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">│ &nbsp; &nbsp; &nbsp; └── pdb.yaml\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__153\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__9 js_darkmode__154\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__155\">\u003Cspan class=\"js_darkmode__156\"># base/kustomization.yaml\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>kustomize.config.k8s.io/v1beta1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Kustomization\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>resources:\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>deployment.yaml\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>service.yaml\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>configmap.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>commonLabels:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>app:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>managed-by:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>images:\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>newName:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>registry.example.com/myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>newTag:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>latest\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__157\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__10 js_darkmode__158\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__159\">\u003Cspan class=\"js_darkmode__160\"># base/deployment.yaml\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>apps/v1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Deployment\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>replicas:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>1\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>selector:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>matchLabels:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>app:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>template:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>labels:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>app:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>containers:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>image:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>ports:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>containerPort:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>8080\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>resources:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>requests:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>cpu:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>100m\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>memory:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>128Mi\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>limits:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>cpu:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>500m\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>memory:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>512Mi\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>envFrom:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>configMapRef:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp-config\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>livenessProbe:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>httpGet:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>path:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>/health\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>port:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>8080\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>initialDelaySeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>30\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>periodSeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>10\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>readinessProbe:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>httpGet:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>path:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>/ready\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>port:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>8080\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>initialDelaySeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>5\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>periodSeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>5\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__161\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__11 js_darkmode__162\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__163\">\u003Cspan class=\"js_darkmode__164\"># overlays/prod/kustomization.yaml\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>kustomize.config.k8s.io/v1beta1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Kustomization\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp-prod\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>bases:\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>../../base\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>patchesStrategicMerge:\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>replica-patch.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>resources:\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>hpa.yaml\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>pdb.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>images:\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>newTag:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>v1.2.3\u003C/span>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__165\"># 生产环境固定版本\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>configMapGenerator:\u003C/span>\u003Cbr>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp-config\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>behavior:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>merge\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>literals:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>LOG_LEVEL=info\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ENVIRONMENT=production\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>DB_POOL_SIZE=50\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__166\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__12 js_darkmode__167\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__168\">\u003Cspan class=\"js_darkmode__169\"># overlays/prod/replica-patch.yaml\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>apps/v1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Deployment\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>replicas:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>5\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>template:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>containers:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>resources:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>requests:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>cpu:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>500m\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>memory:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>1Gi\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>limits:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>cpu:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>2000m\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>memory:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>4Gi\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__170\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__13 js_darkmode__171\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__172\">\u003Cspan class=\"js_darkmode__173\"># overlays/prod/hpa.yaml\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>autoscaling/v2\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>HorizontalPodAutoscaler\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>scaleTargetRef:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>apps/v1\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Deployment\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>minReplicas:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>5\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>maxReplicas:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>20\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>metrics:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Resource\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>resource:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>cpu\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>target:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Utilization\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>averageUtilization:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>70\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Resource\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>resource:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>memory\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>target:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Utilization\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>averageUtilization:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>80\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>behavior:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>scaleDown:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>stabilizationWindowSeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>300\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>policies:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Percent\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>value:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>50\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>periodSeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>60\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>scaleUp:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>stabilizationWindowSeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>0\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>policies:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Percent\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>value:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>100\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>periodSeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>30\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Pods\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>value:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>4\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>periodSeconds:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>30\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>selectPolicy:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Max\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__174\">\u003Cspan leaf=\"\">3.1.2 ApplicationSet 批量管理\u003C/span>\u003C/span>\u003C/h4>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__175\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__14 js_darkmode__176\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__177\">\u003Cspan class=\"js_darkmode__178\"># applicationset.yaml - 多集群部署\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argoproj.io/v1alpha1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ApplicationSet\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>myapp-multi-cluster\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>generators:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>matrix:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>generators:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>git:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>repoURL:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://github.com/your-org/your-repo.git\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>revision:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>HEAD\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>directories:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>path:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>overlays/*\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>clusters:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>selector:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>matchLabels:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>environment:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>production\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>template:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">'myapp-\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{path.basename}}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">-\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{name}}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">'\u003C/span>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>project:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>default\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>source:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>repoURL:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://github.com/your-org/your-repo.git\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>targetRevision:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>HEAD\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>path:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">'\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{path}}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">'\u003C/span>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>destination:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>server:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">'\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{server}}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">'\u003C/span>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">'myapp-\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">{{path.basename}}\u003C/span>\u003C/span>\u003Cspan leaf=\"\">'\u003C/span>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>syncPolicy:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>automated:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>prune:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>true\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>selfHeal:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>true\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>syncOptions:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>CreateNamespace=true\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch3 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__179\">\u003Cspan leaf=\"\">3.2 实际应用案例\u003C/span>\u003C/span>\u003C/h3>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__180\">\u003Cspan leaf=\"\">案例一：配置敏感信息管理\u003C/span>\u003C/span>\u003C/h4>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__181\">\u003Cstrong class=\"js_darkmode__182\">场景描述\u003C/strong>\u003Cspan leaf=\"\">：使用 Sealed Secrets 或 External Secrets Operator 管理数据库密码、API Key 等敏感信息，避免明文存储在 Git 仓库。\u003C/span>\u003C/p>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__183\">\u003Cstrong class=\"js_darkmode__184\">实现代码\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__185\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__15 js_darkmode__186\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__187\">\u003Cspan class=\"js_darkmode__188\"># 安装 Sealed Secrets Controller\u003C/span>\u003Cbr>\u003Cspan>kubectl\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>apply\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-f\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__189\"># 创建 Secret 并加密\u003C/span>\u003Cbr>\u003Cspan>echo\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-n\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>'my-db-password'\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>|\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>kubectl\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>create\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>secret\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>generic\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>db-credentials\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>--dry-run=client\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>--from-file=password=/dev/stdin\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\\\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-o\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>yaml\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>|\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\\\u003C/span>\u003Cbr>\u003Cspan>kubeseal\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>-o\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>yaml\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>&gt;\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>sealed-secret.yaml\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan class=\"js_darkmode__190\"># sealed-secret.yaml（可安全提交到 Git）\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>bitnami.com/v1alpha1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>SealedSecret\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>db-credentials\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>default\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>encryptedData:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>password:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq...\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>template:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>db-credentials\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>default\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>type:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Opaque\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__191\">\u003Cstrong class=\"js_darkmode__192\">运行结果\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__193\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__16 js_darkmode__194\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__195\">\u003Cspan class=\"js_darkmode__196\"># ArgoCD 同步后自动解密为 Secret\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">kubectl get secret db-credentials -o jsonpath=\u003C/span>\u003Cspan>'{.data.password}'\u003C/span>\u003Cspan leaf=\"\">&nbsp;| base64 -d\u003C/span>\u003Cbr>\u003Cspan class=\"js_darkmode__197\"># 输出：my-db-password\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Ch4 data-tool=\"mdnice编辑器\">\u003Cspan class=\"js_darkmode__198\">\u003Cspan leaf=\"\">案例二：RBAC 权限配置\u003C/span>\u003C/span>\u003C/h4>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__199\">\u003Cstrong class=\"js_darkmode__200\">场景描述\u003C/strong>\u003Cspan leaf=\"\">：为开发团队配置只读权限，仅允许查看 dev 环境应用状态，禁止同步操作；为运维团队配置全部环境的管理权限。\u003C/span>\u003C/p>\u003Cp data-tool=\"mdnice编辑器\" class=\"js_darkmode__201\">\u003Cstrong class=\"js_darkmode__202\">实现步骤\u003C/strong>\u003Cspan leaf=\"\">：\u003C/span>\u003C/p>\u003Col class=\"list-paddingleft-1 js_darkmode__203\">\u003Cli>\u003Csection class=\"js_darkmode__204\">\u003Cspan leaf=\"\">创建 AppProject 隔离资源\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__205\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__17 js_darkmode__206\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__207\">\u003Cspan class=\"js_darkmode__208\"># project-dev.yaml\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argoproj.io/v1alpha1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>AppProject\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>dev-project\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan>spec:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>description:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Development\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>environment\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>project\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>sourceRepos:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>'https://github.com/your-org/*'\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>destinations:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>'dev-*'\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>server:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://kubernetes.default.svc\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>clusterResourceWhitelist:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>''\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Namespace\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespaceResourceWhitelist:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>'apps'\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Deployment\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>''\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Service\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>group:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>''\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ConfigMap\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>roles:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>developer\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>description:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>Read-only\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>access\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>to\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>dev\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>apps\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>policies:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>p,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>proj:dev-project:developer,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>applications,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>get,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>dev-project/*,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>allow\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>p,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>proj:dev-project:developer,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>logs,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>get,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>dev-project/*,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>allow\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>groups:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>-\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>dev-team\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Col class=\"list-paddingleft-1 js_darkmode__209\" start=\"2\">\u003Cli>\u003Csection class=\"js_darkmode__210\">\u003Cspan leaf=\"\">配置 ArgoCD RBAC\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__211\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__18 js_darkmode__212\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__213\">\u003Cspan class=\"js_darkmode__214\"># argocd-rbac-cm ConfigMap\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>v1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ConfigMap\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd-rbac-cm\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan>data:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>policy.default:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>role:readonly\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>policy.csv:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">|\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; # 运维团队全部权限\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; g, ops-team, role:admin\u003C/span>\u003Cbr>\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__215\"># 开发团队限制权限\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>p,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>role:developer,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>applications,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>get,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>*/*,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>allow\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>p,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>role:developer,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>applications,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>sync,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>dev-project/*,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>allow\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>p,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>role:developer,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>logs,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>get,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>*/*,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>allow\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>g,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>dev-team,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>role:developer\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan class=\"js_darkmode__216\"># 禁止删除生产应用\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp;&nbsp;\u003C/span>\u003Cspan>p,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>role:developer,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>applications,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>delete,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>prod-project/*,\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>deny\u003C/span>\u003Cbr>\u003C/code>\u003C/pre>\u003Col class=\"list-paddingleft-1 js_darkmode__217\" start=\"3\">\u003Cli>\u003Csection class=\"js_darkmode__218\">\u003Cspan leaf=\"\">集成 OIDC SSO（以 Keycloak 为例）\u003C/span>\u003C/section>\u003C/li>\u003C/ol>\u003Cpre data-tool=\"mdnice编辑器\" class=\"js_darkmode__219\">\u003Cspan data-cacheurl=\"\" data-remoteid=\"\" data-lazy-bgimg=\"https://mmbiz.qpic.cn/mmbiz_svg/vtnuMBibofcZATzCe7PsSEv0icicaBiccYwMleH3MZcNOqopQtIiauqbyba8ibOgZMWh5pATeHUkXz3zPZCRJTiaSpQ5RGLEGvJtxlD/640?wx_fmt=svg&amp;from=appmsg\" class=\"js_darkmode__bg__19 js_darkmode__220\" data-fail=\"0\">\u003C/span>\u003Ccode class=\"js_darkmode__221\">\u003Cspan class=\"js_darkmode__222\"># argocd-cm ConfigMap\u003C/span>\u003Cbr>\u003Cspan>apiVersion:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>v1\u003C/span>\u003Cbr>\u003Cspan>kind:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>ConfigMap\u003C/span>\u003Cbr>\u003Cspan>metadata:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>name:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd-cm\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>namespace:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>argocd\u003C/span>\u003Cbr>\u003Cspan>data:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>url:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>https://argocd.example.com\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp;&nbsp;\u003C/span>\u003Cspan>oidc.config:\u003C/span>\u003Cspan leaf=\"\">&nbsp;\u003C/span>\u003Cspan>\u003Cspan leaf=\"\">|\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; name: Keycloak\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; issuer: https://keycloak.example.com/realms/master\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; clientID: argocd\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; clientSecret: $oidc.keycloak.clientSecret\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; requestedScopes:\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; - openid\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; - profile\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; - email\u003C/span>\u003Cbr>\u003Cspan leaf=\"\">&nbsp; &nbsp; - groups\u003C/span>\u003Cbr>\u003C/span>\u003C/code>\u003C/pre>\u003Ch2 data-tool=\"mdnice编辑器\">\u003Cbr>\u003C/h2>","# 一、概述\n\n### 1.1 背景介绍\n\nGitOps 作为云原生时代的运维范式，将 Git 作为基础设施和应用配置的单一事实来源，通过声明式配置和自动化同步机制，实现了配置管理的版本控制、审计追溯和快速回滚。ArgoCD 作为 CNCF 毕业项目，提供了完整的 GitOps 工作流，支持多集群管理、RBAC 权限控制、SSO 集成等企业级特性。结合 Kustomize 的配置管理能力，能够优雅地解决多环境配置差异、敏感信息管理、配置复用等问题。\n\n在传统的 CI/CD 流程中，往往由 CI 工具直接执行 kubectl apply，这种推模式存在权限管理复杂、审计困难、状态漂移等问题。ArgoCD 采用拉模式，由运行在集群内的 Controller 主动从 Git 仓库拉取配置并应用，实现了部署权限的收敛和状态的持续同步。\n\n### 1.2 技术特点\n\n- 声明式部署：基于 Kubernetes 资源清单定义期望状态，ArgoCD 自动检测并消除实际状态与期望状态的偏差\n- 多集群管理：单个 ArgoCD 实例可管理数百个 Kubernetes 集群，支持集群级别的 RBAC 和资源隔离\n- 自动同步策略：支持手动同步、自动同步、自动修剪(Prune)、自愈(Self-Heal)等多种策略组合\n- 回滚与审计：完整记录每次同步操作，支持一键回滚到任意历史版本，所有变更可追溯到 Git commit\n- 健康检查：内置对 Deployment、StatefulSet、Service、Ingress 等资源的健康检查，支持自定义健康检查脚本\n- SSO 集成：支持 OAuth2、OIDC、SAML、LDAP 等多种认证方式，可与企业统一认证系统集成\n- 渐进式交付：集成 Argo Rollouts 实现蓝绿部署、金丝雀发布、流量分析等高级发布策略\n\n### 1.3 适用场景\n\n- 场景一：多环境配置管理，通过 Kustomize overlay 机制管理 dev/staging/prod 等环境的配置差异，避免重复维护相似配置\n- 场景二：多集群应用分发，使用 ApplicationSet 批量创建 Application，实现应用在多个集群、多个命名空间的标准化部署\n- 场景三：基础设施即代码，将集群基础组件(Ingress Controller、监控栈、日志收集等)以 GitOps 方式管理，实现集群配置的版本化\n- 场景四：合规审计与权限管控，所有变更通过 Git PR 审批，部署操作由 ArgoCD 执行，开发人员无需直接访问生产集群\n- 场景五：灾难恢复，集群配置存储在 Git，可快速在新集群重建全部应用，Recovery Time 从小时级降至分钟级\n\n### 1.4 环境要求\n\n组件\n\n版本要求\n\n说明\n\n操作系统\n\nLinux 内核 4.x+\n\n推荐 Ubuntu 20.04/22.04 或 RHEL 8+\n\nKubernetes\n\n1.24+\n\nArgoCD 2.9+ 要求 Kubernetes 1.24+\n\nkubectl\n\n与 K8s 版本匹配\n\n用于初始安装和手动干预\n\nGit 仓库\n\nGitHub/GitLab/Gitea\n\n支持 HTTPS/SSH 认证，建议配置 Webhook\n\nKustomize\n\n内置于 kubectl\n\nArgoCD 内置 Kustomize 5.0+\n\n硬件配置\n\n2C4G(最小)\n\n生产环境推荐 4C8G，HA 部署需 3 副本\n\n---\n\n## 二、详细步骤\n\n### 2.1 准备工作\n\n#### 2.1.1 系统检查\n\n```\n# 验证 Kubernetes 集群状态kubectl cluster-infokubectl get nodeskubectl version --short# 检查集群资源配额kubectl top nodeskubectl describe quota --all-namespaces# 验证存储类（ArgoCD 需要持久化存储）kubectl get storageclass\n```\n\n#### 2.1.2 安装依赖\n\n```\n# 创建 ArgoCD 命名空间kubectl create namespace argocd# 安装 ArgoCD（使用官方稳定版本）kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml# 等待所有组件就绪kubectl wait --for=condition=available --timeout=600s \\  deployment/argocd-server \\  deployment/argocd-repo-server \\  deployment/argocd-dex-server \\  deployment/argocd-redis \\  -n argocd# 安装 ArgoCD CLIVERSION=$(curl -s https://api.github.com/repos/argoproj/argo-cd/releases/latest | grep tag_name | cut -d '\"' -f 4)curl -sSL -o argocd-linux-amd64 \"https://github.com/argoproj/argo-cd/releases/download/${VERSION}/argocd-linux-amd64\"sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocdrm argocd-linux-amd64# 验证安装argocd version\n```\n\n### 2.2 核心配置\n\n#### 2.2.1 暴露 ArgoCD API Server\n\n```\n# 方式一：LoadBalancer（云环境推荐）kubectl patch svc argocd-server -n argocd -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'# 方式二：Ingress（内网环境推荐）cat\n```\n\n**说明**\n：生产环境建议使用 Ingress + TLS 证书，避免暴露 LoadBalancer 公网 IP。SSL Passthrough 保证端到端加密，ArgoCD Server 使用自签名证书或配置自定义证书。\n\n#### 2.2.2 初始化 ArgoCD\n\n```\n# 获取初始 admin 密码ARGOCD_PASSWORD=$(kubectl -n argocd get secret argocd-initial-admin-secret \\  -o jsonpath=\"{.data.password}\" | base64 -d)echo \"ArgoCD admin password: ${ARGOCD_PASSWORD}\"# 登录 ArgoCDargocd login argocd.example.com --username admin --password \"${ARGOCD_PASSWORD}\" --grpc-web# 修改 admin 密码argocd account update-password# 删除初始密码 Secret（安全加固）kubectl -n argocd delete secret argocd-initial-admin-secret\n```\n\n#### 2.2.3 配置 Git 仓库凭证\n\n```\n# 方式一：HTTPS 认证（使用 Personal Access Token）argocd repo add https://github.com/your-org/your-repo.git \\  --username git \\  --password ghp_xxxxxxxxxxxxxxxxxxxx \\  --name my-repo# 方式二：SSH 认证（推荐）# 生成 SSH 密钥对ssh-keygen -t ed25519 -C \"argocd@example.com\" -f ~/.ssh/argocd_ed25519 -N \"\"# 将公钥添加到 Git 仓库的 Deploy Keyscat ~/.ssh/argocd_ed25519.pub# 添加私钥到 ArgoCDargocd repo add git@github.com:your-org/your-repo.git \\  --ssh-private-key-path ~/.ssh/argocd_ed25519 \\  --name my-repo# 验证仓库连接argocd repo list\n```\n\n**参数说明**\n：\n\n- --insecure-skip-server-verification：跳过 Git 服务器 TLS 验证（自签名证书场景）\n- --proxy：配置代理服务器访问外部 Git 仓库\n- --enable-lfs：启用 Git LFS 支持大文件\n\n### 2.3 启动和验证\n\n#### 2.3.1 创建 Application\n\n```\n# application.yamlapiVersion: argoproj.io/v1alpha1kind: Applicationmetadata:  name: guestbook  namespace: argocd  # Finalizer 确保删除 Application 时同步删除已部署资源  finalizers:  - resources-finalizer.argocd.argoproj.iospec:  project: default  source:    # Git 仓库地址    repoURL: https://github.com/argoproj/argocd-example-apps.git    targetRevision: HEAD    path: guestbook  destination:    server: https://kubernetes.default.svc    namespace: default  syncPolicy:    automated:      prune: true      # 自动删除 Git 中不存在的资源      selfHeal: true   # 自动修复手动修改      allowEmpty: false    syncOptions:    - CreateNamespace=true  # 自动创建目标命名空间    retry:      limit: 5      backoff:        duration: 5s        factor: 2        maxDuration: 3m\n```\n\n```\n# 应用配置kubectl apply -f application.yaml# 查看 Application 状态argocd app get guestbook# 查看同步历史argocd app history guestbook# 手动触发同步argocd app sync guestbook# 查看实时日志argocd app logs guestbook --follow\n```\n\n#### 2.3.2 功能验证\n\n```\n# 验证 Application 健康状态argocd app list# 预期输出：# NAME        CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY# guestbook   https://kubernetes.default.svc  default    default  Synced  Healthy  Auto-Prune# 验证资源同步状态kubectl get all -n default -l app.kubernetes.io/instance=guestbook# 测试自愈功能（手动修改资源）kubectl scale deployment guestbook-ui -n default --replicas=5# 等待 3 秒，ArgoCD 自动恢复副本数# 测试修剪功能（从 Git 删除资源）# 1. 从 Git 仓库删除某个 YAML 文件并提交# 2. 观察 ArgoCD 自动删除对应资源argocd app wait guestbook --health\n```\n\n---\n\n## 三、示例代码和配置\n\n### 3.1 完整配置示例\n\n#### 3.1.1 Kustomize 多环境配置结构\n\n```\n# 仓库目录结构├── base/│   ├── kustomization.yaml│   ├── deployment.yaml│   ├── service.yaml│   └── configmap.yaml├── overlays/│   ├── dev/│   │   ├── kustomization.yaml│   │   ├── replica-patch.yaml│   │   └── configmap-patch.yaml│   ├── staging/│   │   ├── kustomization.yaml│   │   └── resources-patch.yaml│   └── prod/│       ├── kustomization.yaml│       ├── replica-patch.yaml│       ├── hpa.yaml│       └── pdb.yaml\n```\n\n```\n# base/kustomization.yamlapiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources:- deployment.yaml- service.yaml- configmap.yamlcommonLabels:  app: myapp  managed-by: argocdnamespace: myappimages:- name: myapp  newName: registry.example.com/myapp  newTag: latest\n```\n\n```\n# base/deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:  name: myappspec:  replicas: 1  selector:    matchLabels:      app: myapp  template:    metadata:      labels:        app: myapp    spec:      containers:      - name: myapp        image: myapp        ports:        - containerPort: 8080        resources:          requests:            cpu: 100m            memory: 128Mi          limits:            cpu: 500m            memory: 512Mi        envFrom:        - configMapRef:            name: myapp-config        livenessProbe:          httpGet:            path: /health            port: 8080          initialDelaySeconds: 30          periodSeconds: 10        readinessProbe:          httpGet:            path: /ready            port: 8080          initialDelaySeconds: 5          periodSeconds: 5\n```\n\n```\n# overlays/prod/kustomization.yamlapiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationnamespace: myapp-prodbases:- ../../basepatchesStrategicMerge:- replica-patch.yamlresources:- hpa.yaml- pdb.yamlimages:- name: myapp  newTag: v1.2.3  # 生产环境固定版本configMapGenerator:- name: myapp-config  behavior: merge  literals:  - LOG_LEVEL=info  - ENVIRONMENT=production  - DB_POOL_SIZE=50\n```\n\n```\n# overlays/prod/replica-patch.yamlapiVersion: apps/v1kind: Deploymentmetadata:  name: myappspec:  replicas: 5  template:    spec:      containers:      - name: myapp        resources:          requests:            cpu: 500m            memory: 1Gi          limits:            cpu: 2000m            memory: 4Gi\n```\n\n```\n# overlays/prod/hpa.yamlapiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata:  name: myappspec:  scaleTargetRef:    apiVersion: apps/v1    kind: Deployment    name: myapp  minReplicas: 5  maxReplicas: 20  metrics:  - type: Resource    resource:      name: cpu      target:        type: Utilization        averageUtilization: 70  - type: Resource    resource:      name: memory      target:        type: Utilization        averageUtilization: 80  behavior:    scaleDown:      stabilizationWindowSeconds: 300      policies:      - type: Percent        value: 50        periodSeconds: 60    scaleUp:      stabilizationWindowSeconds: 0      policies:      - type: Percent        value: 100        periodSeconds: 30      - type: Pods        value: 4        periodSeconds: 30      selectPolicy: Max\n```\n\n#### 3.1.2 ApplicationSet 批量管理\n\n```\n# applicationset.yaml - 多集群部署apiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata:  name: myapp-multi-cluster  namespace: argocdspec:  generators:  - matrix:      generators:      - git:          repoURL: https://github.com/your-org/your-repo.git          revision: HEAD          directories:          - path: overlays/*      - clusters:          selector:            matchLabels:              environment: production  template:    metadata:      name: 'myapp-{{path.basename}}-{{name}}'    spec:      project: default      source:        repoURL: https://github.com/your-org/your-repo.git        targetRevision: HEAD        path: '{{path}}'      destination:        server: '{{server}}'        namespace: 'myapp-{{path.basename}}'      syncPolicy:        automated:          prune: true          selfHeal: true        syncOptions:        - CreateNamespace=true\n```\n\n### 3.2 实际应用案例\n\n#### 案例一：配置敏感信息管理\n\n**场景描述**\n：使用 Sealed Secrets 或 External Secrets Operator 管理数据库密码、API Key 等敏感信息，避免明文存储在 Git 仓库。\n\n**实现代码**\n：\n\n```\n# 安装 Sealed Secrets Controllerkubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml# 创建 Secret 并加密echo -n 'my-db-password' | kubectl create secret generic db-credentials \\  --dry-run=client \\  --from-file=password=/dev/stdin \\  -o yaml | \\kubeseal -o yaml > sealed-secret.yaml# sealed-secret.yaml（可安全提交到 Git）apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata:  name: db-credentials  namespace: defaultspec:  encryptedData:    password: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq...  template:    metadata:      name: db-credentials      namespace: default    type: Opaque\n```\n\n**运行结果**\n：\n\n```\n# ArgoCD 同步后自动解密为 Secretkubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d# 输出：my-db-password\n```\n\n#### 案例二：RBAC 权限配置\n\n**场景描述**\n：为开发团队配置只读权限，仅允许查看 dev 环境应用状态，禁止同步操作；为运维团队配置全部环境的管理权限。\n\n**实现步骤**\n：\n\n1. 创建 AppProject 隔离资源\n\n```\n# project-dev.yamlapiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata:  name: dev-project  namespace: argocdspec:  description: Development environment project  sourceRepos:  - 'https://github.com/your-org/*'  destinations:  - namespace: 'dev-*'    server: https://kubernetes.default.svc  clusterResourceWhitelist:  - group: ''    kind: Namespace  namespaceResourceWhitelist:  - group: 'apps'    kind: Deployment  - group: ''    kind: Service  - group: ''    kind: ConfigMap  roles:  - name: developer    description: Read-only access to dev apps    policies:    - p, proj:dev-project:developer, applications, get, dev-project/*, allow    - p, proj:dev-project:developer, logs, get, dev-project/*, allow    groups:    - dev-team\n```\n\n1. 配置 ArgoCD RBAC\n\n```\n# argocd-rbac-cm ConfigMapapiVersion: v1kind: ConfigMapmetadata:  name: argocd-rbac-cm  namespace: argocddata:  policy.default: role:readonly  policy.csv: |    # 运维团队全部权限    g, ops-team, role:admin    # 开发团队限制权限    p, role:developer, applications, get, */*, allow    p, role:developer, applications, sync, dev-project/*, allow    p, role:developer, logs, get, */*, allow    g, dev-team, role:developer    # 禁止删除生产应用    p, role:developer, applications, delete, prod-project/*, deny\n```\n\n1. 集成 OIDC SSO（以 Keycloak 为例）\n\n```\n# argocd-cm ConfigMapapiVersion: v1kind: ConfigMapmetadata:  name: argocd-cm  namespace: argocddata:  url: https://argocd.example.com  oidc.config: |    name: Keycloak    issuer: https://keycloak.example.com/realms/master    clientID: argocd    clientSecret: $oidc.keycloak.clientSecret    requestedScopes:    - openid    - profile    - email    - groups\n```\n\n##","/article/117",310,"2026-01-06 11:45:03","2026-01-06 11:48:56",{"id":210,"category_id":44,"title":211,"keywords":212,"description":213,"image_url":6,"content":214,"content_md":215,"url":216,"hits":217,"is_recommend":73,"is_top":73,"create_time":218,"update_time":219},113,"在CentOS 7中添加命令自动补全功能","命令自动补全,centos","在CentOS 7中，默认情况下并不会安装命令补全包，需要手动安装才能使用命令补全功能。以下是在CentOS 7中安装命令补全包的方法：1. bash-completion：这是一个针对Bash shell的命令补全软件包，可以提供对系统命令、用户自定义命令和文件路径的自动补全功能。可以通过以下命令安装：```sudo yum install bash-completion```安装完成后，需要在/etc/profile配置文件中添加以下内容：```if [ -f /etc/bash_compl","\u003Cp>在CentOS 7中，默认情况下并不会安装命令补全包，需要手动安装才能使用命令补全功能。以下是在CentOS 7中安装命令补全包的方法：\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>1. bash-completion：这是一个针对Bash shell的命令补全软件包，可以提供对系统命令、用户自定义命令和文件路径的自动补全功能。可以通过以下命令安装：\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>```\u003C/p>\u003Cp>sudo yum install bash-completion\u003C/p>\u003Cp>```\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>安装完成后，需要在/etc/profile配置文件中添加以下内容：\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>```\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>if [ -f /etc/bash_completion ]; then\u003C/p>\u003Cp>&nbsp; &nbsp; . /etc/bash_completion\u003C/p>\u003Cp>fi\u003C/p>\u003Cp>```\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>2. yum-utils：这是一个包管理工具，在安装软件包时可以提供命令补全功能。可以通过以下命令安装：\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>```\u003C/p>\u003Cp>sudo yum install yum-utils\u003C/p>\u003Cp>```\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>安装完成后，即可使用yum命令的自动补全功能。\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>安装完成后，可以在命令行中输入部分命令，然后按下Tab键进行自动补全。此外，在输入文件路径时，也可以按下Tab键进行自动补全。\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>\u003Cimg src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABfEAAADmCAYAAAB1T89oAAAgAElEQVR4nO3dv24a2/c34M/31e8uaJCT5tSU7pCiVOEKhpIiTZSOdlq6ozSnoIQrIFUUiY6S+jQnEQ3X4bcAbMDYZrCxx87zSFvKn+1hz8yaAdZsr50kV4dbcTVaLq+WO212NRrNrpbL5dWouOnbKmd7/fbarLxq3dp+66qc3e67vV1N+3Paa7zeNtscXRUP9C1G94x5b7zF6Pj9Ona7jz9ms6uy9fh9q3pcRweOxf45O7xvh2On2vG94/wWo/XPPHze69te2fXWKq9md73+qHj4nG1+fqfv6fF76JjctW9V+mpvtb2y6+36HnfTZqPRgWuo2r16uz18XRzep0PvR9XeA44/F1Va1fehap8fjomFave+1/WZwPXmejt87fiMqGmapml/Xvt/udM43U4/w8Vi/fdFpv3L/P1r9edf/979k8eZp/zSz/R6+/Ane9vX27h7mU5/mt2XX2Qx7afzpcx8p2/jdt/FNP29flW3W90833+uN7z4me93bOycY/jR7Wd6vd1Fpv1OuuO9UZaX6Qynuek2zbCziZ1D4z3++N6xgXSGiyTtDEbF8TtTK6/sepuX+dLZ3946xvYDoqJT4vdWzN079OP78la9suvt+h63spj2c3nXDXXtmHv1toevi3nKy07608VOn8Vimn7nMuXWhVntPeDQufhy5/vFsaq+D1Xx6PesJ/PynwmO43rb99autw2fEQHgz1Qp6796Qn/3DBRN056uud7+xHb8DEXtaZvrTdOer73+6829Wns9zfX2VprjoGmapml/crtnJn5SlKOURev6761ilM/t3DsDBTiN6w2ej+sNno/rDZ6P6w0A4G36v3v/9107vV47vcHuP0//ee5fYYU/gOsNno/rDZ6P6w2ej+sNAOBNuncm/vjvfobTraJ4i4frDgKncb3B83G9wfNxvcHzcb0BALxN/8uqrg4AAAAAAFAz987EBwAAAAAAXo4kPgAAAAAA1JQkPgAAAAAA1NQRSfwio+Uyy+s2SnH+cdVDq8xsZ9+XWc7KtF56XHepNN5Wytkfdj7vVT3OW+Vs6/iufn5WPnN0FKMsX+J1AQAAAIBn8fZm4m8S2SOp6VflFZ63v941k9//ZZ4krfe5yCI/v89feliHvcLjCwAAAABUSeIvhuk0Gmk0uhmfcUDPqlWkHM12Zq/PZqMUm0nN8zKXjUYajUYajX6mLzrYI7y28dbKON1GI41GJ8PFMf2LfGwni1//rv7617s08zv/PXcOf9xNo9HIZVnThwcAAAAAwKO8vZn4xypGmU0G+ZB/8mWT+O708zPtDCazqE7CvfZm3herjH7+feFhAQAAAABvyxMm8XdrrLfK0fUM99mo2KvL3kpx3wz4yn03r73MctJLM0nag53a8DtVRFplZoN2MuzksjvO9Rzm+TjlZT/TNNP7emrZkSr7lrSKUWaz7Rr2h/u2WkVGs9nWPs0yKveP66laKUezre3etdXHnbflbJRyp3PF8/biturmT3ppppneZPX3QTtJs5fJY9ZNaBUpZ1vnoWit6u7fOg5bx21zHg6es3Mf3yrX/OFY97AMAAAAAO53lpn478tZJr32KmmYpNn+nE/XybpWytkkg3bz+v+TpNk8NAO+St/jFV97aS6G+bIuQdIqtpOPH5NFkov3JyRiq423GC0zGbTT3OnczuDbfhK4yNfJIO3djmn3Bpk8QZb742iSXvv6bKXd+3bg2Fbdt9t902ynN/hqId2Diowmg/SaW+dh8C1f373ooI52/zWfFKPZwVjvTWY1e1ADAAAAAPVyhiT+RT58SIb9zro2eyOd/s/8t/nv4mt6zSSLafqdTf32TvrDRZJmetsJ7KP7zlNebkriDLNIkmn/+vUbjUa6m0L+rTKf28ni5/f1gqRlvq1n5TcajXz5dZH2Tua5gkr7NlrN3s5i51g1Ov0Mf9/e9K/pMP3Obr9pkrQ/P3I2czvti816B530p0nSzIdP+1n5Cvu2rhefTDPsNHb3bfpra6MVzlst7NbNX6xjptGfJlnc7OtlmaoV6lvl56zCYXh9fDv932kfDMat49a/b+WD5zq+D13zowzazb3YaaTTnyZppv35xN9cAAAAAIA/wBmS+M38/ucy5fgmjTkfl9n8tfjYTrLI8Es3N13mGZdfVguKNt/lr1Tve7S/3qWZ5Pd6BdLiay/NTPPPelb+vPzn5AVhq+9bMu3vHqvMxym7+0ng1b+N57v9/l4n0N9VPgjbFhl+2bzePOO/V8ne5t5GTzsXF3n3qUxRFGm1bvbt/Hn5Voqt0i7L5WxV3mXrt0GK0SNKubQ+5UNzvx7+z3x/xNqyf71rZnMuNsd3Pv77yEV2X9op13wyH3dXD42aH7L/zAgAAAAAWPm/p9/kIr/uXN2zlfcXSfI7/91KeM7z3+8kzYu8byWZV+l7/Oha7y+2xrh+jZ0FSf/Nr0VWs6IrOWXfpvlxZEa7VZT5+vnDXkmdp3BovLdeveK5GKfb/5jZoJ12r7c+loNkMc3wSzflI5LdR2l9yuet0i5JM832IJP2YKvTIsO/q2y0yGg52ImL3mSZ3s3fMln2ksUwncoz8e86vvN8/7lIr/fU5/ypHXPNN/eOFwAAAABwjDPMxD8mKUwlxSiTQe8MCfwzGndz2Wik0++nP5xmusiqBvqtev/n8XvYX5cI2pT9meZmUvsi0+GX8z9M+GO45gEAAADgXM6ysO3d1rO2s561vWN/NnKVvo8cz04pmL/y7qRc+Sn71s7HBxf1bKX8vC5Hsl07v9FI59lqrZx+LubjccZlN93LzuklkKqal+mW463Z8POMy9VDhdWxu0y3cgb/fPXw7z6+rXz68Ioe3By02bdp+luxu9suPVABAAAAgDs8cxI/Gf9YLWbZ+zZKsVOj/Nt64dSb0jZV+t5y8XHrZ27MV1n76zryqxrw7XxeF0i/XmD0llWZnTQ/5NOhDZ+0b0l7MEu5vb1WkXL08Gz1VlHm271lVh4ebxWVzkWrzGhUpmht79enHJWPvuO81cfqIc9mTYXW+4tH18NPkn9/3SwQvNn/VvH1uGNWxQsc31XstDOYlXuv3UqrGGV2RLwDAAAAwJ/q2ZP42SzW2WxnMNksPDrJoH2zsOf8lL4b8+/5eetnlhltZryPf2Sa5GIz5Xle5kt/mvQmWS6X+fbu96r0yy2r+uRJM73B5PZ2K+/belHPve0tJ4P0Lh5+3cngQ34fHujx462i4rm4aPcymGzvV29Vo3764/DCtg+dt7ooPqa9VQP+r1VG/4TZ97uuF1Ru9q73fzK4OHiOW+Xs5rgOVo+cmr2tYz07kBR/yeM77qY/Xezs2yZ+JoN2mhcPbwIAAAAA/lTPn8TPPOVlJ/3pItvpycVimn5nv6xGlb5bP/Oln+nirgT3OD+mSbP3NZv85Xx8U2rlsttN9/JwWZR5eZnOTm31x+xbMu420ulPszPUxTT9vYT4rdddTDPsXObvX3cO5MjxVlFh3+ZlvnT2z8Eii2k/ne5dK/k+dN7qYXfmfZGP7WRx96quFYzT7fQzvN7/Rab9zTm+b+HYY73s8R13L2/H+iYmDj2MAwAAAACSJP9LcnV/lyKj5WCrxMw0/Ub38GzqV2O9T+uksgQidY3zYrTMoL3I8M6HVgAAAADAW/YCM/HrYJxuZ5hFe5DJbFTzGuz8KYpytLM+QqsYZbWm8eNr7gMAAAAAr9MRM/HfslaK8ms+f2ineb2A6DT9TjdjSVOe2WrW/e1/n/YbubMKEQAAAADwpv3hSXyokVaR8uvn9NrrJ0qLRab/fEnXEyUAAAAA+GNJ4gMAAAAAQE39oTXxAQAAAACg/iTxAQAAAACgpiTxAQAAAACgpp45id9KOVtmuRyleN4XhqO1ilFmy2WW6zYrW+v/KHf+fblcZjkr03rZ4fLWPCbOitFuzD5uIO7XAPdyn+QEPk/C61flOnbNA/BEzMSHbcUok0E7zZceB8CfZPMFdyQVCgB/NJ8JOJXY4TUTvxxBEh+2tN5fJEmm/U4ajUYajUYuy/nqP+dlLtf/1mj0M33BcfKGPSbOxt3dmAUA6sXnSXj9qlzHrnkAnogkPmz5610zySK//pUEBQAAAABe3gNJ/N1an63yplb4bFTcquPWKkaZzbZrvY1yd2nmIqPrvrOMisMdW60io9lsq4bcLKPy9mtvxluMZrs152ajlHdtu9J4qYczxOS6jvhyucygnSTN9CYHauKfON79mJzNRjkYkq0i5XWsr66JVrn6u9+oqrNz3iervP5DMbs9zlbK0VasVRnAVl3Pp6m9z9N76pjc2t5mzZBZmdZWHM1G+7Vdj7n3bcXupLcqY9Ye7MTyoXuf9+7X6IwxuXMPfKrPk4fHcMemD/yw+2T9vXxMVhrtGePXPbUuzvR58qjvF3es7/FAaYfjY+eY7+infSZ4WJVr87Tj8Had6zvOU+dszhU71M/Tx2QxuitG7l73qEqsPzxe8Us1R8/Ef1/OMund1Apvtj/n01agFqPZqpb4djHxZju9yexg0H0cDdK+7ttMezA50K/I18kg7d2Npt0bZHJgo8VokkG7uVvPvNlOb/D11oVXdbzUz1PH5NNrpZzdjslms53BZLZ3oy8ymgzSux5sM+3Bt3x99xzj5KnUPyZXPo4m6bW3Yq337bgv7K0ys/WHi8Wwo2zPK/C0MdnOYLNmSLOXb7Nv13HUbPfydScZcOy9r5q6XEOc7uk/T07Se/LPk8uDYxh8O2IhQvfJV+dlYrKK88Wve2o9PV1Mnu/7RZXYqfId/Zye/tr8czzlfVLOhqfwVDE5/rEqcNX+uB+oX1f3i+mPjLf/+cSYfGi8cKwjk/gX+fAhGW7VCe/0f+a/zX8XowzazWQxTb/T2OozTdJM+/P+h8Z22hfDdHb65UC/5Nd0mH7n5nUbnXUdufbnW0nQj+0kmWa4NYZGp5/h9NfuRiuPl/p5wphc1xFvNBpZheJiJ4ZO/gK+ufHvjKGT/nCRpJne1pepVvk57SRZDK/7dvq/024379w8dfPU98ljzVNerrfXP6bK5vb9t7OO+WY+PPQpohhdJ6amfYmp1+GpY3J9b+wMs0jSbP5OfyvuLt6vex9979uK3fU2M+3fvH83Gunufmr23v3qvYLPk8Vo/Vt5i51xNjr9DH8/sHvuk6/Qy8VkFWeJX/fUmnq6mNz+fnETk0/w/aJS7Bz7Hb3iZ4LKznNt/hme8j55jpzNuWOH+nnKXNCP9fvpx52HSMUqUDP9sRU8J79v3jde8Ut1V3e31lU5W14tl8urUXF3v2K0vFouZ1dl66H/22xvv+9d/364tcrZgTEVV6PlahujsrwqiuKqdce2jh+vVr/21DF56vlfx9usvGpVHsNmH0ZXxb19j9tX7aXbOWPy4TjbacXoarlcXs3K1j3j3HudVnk1Wy6vlqPijv6jq3K93eVyJhZfRTvXe/fmnrUXl3sxVOXe93AcnjJerX7t9XyeXL3Ose+77pOvt9UlJiu+z2+1x8ave2rd2tN/njz++8Ud7893vDdXi53jv6M/9LqPO67HXJvVjsNNq3Idn37Nv4WYPHvO5kljR6tfO8/37tvvnZs43b0XVI/Jivkc8asd0f4vR1nk1793/V8r7y+STR3x3lHb+53/diYnzfP95yK9Az/cKsp8/fxh71dIDxmn2/+Y2aCddq+3mnWQQbKYZvilm5vJUKeMl/p56ph8apsx7Md6kszz3+8kzYu8byWZ39V3c12Yjf861D0mNw7F5H3a6Q1ufvaHmQCvyEvEZJV73ynbrcM1xOnq/nlyM4ZpxXud++Tr9XIxWcXTx697an09VUye6/tF1dg59jv6aWMpZ9slcrKawXpw2up5rs0/w1PeJ+VseApP+949/jHNoN1eldQZj5Pi4yo2d0rpPCYm7xsvVHNkOZ2qSZ8nUowyGfSOSOCvjbu5bDTS6ffTH04zXWRVn+qYGqa8Mi8Uk3CntxyTi0yniyTtDBSgfEXeckzyOr2Sz5MncZ98nV7BffJZ4pf6eAUxWZXv6K/cE8ekeODRnjom/85wkeuSOgdL6TzKG7yv82KOnIl/n83Mumn6jW6OC/P9WXitfPrQTFYVoK7/rfzczqqm45eU45uob5WzTO6ZPTAfjzPPOONy83T+Xf66frlTxsvrUodzfN+M0/2ZMXf13VwXvH51iMlTLTLsXKacr++n7UFm5b9qPb9654rJKve+U7b7Gq8hjlOHz5ObMbSzmYx1HPfJt+lcMVnFueLXPfV1qnLenuD7xV/vcrvn6bFz/3f0U6xqSZdH9X3EtXnwOLByrnhwj+JUp8TO5jdz2vlYFFlPw9/7rTYxST0cORP/fqsVndsZzMoUO49PW2kVo8xG+09V9xb1vF4E72e+P/Au3irKfDuUwG+VGY3KFK2tV2p9yqHPKNXHy2tz/nP8b34tkjQ/5FNxeEurMTTT+zbaGkMrxejbOt5/ZfNbVf/+ulnwcdO3VXw9GL+8TqfF5MNxdn43D5vKy9VCes3et72FxXmNznWfrHLvu+XiY+4Kde/db18dPk+uxpC0B7OU24NoFSnvjDH3ybfq/DF52vv8U8Sve+rrVOW8bX+/uBWTO9bJqbTzubz+IrJ+gPS4MVT5jn7LPZ8Jqjvm2qx2HG5UuY7r8Nn+aZ0rHh51j3rS2OG1OSV25t9/ZpGkPRgcKKVz+nZPIn65x5Mk8TPupj9dJM1eBpNllstNm2QyaKd5sf8D00x/9zJZ95sM1r+u8k+59SR+9TQsaaY3mFxvczL4kN/Tw0/ML9q9DCY3fZeT3uqp+f4FWHm8vDpnP8eH43PnN+g3v5bVbG+NYbJa0TyLDL/cxPu8/Ge1KvrWeCeDiztjnVfopJh8OM5a5exmW+t7abO3dR+cPeWX8HG6/XWCdjKKghGv3LnukxXufdfm3/Pz1s/s31O9d795dfg8Oe6mv3pD3um/nAzSOyrG3CfflLPE5LaH3ufPGL/uqa9ThfO2/f3iJiYv1qW/9ja7fgB0/RlyMsiH39PD89Qrxs7R39GvB37EZ4LKjrs2Kx2HmwE//L3wpL6vxLni4ZR71Flih1fnMbGTJFlk+PeBu9O53zfFL0d4miR+knH3Mp3+NIudd7hFFtN+Oge+sP/odlZf8tf9pv1O9tegmZeX6Qy33jQX0ww7l/n714EBzMt86fQz3RnA+vUPLG5Tdby8Puc+x7fi83aPlJed9KeLnT6LxTT9zuXeQk7jdDv9DK8Hu8i0v4l1C6G8FafE5MNx9szG3XSG6j6/Fee5T1a59239zJf99/DnGi91Uv3zZD/Tp/w8mWTcbdwew2Ka/rEx5j75ppwjJrc99D5/zvh1T32djj9v932/uLXR9X1r3XPaz+VdQVZlDBW/o69/6KjPBFUddW1WPA4bVT6v1+6z/RM4VzxUv0edJ3Z4fU6Jne+bLP49v9F53vdN8ctxrjRNq2crRsur5XJ2VbZefiyapmmaVo/Wuipny6vlcnRVvPhYNC1XYlJ7Ta1Vzq6Wy+XVqHj5sZy/uTY1TdO0t9OebCY+8DhFOdqpX9oqRlmtZfZwbV8AAAAA4G36v5ceALD2rp1er53eYPef766jCgAAAAC8dWbiQ02M/+5nuL3Q1OLhOqoAAAAAwNv2v6zq6gAAAAAAADWjnA5QD1UeJ/7vbKMAAAAAgFpRTgcAAAAAAGpKEh8AAAAAAGrqiCR+kdFymeV1G6U4/7jqoVVmtrPvyyxnZVovPa67VBpvK+XsDzuf96oe561ytnV8Vz8/K585OopRli/xugAAAADAs3h7M/E3ieyR1PSr8grP21/vmsnv/zJPktb7XGSRn9/nLz2sw17h8QUAAAAAqiTxF8N0Go00Gt2MzzigZ9UqUo5mO7PXZ7NRis2k5nmZy0YjjUYjjUY/0xcd7BFe23hrZZxuo5FGo5Ph4pj+RT62k8Wvf1d//etdmvmd/547hz/uptFo5LKs6cMDAAAAAOBR3t5M/GMVo8wmg3zIP/mySXx3+vmZdgaTWVQn4V57M++LVUY//77wsAAAAACAt+UJk/i7NdZb5eh6hvtsVOzVZW+luG8GfOW+m9deZjnppZkk7cFObfidKiKtMrNBOxl2ctkd53oO83yc8rKfaZrpfT217EiVfUtaxSiz2XYN+8N9W60io9lsa59mGZX7x/VUrZSj2dZ279rq487bcjZKudO54nl7cVt18ye9NNNMb7L6+6CdpNnL5DHrJrSKlLOt81C0VnX3bx2HreO2OQ8Hz9m5j2+Va/5wrHtYBgAAAAD3O8tM/PflLJNee5U0TNJsf86n62RdK+VskkG7ef3/SdJsHpoBX6Xv8YqvvTQXw3xZlyBpFdvJx4/JIsnF+xMSsdXGW4yWmQzaae50bmfwbT8JXOTrZJD2bse0e4NMniDL/XE0Sa99fbbS7n07cGyr7tvtvmm20xt8tZDuQUVGk0F6za3zMPiWr+9edFBHu/+aT4rR7GCs9yazmj2oAQAAAIB6OUMS/yIfPiTDfmddm72RTv9n/tv8d/E1vWaSxTT9zqZ+eyf94SJJM73tBPbRfecpLzclcYZZJMm0f/36jUYj3U0h/1aZz+1k8fP7ekHSMt/Ws/IbjUa+/LpIeyfzXEGlfRutZm9nsXOsGp1+hr9vb/rXdJh+Z7ffNEnanx85m7md9sVmvYNO+tMkaebDp/2sfIV9W9eLT6YZdhq7+zb9tbXRCuetFnbr5i/WMdPoT5Msbvb1skzVCvWt8nNW4TC8Pr6d/u+0Dwbj1nHr37fywXMd34eu+VEG7eZe7DTS6U+TNNP+fOJvLgAAAADAH+AMSfxmfv9zmXJ8k8acj8ts/lp8bCdZZPilm5su84zLL6sFRZvv8leq9z3aX+/STPJ7vQJp8bWXZqb5Zz0rf17+c/KCsNX3LZn2d49V5uOU3f0k8OrfxvPdfn+vE+jvKh+EbYsMv2xeb57x36tkb3Nvo6edi4u8+1SmKIq0Wjf7dv68fCvFVmmX5XK2Ku+y9dsgxegRpVxan/KhuV8P/2e+P2Jt2b/eNbM5F5vjOx//feQiuy/tlGs+mY+7q4dGzQ/Zf2YEAAAAAKz839NvcpFfd67u2cr7iyT5nf9uJTzn+e93kuZF3reSzKv0PX50rfcXW2Ncv8bOgqT/5tciq1nRlZyyb9P8ODKj3SrKfP38Ya+kzlM4NN5br17xXIzT7X/MbNBOu9dbH8tBsphm+KWb8hHJ7qO0PuXzVmmXpJlme5BJe7DVaZHh31U2WmS0HOzERW+yTO/mb5kse8limE7lmfh3Hd95vv9cpNd76nP+1I655pt7xwsAAAAAOMYZZuIfkxSmkmKUyaB3hgT+GY27uWw00un30x9OM11kVQP9Vr3/8/g97K9LBG3K/kxzM6l9kenwy/kfJvwxXPMAAAAAcC5nWdj2butZ21nP2t6xPxu5St9HjmenFMxfeXdSrvyUfWvn44OLerZSfl6XI9mund9opPNstVZOPxfz8TjjspvuZef0EkhVzct0y/HWbPh5xuXqocLq2F2mWzmDf756+Hcf31Y+fXhFD24O2uzbNP2t2N1tlx6oAAAAAMAdnjmJn4x/rBaz7H0bpdipUf5tvXDqTWmbKn1vufi49TM35qus/XUd+VUN+HY+rwukXy8wesuqzE6aH/Lp0IZP2rekPZil3N5eq0g5eni2eqso8+3eMisPj7eKSueiVWY0KlO0tvfrU47KR99x3upj9ZBns6ZC6/3Fo+vhJ8m/v24WCN7sf6v4etwxq+IFju8qdtoZzMq9126lVYwyOyLeAQAAAOBP9exJ/GwW62y2M5hsFh6dZNC+Wdhzfkrfjfn3/Lz1M8uMNjPexz8yTXKxmfI8L/OlP016kyyXy3x793tV+uWWVX3ypJneYHJ7u5X3bb2o5972lpNBehcPv+5k8CG/Dw/0+PFWUfFcXLR7GUy296u3qlE//XF4YduHzltdFB/T3qoB/9cqo3/C7Ptd1wsqN3vX+z8ZXBw8x61ydnNcB6tHTs3e1rGeHUiKv+TxHXfTny529m0TP5NBO82LhzcBAAAAAH+q50/iZ57yspP+dJHt9ORiMU2/s19Wo0rfrZ/50s90cVeCe5wf06TZ+5pN/nI+vim1ctntpnt5uCzKvLxMZ6e2+mP2LRl3G+n0p9kZ6mKa/l5C/NbrLqYZdi7z9687B3LkeKuosG/zMl86++dgkcW0n073rpV8Hzpv9bA7877Ix3ayuHtV1wrG6Xb6GV7v/yLT/uYc37dw7LFe9viOu5e3Y30TE4cexgEAAAAASZL/Jbm6v0uR0XKwVWJmmn6je3g29aux3qd1UlkCkbrGeTFaZtBeZHjnQ6s35IE70Y7/nW0UAAAAAFArLzATvw7G6XaGWbQHmcxGNa/Bzp+iKEc76yO0ilFWaxo/vuY+AAAAAPA6HTET/y1rpSi/5vOHdprXC4hO0+90M5Y05ZmtZt3f/vdpv5E7qxC9JWbiAwAAAMAtf3gSH2qkVaT8+jm99vqJ0mKR6T9f0v1TnihJ4gMAAADALZL4AAAAAABQU39oTXwAAAAAAKg/SXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAEWEvKEAAARtSURBVKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKip/w9X01Uh2hywmwAAAABJRU5ErkJggg==\" alt=\"\">\u003C/p>","在CentOS 7中，默认情况下并不会安装命令补全包，需要手动安装才能使用命令补全功能。以下是在CentOS 7中安装命令补全包的方法：\n\n1. bash-completion：这是一个针对Bash shell的命令补全软件包，可以提供对系统命令、用户自定义命令和文件路径的自动补全功能。可以通过以下命令安装：\n\n```\n\nsudo yum install bash-completion\n\n```\n\n安装完成后，需要在/etc/profile配置文件中添加以下内容：\n\n```\n\nif [ -f /etc/bash_completion ]; then\n\n    . /etc/bash_completion\n\nfi\n\n```\n\n2. yum-utils：这是一个包管理工具，在安装软件包时可以提供命令补全功能。可以通过以下命令安装：\n\n```\n\nsudo yum install yum-utils\n\n```\n\n安装完成后，即可使用yum命令的自动补全功能。\n\n安装完成后，可以在命令行中输入部分命令，然后按下Tab键进行自动补全。此外，在输入文件路径时，也可以按下Tab键进行自动补全。\n\n![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABfEAAADmCAYAAAB1T89oAAAgAElEQVR4nO3dv24a2/c34M/31e8uaJCT5tSU7pCiVOEKhpIiTZSOdlq6ozSnoIQrIFUUiY6S+jQnEQ3X4bcAbMDYZrCxx87zSFvKn+1hz8yaAdZsr50kV4dbcTVaLq+WO212NRrNrpbL5dWouOnbKmd7/fbarLxq3dp+66qc3e67vV1N+3Paa7zeNtscXRUP9C1G94x5b7zF6Pj9Ona7jz9ms6uy9fh9q3pcRweOxf45O7xvh2On2vG94/wWo/XPPHze69te2fXWKq9md73+qHj4nG1+fqfv6fF76JjctW9V+mpvtb2y6+36HnfTZqPRgWuo2r16uz18XRzep0PvR9XeA44/F1Va1fehap8fjomFave+1/WZwPXmejt87fiMqGmapml/Xvt/udM43U4/w8Vi/fdFpv3L/P1r9edf/979k8eZp/zSz/R6+/Ane9vX27h7mU5/mt2XX2Qx7afzpcx8p2/jdt/FNP29flW3W90833+uN7z4me93bOycY/jR7Wd6vd1Fpv1OuuO9UZaX6Qynuek2zbCziZ1D4z3++N6xgXSGiyTtDEbF8TtTK6/sepuX+dLZ3946xvYDoqJT4vdWzN079OP78la9suvt+h63spj2c3nXDXXtmHv1toevi3nKy07608VOn8Vimn7nMuXWhVntPeDQufhy5/vFsaq+D1Xx6PesJ/PynwmO43rb99autw2fEQHgz1Qp6796Qn/3DBRN056uud7+xHb8DEXtaZvrTdOer73+6829Wns9zfX2VprjoGmapml/crtnJn5SlKOURev6761ilM/t3DsDBTiN6w2ej+sNno/rDZ6P6w0A4G36v3v/9107vV47vcHuP0//ee5fYYU/gOsNno/rDZ6P6w2ej+sNAOBNuncm/vjvfobTraJ4i4frDgKncb3B83G9wfNxvcHzcb0BALxN/8uqrg4AAAAAAFAz987EBwAAAAAAXo4kPgAAAAAA1JQkPgAAAAAA1NQRSfwio+Uyy+s2SnH+cdVDq8xsZ9+XWc7KtF56XHepNN5Wytkfdj7vVT3OW+Vs6/iufn5WPnN0FKMsX+J1AQAAAIBn8fZm4m8S2SOp6VflFZ63v941k9//ZZ4krfe5yCI/v89feliHvcLjCwAAAABUSeIvhuk0Gmk0uhmfcUDPqlWkHM12Zq/PZqMUm0nN8zKXjUYajUYajX6mLzrYI7y28dbKON1GI41GJ8PFMf2LfGwni1//rv7617s08zv/PXcOf9xNo9HIZVnThwcAAAAAwKO8vZn4xypGmU0G+ZB/8mWT+O708zPtDCazqE7CvfZm3herjH7+feFhAQAAAABvyxMm8XdrrLfK0fUM99mo2KvL3kpx3wz4yn03r73MctJLM0nag53a8DtVRFplZoN2MuzksjvO9Rzm+TjlZT/TNNP7emrZkSr7lrSKUWaz7Rr2h/u2WkVGs9nWPs0yKveP66laKUezre3etdXHnbflbJRyp3PF8/biturmT3ppppneZPX3QTtJs5fJY9ZNaBUpZ1vnoWit6u7fOg5bx21zHg6es3Mf3yrX/OFY97AMAAAAAO53lpn478tZJr32KmmYpNn+nE/XybpWytkkg3bz+v+TpNk8NAO+St/jFV97aS6G+bIuQdIqtpOPH5NFkov3JyRiq423GC0zGbTT3OnczuDbfhK4yNfJIO3djmn3Bpk8QZb742iSXvv6bKXd+3bg2Fbdt9t902ynN/hqId2Diowmg/SaW+dh8C1f373ooI52/zWfFKPZwVjvTWY1e1ADAAAAAPVyhiT+RT58SIb9zro2eyOd/s/8t/nv4mt6zSSLafqdTf32TvrDRZJmetsJ7KP7zlNebkriDLNIkmn/+vUbjUa6m0L+rTKf28ni5/f1gqRlvq1n5TcajXz5dZH2Tua5gkr7NlrN3s5i51g1Ov0Mf9/e9K/pMP3Obr9pkrQ/P3I2czvti816B530p0nSzIdP+1n5Cvu2rhefTDPsNHb3bfpra6MVzlst7NbNX6xjptGfJlnc7OtlmaoV6lvl56zCYXh9fDv932kfDMat49a/b+WD5zq+D13zowzazb3YaaTTnyZppv35xN9cAAAAAIA/wBmS+M38/ucy5fgmjTkfl9n8tfjYTrLI8Es3N13mGZdfVguKNt/lr1Tve7S/3qWZ5Pd6BdLiay/NTPPPelb+vPzn5AVhq+9bMu3vHqvMxym7+0ng1b+N57v9/l4n0N9VPgjbFhl+2bzePOO/V8ne5t5GTzsXF3n3qUxRFGm1bvbt/Hn5Voqt0i7L5WxV3mXrt0GK0SNKubQ+5UNzvx7+z3x/xNqyf71rZnMuNsd3Pv77yEV2X9op13wyH3dXD42aH7L/zAgAAAAAWPm/p9/kIr/uXN2zlfcXSfI7/91KeM7z3+8kzYu8byWZV+l7/Oha7y+2xrh+jZ0FSf/Nr0VWs6IrOWXfpvlxZEa7VZT5+vnDXkmdp3BovLdeveK5GKfb/5jZoJ12r7c+loNkMc3wSzflI5LdR2l9yuet0i5JM832IJP2YKvTIsO/q2y0yGg52ImL3mSZ3s3fMln2ksUwncoz8e86vvN8/7lIr/fU5/ypHXPNN/eOFwAAAABwjDPMxD8mKUwlxSiTQe8MCfwzGndz2Wik0++nP5xmusiqBvqtev/n8XvYX5cI2pT9meZmUvsi0+GX8z9M+GO45gEAAADgXM6ysO3d1rO2s561vWN/NnKVvo8cz04pmL/y7qRc+Sn71s7HBxf1bKX8vC5Hsl07v9FI59lqrZx+LubjccZlN93LzuklkKqal+mW463Z8POMy9VDhdWxu0y3cgb/fPXw7z6+rXz68Ioe3By02bdp+luxu9suPVABAAAAgDs8cxI/Gf9YLWbZ+zZKsVOj/Nt64dSb0jZV+t5y8XHrZ27MV1n76zryqxrw7XxeF0i/XmD0llWZnTQ/5NOhDZ+0b0l7MEu5vb1WkXL08Gz1VlHm271lVh4ebxWVzkWrzGhUpmht79enHJWPvuO81cfqIc9mTYXW+4tH18NPkn9/3SwQvNn/VvH1uGNWxQsc31XstDOYlXuv3UqrGGV2RLwDAAAAwJ/q2ZP42SzW2WxnMNksPDrJoH2zsOf8lL4b8+/5eetnlhltZryPf2Sa5GIz5Xle5kt/mvQmWS6X+fbu96r0yy2r+uRJM73B5PZ2K+/belHPve0tJ4P0Lh5+3cngQ34fHujx462i4rm4aPcymGzvV29Vo3764/DCtg+dt7ooPqa9VQP+r1VG/4TZ97uuF1Ru9q73fzK4OHiOW+Xs5rgOVo+cmr2tYz07kBR/yeM77qY/Xezs2yZ+JoN2mhcPbwIAAAAA/lTPn8TPPOVlJ/3pItvpycVimn5nv6xGlb5bP/Oln+nirgT3OD+mSbP3NZv85Xx8U2rlsttN9/JwWZR5eZnOTm31x+xbMu420ulPszPUxTT9vYT4rdddTDPsXObvX3cO5MjxVlFh3+ZlvnT2z8Eii2k/ne5dK/k+dN7qYXfmfZGP7WRx96quFYzT7fQzvN7/Rab9zTm+b+HYY73s8R13L2/H+iYmDj2MAwAAAACSJP9LcnV/lyKj5WCrxMw0/Ub38GzqV2O9T+uksgQidY3zYrTMoL3I8M6HVgAAAADAW/YCM/HrYJxuZ5hFe5DJbFTzGuz8KYpytLM+QqsYZbWm8eNr7gMAAAAAr9MRM/HfslaK8ms+f2ineb2A6DT9TjdjSVOe2WrW/e1/n/YbubMKEQAAAADwpv3hSXyokVaR8uvn9NrrJ0qLRab/fEnXEyUAAAAA+GNJ4gMAAAAAQE39oTXxAQAAAACg/iTxAQAAAACgpiTxAQAAAACgpp45id9KOVtmuRyleN4XhqO1ilFmy2WW6zYrW+v/KHf+fblcZjkr03rZ4fLWPCbOitFuzD5uIO7XAPdyn+QEPk/C61flOnbNA/BEzMSHbcUok0E7zZceB8CfZPMFdyQVCgB/NJ8JOJXY4TUTvxxBEh+2tN5fJEmm/U4ajUYajUYuy/nqP+dlLtf/1mj0M33BcfKGPSbOxt3dmAUA6sXnSXj9qlzHrnkAnogkPmz5610zySK//pUEBQAAAABe3gNJ/N1an63yplb4bFTcquPWKkaZzbZrvY1yd2nmIqPrvrOMisMdW60io9lsq4bcLKPy9mtvxluMZrs152ajlHdtu9J4qYczxOS6jvhyucygnSTN9CYHauKfON79mJzNRjkYkq0i5XWsr66JVrn6u9+oqrNz3iervP5DMbs9zlbK0VasVRnAVl3Pp6m9z9N76pjc2t5mzZBZmdZWHM1G+7Vdj7n3bcXupLcqY9Ye7MTyoXuf9+7X6IwxuXMPfKrPk4fHcMemD/yw+2T9vXxMVhrtGePXPbUuzvR58qjvF3es7/FAaYfjY+eY7+infSZ4WJVr87Tj8Had6zvOU+dszhU71M/Tx2QxuitG7l73qEqsPzxe8Us1R8/Ef1/OMund1Apvtj/n01agFqPZqpb4djHxZju9yexg0H0cDdK+7ttMezA50K/I18kg7d2Npt0bZHJgo8VokkG7uVvPvNlOb/D11oVXdbzUz1PH5NNrpZzdjslms53BZLZ3oy8ymgzSux5sM+3Bt3x99xzj5KnUPyZXPo4m6bW3Yq337bgv7K0ys/WHi8Wwo2zPK/C0MdnOYLNmSLOXb7Nv13HUbPfydScZcOy9r5q6XEOc7uk/T07Se/LPk8uDYxh8O2IhQvfJV+dlYrKK88Wve2o9PV1Mnu/7RZXYqfId/Zye/tr8czzlfVLOhqfwVDE5/rEqcNX+uB+oX1f3i+mPjLf/+cSYfGi8cKwjk/gX+fAhGW7VCe/0f+a/zX8XowzazWQxTb/T2OozTdJM+/P+h8Z22hfDdHb65UC/5Nd0mH7n5nUbnXUdufbnW0nQj+0kmWa4NYZGp5/h9NfuRiuPl/p5wphc1xFvNBpZheJiJ4ZO/gK+ufHvjKGT/nCRpJne1pepVvk57SRZDK/7dvq/024379w8dfPU98ljzVNerrfXP6bK5vb9t7OO+WY+PPQpohhdJ6amfYmp1+GpY3J9b+wMs0jSbP5OfyvuLt6vex9979uK3fU2M+3fvH83Gunufmr23v3qvYLPk8Vo/Vt5i51xNjr9DH8/sHvuk6/Qy8VkFWeJX/fUmnq6mNz+fnETk0/w/aJS7Bz7Hb3iZ4LKznNt/hme8j55jpzNuWOH+nnKXNCP9fvpx52HSMUqUDP9sRU8J79v3jde8Ut1V3e31lU5W14tl8urUXF3v2K0vFouZ1dl66H/22xvv+9d/364tcrZgTEVV6PlahujsrwqiuKqdce2jh+vVr/21DF56vlfx9usvGpVHsNmH0ZXxb19j9tX7aXbOWPy4TjbacXoarlcXs3K1j3j3HudVnk1Wy6vlqPijv6jq3K93eVyJhZfRTvXe/fmnrUXl3sxVOXe93AcnjJerX7t9XyeXL3Ose+77pOvt9UlJiu+z2+1x8ave2rd2tN/njz++8Ud7893vDdXi53jv6M/9LqPO67HXJvVjsNNq3Idn37Nv4WYPHvO5kljR6tfO8/37tvvnZs43b0XVI/Jivkc8asd0f4vR1nk1793/V8r7y+STR3x3lHb+53/diYnzfP95yK9Az/cKsp8/fxh71dIDxmn2/+Y2aCddq+3mnWQQbKYZvilm5vJUKeMl/p56ph8apsx7Md6kszz3+8kzYu8byWZ39V3c12Yjf861D0mNw7F5H3a6Q1ufvaHmQCvyEvEZJV73ynbrcM1xOnq/nlyM4ZpxXud++Tr9XIxWcXTx697an09VUye6/tF1dg59jv6aWMpZ9slcrKawXpw2up5rs0/w1PeJ+VseApP+949/jHNoN1eldQZj5Pi4yo2d0rpPCYm7xsvVHNkOZ2qSZ8nUowyGfSOSOCvjbu5bDTS6ffTH04zXWRVn+qYGqa8Mi8Uk3CntxyTi0yniyTtDBSgfEXeckzyOr2Sz5MncZ98nV7BffJZ4pf6eAUxWZXv6K/cE8ekeODRnjom/85wkeuSOgdL6TzKG7yv82KOnIl/n83Mumn6jW6OC/P9WXitfPrQTFYVoK7/rfzczqqm45eU45uob5WzTO6ZPTAfjzPPOONy83T+Xf66frlTxsvrUodzfN+M0/2ZMXf13VwXvH51iMlTLTLsXKacr++n7UFm5b9qPb9654rJKve+U7b7Gq8hjlOHz5ObMbSzmYx1HPfJt+lcMVnFueLXPfV1qnLenuD7xV/vcrvn6bFz/3f0U6xqSZdH9X3EtXnwOLByrnhwj+JUp8TO5jdz2vlYFFlPw9/7rTYxST0cORP/fqsVndsZzMoUO49PW2kVo8xG+09V9xb1vF4E72e+P/Au3irKfDuUwG+VGY3KFK2tV2p9yqHPKNXHy2tz/nP8b34tkjQ/5FNxeEurMTTT+zbaGkMrxejbOt5/ZfNbVf/+ulnwcdO3VXw9GL+8TqfF5MNxdn43D5vKy9VCes3et72FxXmNznWfrHLvu+XiY+4Kde/db18dPk+uxpC0B7OU24NoFSnvjDH3ybfq/DF52vv8U8Sve+rrVOW8bX+/uBWTO9bJqbTzubz+IrJ+gPS4MVT5jn7LPZ8Jqjvm2qx2HG5UuY7r8Nn+aZ0rHh51j3rS2OG1OSV25t9/ZpGkPRgcKKVz+nZPIn65x5Mk8TPupj9dJM1eBpNllstNm2QyaKd5sf8D00x/9zJZ95sM1r+u8k+59SR+9TQsaaY3mFxvczL4kN/Tw0/ML9q9DCY3fZeT3uqp+f4FWHm8vDpnP8eH43PnN+g3v5bVbG+NYbJa0TyLDL/cxPu8/Ge1KvrWeCeDiztjnVfopJh8OM5a5exmW+t7abO3dR+cPeWX8HG6/XWCdjKKghGv3LnukxXufdfm3/Pz1s/s31O9d795dfg8Oe6mv3pD3um/nAzSOyrG3CfflLPE5LaH3ufPGL/uqa9ThfO2/f3iJiYv1qW/9ja7fgB0/RlyMsiH39PD89Qrxs7R39GvB37EZ4LKjrs2Kx2HmwE//L3wpL6vxLni4ZR71Flih1fnMbGTJFlk+PeBu9O53zfFL0d4miR+knH3Mp3+NIudd7hFFtN+Oge+sP/odlZf8tf9pv1O9tegmZeX6Qy33jQX0ww7l/n714EBzMt86fQz3RnA+vUPLG5Tdby8Puc+x7fi83aPlJed9KeLnT6LxTT9zuXeQk7jdDv9DK8Hu8i0v4l1C6G8FafE5MNx9szG3XSG6j6/Fee5T1a59239zJf99/DnGi91Uv3zZD/Tp/w8mWTcbdwew2Ka/rEx5j75ppwjJrc99D5/zvh1T32djj9v932/uLXR9X1r3XPaz+VdQVZlDBW/o69/6KjPBFUddW1WPA4bVT6v1+6z/RM4VzxUv0edJ3Z4fU6Jne+bLP49v9F53vdN8ctxrjRNq2crRsur5XJ2VbZefiyapmmaVo/Wuipny6vlcnRVvPhYNC1XYlJ7Ta1Vzq6Wy+XVqHj5sZy/uTY1TdO0t9OebCY+8DhFOdqpX9oqRlmtZfZwbV8AAAAA4G36v5ceALD2rp1er53eYPef766jCgAAAAC8dWbiQ02M/+5nuL3Q1OLhOqoAAAAAwNv2v6zq6gAAAAAAADWjnA5QD1UeJ/7vbKMAAAAAgFpRTgcAAAAAAGpKEh8AAAAAAGrqiCR+kdFymeV1G6U4/7jqoVVmtrPvyyxnZVovPa67VBpvK+XsDzuf96oe561ytnV8Vz8/K585OopRli/xugAAAADAs3h7M/E3ieyR1PSr8grP21/vmsnv/zJPktb7XGSRn9/nLz2sw17h8QUAAAAAqiTxF8N0Go00Gt2MzzigZ9UqUo5mO7PXZ7NRis2k5nmZy0YjjUYjjUY/0xcd7BFe23hrZZxuo5FGo5Ph4pj+RT62k8Wvf1d//etdmvmd/547hz/uptFo5LKs6cMDAAAAAOBR3t5M/GMVo8wmg3zIP/mySXx3+vmZdgaTWVQn4V57M++LVUY//77wsAAAAACAt+UJk/i7NdZb5eh6hvtsVOzVZW+luG8GfOW+m9deZjnppZkk7cFObfidKiKtMrNBOxl2ctkd53oO83yc8rKfaZrpfT217EiVfUtaxSiz2XYN+8N9W60io9lsa59mGZX7x/VUrZSj2dZ279rq487bcjZKudO54nl7cVt18ye9NNNMb7L6+6CdpNnL5DHrJrSKlLOt81C0VnX3bx2HreO2OQ8Hz9m5j2+Va/5wrHtYBgAAAAD3O8tM/PflLJNee5U0TNJsf86n62RdK+VskkG7ef3/SdJsHpoBX6Xv8YqvvTQXw3xZlyBpFdvJx4/JIsnF+xMSsdXGW4yWmQzaae50bmfwbT8JXOTrZJD2bse0e4NMniDL/XE0Sa99fbbS7n07cGyr7tvtvmm20xt8tZDuQUVGk0F6za3zMPiWr+9edFBHu/+aT4rR7GCs9yazmj2oAQAAAIB6OUMS/yIfPiTDfmddm72RTv9n/tv8d/E1vWaSxTT9zqZ+eyf94SJJM73tBPbRfecpLzclcYZZJMm0f/36jUYj3U0h/1aZz+1k8fP7ekHSMt/Ws/IbjUa+/LpIeyfzXEGlfRutZm9nsXOsGp1+hr9vb/rXdJh+Z7ffNEnanx85m7md9sVmvYNO+tMkaebDp/2sfIV9W9eLT6YZdhq7+zb9tbXRCuetFnbr5i/WMdPoT5Msbvb1skzVCvWt8nNW4TC8Pr6d/u+0Dwbj1nHr37fywXMd34eu+VEG7eZe7DTS6U+TNNP+fOJvLgAAAADAH+AMSfxmfv9zmXJ8k8acj8ts/lp8bCdZZPilm5su84zLL6sFRZvv8leq9z3aX+/STPJ7vQJp8bWXZqb5Zz0rf17+c/KCsNX3LZn2d49V5uOU3f0k8OrfxvPdfn+vE+jvKh+EbYsMv2xeb57x36tkb3Nvo6edi4u8+1SmKIq0Wjf7dv68fCvFVmmX5XK2Ku+y9dsgxegRpVxan/KhuV8P/2e+P2Jt2b/eNbM5F5vjOx//feQiuy/tlGs+mY+7q4dGzQ/Zf2YEAAAAAKz839NvcpFfd67u2cr7iyT5nf9uJTzn+e93kuZF3reSzKv0PX50rfcXW2Ncv8bOgqT/5tciq1nRlZyyb9P8ODKj3SrKfP38Ya+kzlM4NN5br17xXIzT7X/MbNBOu9dbH8tBsphm+KWb8hHJ7qO0PuXzVmmXpJlme5BJe7DVaZHh31U2WmS0HOzERW+yTO/mb5kse8limE7lmfh3Hd95vv9cpNd76nP+1I655pt7xwsAAAAAOMYZZuIfkxSmkmKUyaB3hgT+GY27uWw00un30x9OM11kVQP9Vr3/8/g97K9LBG3K/kxzM6l9kenwy/kfJvwxXPMAAAAAcC5nWdj2butZ21nP2t6xPxu5St9HjmenFMxfeXdSrvyUfWvn44OLerZSfl6XI9mund9opPNstVZOPxfz8TjjspvuZef0EkhVzct0y/HWbPh5xuXqocLq2F2mWzmDf756+Hcf31Y+fXhFD24O2uzbNP2t2N1tlx6oAAAAAMAdnjmJn4x/rBaz7H0bpdipUf5tvXDqTWmbKn1vufi49TM35qus/XUd+VUN+HY+rwukXy8wesuqzE6aH/Lp0IZP2rekPZil3N5eq0g5eni2eqso8+3eMisPj7eKSueiVWY0KlO0tvfrU47KR99x3upj9ZBns6ZC6/3Fo+vhJ8m/v24WCN7sf6v4etwxq+IFju8qdtoZzMq9126lVYwyOyLeAQAAAOBP9exJ/GwW62y2M5hsFh6dZNC+Wdhzfkrfjfn3/Lz1M8uMNjPexz8yTXKxmfI8L/OlP016kyyXy3x793tV+uWWVX3ypJneYHJ7u5X3bb2o5972lpNBehcPv+5k8CG/Dw/0+PFWUfFcXLR7GUy296u3qlE//XF4YduHzltdFB/T3qoB/9cqo3/C7Ptd1wsqN3vX+z8ZXBw8x61ydnNcB6tHTs3e1rGeHUiKv+TxHXfTny529m0TP5NBO82LhzcBAAAAAH+q50/iZ57yspP+dJHt9ORiMU2/s19Wo0rfrZ/50s90cVeCe5wf06TZ+5pN/nI+vim1ctntpnt5uCzKvLxMZ6e2+mP2LRl3G+n0p9kZ6mKa/l5C/NbrLqYZdi7z9687B3LkeKuosG/zMl86++dgkcW0n073rpV8Hzpv9bA7877Ix3ayuHtV1wrG6Xb6GV7v/yLT/uYc37dw7LFe9viOu5e3Y30TE4cexgEAAAAASZL/Jbm6v0uR0XKwVWJmmn6je3g29aux3qd1UlkCkbrGeTFaZtBeZHjnQ6s35IE70Y7/nW0UAAAAAFArLzATvw7G6XaGWbQHmcxGNa/Bzp+iKEc76yO0ilFWaxo/vuY+AAAAAPA6HTET/y1rpSi/5vOHdprXC4hO0+90M5Y05ZmtZt3f/vdpv5E7qxC9JWbiAwAAAMAtf3gSH2qkVaT8+jm99vqJ0mKR6T9f0v1TnihJ4gMAAADALZL4AAAAAABQU39oTXwAAAAAAKg/SXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAEWEvKEAAARtSURBVKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKgpSXwAAAAAAKip/w9X01Uh2hywmwAAAABJRU5ErkJggg==)","/article/113",14948,"2023-05-16 10:54:01","2023-05-16 10:57:28",{"id":221,"category_id":44,"title":222,"keywords":223,"description":224,"image_url":6,"content":225,"content_md":226,"url":227,"hits":228,"is_recommend":73,"is_top":73,"create_time":229,"update_time":230},112,"Centos 7.x主机下的打开limits资源限制，Systemd不生效","limits,Systemd不生效","Centos 7.x环境,Systemd下的服务文件描述符限制不生效","\u003Cp>\u003Cb>一、背景\u003C/b>\u003C/p>\u003Cp>&nbsp; &nbsp; Centos 7.x环境部署服务时遇到了问题，在/etc/security/limits.conf文件中对打开文件nofile做了限制，重启系统进入用户下是生效，但是在Centos 7.x环境的Systemd下的服务却没生效。\u003C/p>\u003Cp>\u003Cb>二、原因\u003C/b>\u003C/p>\u003Cp>&nbsp; &nbsp;经分析发现/etc/security/limits.conf只对pam登录用户起作用，而若通过systemd启动服务，此配置文件不起作用。.\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20220708/0f23a79d2f54bb6d371ce5f3708e4b08.png\" alt=\"limits.png\">\u003Cbr>\u003C/p>\u003Cp>\u003Cb>三、解决\u003C/b>\u003C/p>\u003Cp>&nbsp; &nbsp;对于systemd启动的服务，按照优先级（后者覆盖前者）起作用的是：\u003C/p>\u003Cp>/etc/systemd/system.conf ：设置系统级服务全局默认值（需重启系统生效），如：\u003C/p>\u003Cp>[root@VM-32-96-centos systemd]# vi /etc/systemd/system.conf&nbsp;\u003C/p>\u003Cp>...\u003C/p>\u003Cp>DefaultLimitNOFILE=50000\u003C/p>\u003Cp>...\u003C/p>\u003Cp>服务本身，如mysql进程：\u003C/p>\u003Cp>% vi /usr/lib/systemd/system/gateway-go.service\u003C/p>\u003Cp>[Service]\u003C/p>\u003Cp>...\u003C/p>\u003Cp>LimitNOFILE = 20000\u003C/p>\u003Cp>...\u003C/p>\u003Cp>[root@VM-32-96-centos systemd]# systemctl deamon-reload\u003C/p>\u003Cp>[root@VM-32-96-centos systemd]# systemctl restart gateway-go\u003C/p>\u003Cp>检查：\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>[root@VM-32-96-centos systemd]# cat /proc/12010/limits&nbsp;\u003C/p>\u003Cp>Limit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Soft Limit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Hard Limit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Units&nbsp; &nbsp; &nbsp;\u003C/p>\u003Cp>Max open files&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20000&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20000&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; files&nbsp;\u003C/p>\u003Cp>...\u003C/p>\u003Cp>注意：上面只是争对系统级服务，即使用systemctl start/stop管理的服务，而对于systemctl --user管理的用户级服务（非常少用，且需要特殊配置），环境变量或limits限制由如下文件限制：\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>1、~/.config/systemd/user.conf：对于有HOME的用户，可再此目录配置；\u003C/p>\u003Cp>2、/etc/systemd/user.conf：用户级别默认配置；\u003C/p>\u003Cp>3、/etc/systemd/system/user@.service.d/：对于所有用户级别管理的服务生效；\u003C/p>\u003Cp>4、/etc/systemd/system/user@&lt;uid&gt;.service.d：对于特定用户生效；\u003C/p>\u003Cp>\u003C/p>","**一、背景**\n\n    Centos 7.x环境部署服务时遇到了问题，在/etc/security/limits.conf文件中对打开文件nofile做了限制，重启系统进入用户下是生效，但是在Centos 7.x环境的Systemd下的服务却没生效。\n\n**二、原因**\n\n   经分析发现/etc/security/limits.conf只对pam登录用户起作用，而若通过systemd启动服务，此配置文件不起作用。.\n\n![limits.png](/uploads/layedit/20220708/0f23a79d2f54bb6d371ce5f3708e4b08.png)\n\n**三、解决**\n\n   对于systemd启动的服务，按照优先级（后者覆盖前者）起作用的是：\n\n/etc/systemd/system.conf ：设置系统级服务全局默认值（需重启系统生效），如：\n\n[root@VM-32-96-centos systemd]# vi /etc/systemd/system.conf \n\n...\n\nDefaultLimitNOFILE=50000\n\n...\n\n服务本身，如mysql进程：\n\n% vi /usr/lib/systemd/system/gateway-go.service\n\n[Service]\n\n...\n\nLimitNOFILE = 20000\n\n...\n\n[root@VM-32-96-centos systemd]# systemctl deamon-reload\n\n[root@VM-32-96-centos systemd]# systemctl restart gateway-go\n\n检查：\n\n[root@VM-32-96-centos systemd]# cat /proc/12010/limits \n\nLimit                     Soft Limit           Hard Limit           Units     \n\nMax open files            20000                20000                files \n\n...\n\n注意：上面只是争对系统级服务，即使用systemctl start/stop管理的服务，而对于systemctl --user管理的用户级服务（非常少用，且需要特殊配置），环境变量或limits限制由如下文件限制：\n\n1、~/.config/systemd/user.conf：对于有HOME的用户，可再此目录配置；\n\n2、/etc/systemd/user.conf：用户级别默认配置；\n\n3、/etc/systemd/system/user@.service.d/：对于所有用户级别管理的服务生效；\n\n4、/etc/systemd/system/user@.service.d：对于特定用户生效；","/article/112",5588,"2022-07-08 12:03:43","2022-07-08 12:11:28",{"id":232,"category_id":44,"title":233,"keywords":234,"description":235,"image_url":6,"content":236,"content_md":237,"url":238,"hits":239,"is_recommend":73,"is_top":73,"create_time":240,"update_time":241},109,"CentOS7 开启 NSCD 缓存服务减少DNS集群请求压力","NSCD、DNS缓存、centos7","CentOS7 开启 NSCD 缓存服务以减少集群压力","\u003Cp>一、介绍：\u003C/p>\u003Cp>&nbsp; &nbsp; nscd（Name Service Cache Daemon）是一种能够缓存 passwd、group、hosts 的本地缓存服务，分别对应三个源 /etc/passwd、/etc/hosts、/etc/resolv.conf。其最为明显的作用就是加快 DNS 解析速度，在接口调用频繁的内网环境建议开启。默认Linux服务器是不会对DNS解析记录进行缓存的，系统安装了nscd之后，几乎所有的DNS查询都会经过nscd，可以避免很多重复的DNS查询。\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>二、开启NSCD DNS缓存服务的优点和缺点：\u003C/p>\u003Cp>1、优点\u003C/p>\u003Cp>&nbsp; &nbsp; 本地缓存DNS解析信息，提供解析速度。\u003C/p>\u003Cp>&nbsp; &nbsp; DNS服务挂了也没有问题，在缓存服务时间范围内，解析依旧正常。\u003C/p>\u003Cp>2、缺点\u003C/p>\u003Cp>&nbsp; &nbsp; DNS解析信息会滞后，如域名解析更改需要手动刷新缓存，NSCD不适合做实时的切换的应用，目前对于依赖DNS切换的服务，建议不要开启DNS缓存。\u003C/p>\u003Cp>&nbsp; &nbsp; DNS Cache作为普通的DNS解析Cache那是没问题的，如果你使用RDS云服务器，也不建议使用DNS缓存服务。\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>三、 安装配置\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>yum install -y nscd\u003C/p>\u003Cp>systemctl enable nscd\u003C/p>\u003Cp>systemctl start nscd\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>有需要的话还可以配置一下nscd， /etc/nscd.conf\u003C/p>\u003Cp>#设置日志文件\u003C/p>\u003Cp>logfile debug-file-name\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#设置debug记录的级别，默认是0\u003C/p>\u003Cp>debug-level value\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#程序启动时，等待进去请求的处理线程数，至少5个\u003C/p>\u003Cp>threads number\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#最大线程数，默认32\u003C/p>\u003Cp>max-threads number\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#nscd程序以哪个用户运行,如果设置了该选项，nscd将作为该用户运行，\u003C/p>\u003Cp>#而不是作为root。如果每个用户都使用一个单独的缓存(-S参数)，将忽略该选项。\u003C/p>\u003Cp>server-user user\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#哪个用户可以请求统计用户\u003C/p>\u003Cp>stat-user user\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#在一个缓存项被删除之前允许使用的次数，默认是5\u003C/p>\u003Cp>reload-count unlimited | number\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#是否启用偏执模式，启用会导致nscd周期性重启，默认是no\u003C/p>\u003Cp>paranoia &lt;yes|no&gt;\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#如果启用偏执模式，设置的定期重启nscd的时间间隔，默认是3600秒\u003C/p>\u003Cp>restart-interval time\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#开启或者关闭服务缓存，默认是no\u003C/p>\u003Cp>enable-cache service &lt;yes|no&gt;\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#为成功请求的元素设置缓存TTL，单位是秒，值越大缓存命中率越高，\u003C/p>\u003Cp>#降低平均响应时间，但会增加缓存的一致性问题\u003C/p>\u003Cp>positive-time-to-live service value\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#为失败查询元素设置缓存TTL，单位是秒，应保持小值，减小缓存一致性问题\u003C/p>\u003Cp>negative-time-to-live service value\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#内部的散列表大小，value应该保持一个素数以达到优化效果。默认值是211\u003C/p>\u003Cp>suggested-size service value\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#启用或者禁用检查文件是否属于指定的服务，这些文件是/etc/passwd、/etc/group、\u003C/p>\u003Cp>#/etc/hosts、/etc/services、/etc/netgroup等\u003C/p>\u003Cp>check-files service &lt;yes|no&gt;\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#设置缓存在服务器重启后，仍旧能提供缓存服务，在使用偏执模式时有用，默认是no\u003C/p>\u003Cp>persistent service &lt;yes|no&gt;\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#为客户端共享nscd数据库在内存中做的映射，使客户端可以直接搜索，\u003C/p>\u003Cp>#而不用每次都查询守护进行，默认是no\u003C/p>\u003Cp>shared service &lt;yes|no&gt;\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#该数据库的最大大小，单位是bytes，默认是33554432\u003C/p>\u003Cp>max-db-size service bytes\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>#此选项仅使用于passwd和group服务\u003C/p>\u003Cp>auto-propagate service &lt;yes|no&gt;\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>四、常规命令\u003C/p>\u003Cp>nscd -g&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //查看命中数\u003C/p>\u003Cp>nscd -i hosts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //清除缓存\u003C/p>\u003Cdiv>\u003Cbr>\u003C/div>","一、介绍：\n\n    nscd（Name Service Cache Daemon）是一种能够缓存 passwd、group、hosts 的本地缓存服务，分别对应三个源 /etc/passwd、/etc/hosts、/etc/resolv.conf。其最为明显的作用就是加快 DNS 解析速度，在接口调用频繁的内网环境建议开启。默认Linux服务器是不会对DNS解析记录进行缓存的，系统安装了nscd之后，几乎所有的DNS查询都会经过nscd，可以避免很多重复的DNS查询。\n\n二、开启NSCD DNS缓存服务的优点和缺点：\n\n1、优点\n\n    本地缓存DNS解析信息，提供解析速度。\n\n    DNS服务挂了也没有问题，在缓存服务时间范围内，解析依旧正常。\n\n2、缺点\n\n    DNS解析信息会滞后，如域名解析更改需要手动刷新缓存，NSCD不适合做实时的切换的应用，目前对于依赖DNS切换的服务，建议不要开启DNS缓存。\n\n    DNS Cache作为普通的DNS解析Cache那是没问题的，如果你使用RDS云服务器，也不建议使用DNS缓存服务。\n\n三、 安装配置\n\nyum install -y nscd\n\nsystemctl enable nscd\n\nsystemctl start nscd\n\n有需要的话还可以配置一下nscd， /etc/nscd.conf\n\n#设置日志文件\n\nlogfile debug-file-name\n\n \n\n#设置debug记录的级别，默认是0\n\ndebug-level value\n\n \n\n#程序启动时，等待进去请求的处理线程数，至少5个\n\nthreads number\n\n \n\n#最大线程数，默认32\n\nmax-threads number\n\n \n\n#nscd程序以哪个用户运行,如果设置了该选项，nscd将作为该用户运行，\n\n#而不是作为root。如果每个用户都使用一个单独的缓存(-S参数)，将忽略该选项。\n\nserver-user user\n\n \n\n#哪个用户可以请求统计用户\n\nstat-user user\n\n \n\n#在一个缓存项被删除之前允许使用的次数，默认是5\n\nreload-count unlimited | number\n\n \n\n#是否启用偏执模式，启用会导致nscd周期性重启，默认是no\n\nparanoia\n\n \n\n#如果启用偏执模式，设置的定期重启nscd的时间间隔，默认是3600秒\n\nrestart-interval time\n\n \n\n#开启或者关闭服务缓存，默认是no\n\nenable-cache service\n\n \n\n#为成功请求的元素设置缓存TTL，单位是秒，值越大缓存命中率越高，\n\n#降低平均响应时间，但会增加缓存的一致性问题\n\npositive-time-to-live service value\n\n \n\n#为失败查询元素设置缓存TTL，单位是秒，应保持小值，减小缓存一致性问题\n\nnegative-time-to-live service value\n\n \n\n#内部的散列表大小，value应该保持一个素数以达到优化效果。默认值是211\n\nsuggested-size service value\n\n \n\n#启用或者禁用检查文件是否属于指定的服务，这些文件是/etc/passwd、/etc/group、\n\n#/etc/hosts、/etc/services、/etc/netgroup等\n\ncheck-files service\n\n \n\n#设置缓存在服务器重启后，仍旧能提供缓存服务，在使用偏执模式时有用，默认是no\n\npersistent service\n\n \n\n#为客户端共享nscd数据库在内存中做的映射，使客户端可以直接搜索，\n\n#而不用每次都查询守护进行，默认是no\n\nshared service\n\n \n\n#该数据库的最大大小，单位是bytes，默认是33554432\n\nmax-db-size service bytes\n\n \n\n#此选项仅使用于passwd和group服务\n\nauto-propagate service\n\n四、常规命令\n\nnscd -g                //查看命中数\n\nnscd -i hosts          //清除缓存","/article/109",10564,"2021-12-28 20:59:03","2021-12-28 21:04:48",{"id":243,"category_id":44,"title":244,"keywords":245,"description":246,"image_url":6,"content":247,"content_md":248,"url":249,"hits":250,"is_recommend":73,"is_top":73,"create_time":251,"update_time":252},108,"挖矿木马自助清理手册","木马,自助,清理,手册","一、什么是挖矿木马挖矿木马会占用CPU进行超频运算，从而占用主机大量的CPU资源，严重影响服务器上的其他应用的正常运行。黑客为了得到更多的算力资源，一般都会对全网进行无差别扫描，同时利用SSH爆破和漏洞利用等手段攻击主机。部分挖矿木马还具备蠕虫化的特点，在主机被成功入侵之后，挖矿木马还会向内网渗透，并在被入侵的服务器上持久化驻留以获取最大收益。挖矿木马的整体攻击流程大致如下图所示：二、挖矿木马中招特征挖矿木马会在用户不知情的情况下利用主机的算力进行挖矿，最明显的特征就是主机的CPU被大量消耗，查","\u003Csection data-mpa-template=\"t\" mpa-from-tpl=\"t\" style=\"text-align: justify;\">\u003Csection mpa-from-tpl=\"t\" style=\"text-align: center;\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Cp>\u003Cspan>\u003Cem>\u003Cstrong mpa-from-tpl=\"t\" mpa-is-content=\"t\">一、什么是挖矿木马\u003C/strong>\u003C/em>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp>\u003Cbr>\u003C/p>\u003C/section>\u003Csection style=\"text-align: justify;\">\u003Cspan>&nbsp; &nbsp;挖矿木马会占用CPU进行超频运算，从而占用主机大量的CPU资源，严重影响服务器上的其他应用的正常运行。黑客为了得到更多的算力资源，一般都会对全网进行无差别扫描，同时利用SSH爆破和漏洞利用等手段攻击主机。\u003C/span>\u003Cbr>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>部分挖矿木马还具备蠕虫化的特点，在主机被成功入侵之后，挖矿木马还会向内网渗透，并在被入侵的服务器上持久化驻留以获取最大收益。\u003Cbr>\u003Cbr>\u003C/span>\u003C/p>\u003Cp>\u003Cspan>挖矿木马的整体攻击流程大致如下图所示：\u003C/span>\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20211110/73a83cf25324be000806d35145752664.jpg\" alt=\"1.jpg\" style=\"text-align: center;\">\u003C/p>\u003Cp>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"24938\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Cp>\u003Cbr mpa-from-tpl=\"t\">\u003C/p>\u003Csection data-mpa-template=\"t\" mpa-from-tpl=\"t\">\u003Cp>\u003Cbr>\u003C/p>\u003Csection mpa-from-tpl=\"t\" style=\"text-align: center;\">\u003Cp>\u003Cbr>\u003C/p>\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Cp>\u003Cspan>\u003Cem>\u003Cstrong mpa-from-tpl=\"t\" mpa-is-content=\"t\">二、挖矿木马中招特征\u003C/strong>\u003C/em>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp>\u003Cbr>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>挖矿木马会在用户不知情的情况下利用主机的算力进行挖矿，最明显的特征就是主机的CPU被大量消耗，查看云主机CPU占用率的方法有两种：\u003C/span>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cstrong>控制台实例监控\u003C/strong>\u003C/p>\u003Cp>\u003Cstrong>\u003Cimg src=\"/uploads/layedit/20211110/d68438c0482915789a8059a78e24cf78.jpg\" alt=\"2.jpg\">\u003Cbr>\u003C/strong>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cstrong>主机执行TOP命令\u003C/strong>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>如下图所示，通过执行top命令，即可在返回结果中看到当时系统的CPU占用率。\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">top\u003C/span> -c\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/ab5fcddaf033a9836e9043cc42854e2c.jpg\" alt=\"3 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>如果云主机CPU占用率居高不下，那么主机很有可能已经被植入了挖矿木马，会影响服务器上的其他应用的正常运行，需要立刻上机排查。\u003C/span>\u003C/p>\u003Csection data-mpa-template=\"t\" mpa-from-tpl=\"t\" style=\"text-align: justify;\">\u003Csection mpa-from-tpl=\"t\" style=\"text-align: center;\">\u003Cp>\u003Cbr>\u003C/p>\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Cp>\u003Cspan>\u003Cem>\u003Cstrong mpa-from-tpl=\"t\" mpa-is-content=\"t\">三、清理挖矿木马\u003C/strong>\u003C/em>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp>\u003Cspan>\u003C/span>\u003C/p>\u003C/section>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection data-form=\"0\" data-num=\"1\" style=\"text-align: center;\">\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cstrong>1、及时隔离主机\u003C/strong>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>部分带有蠕虫功能的挖矿木马在取得主机的控制权后，会继续对公网的其他主机，或者以当前主机作为跳板机对同一局域网内的其他主机进行横向渗透，所以在发现主机被植入挖矿木马后，在不影响业务正常运行的前提下，应该及时隔离受感染的主机，然后进行下一步分析和清除工作。\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>腾讯云主机可以通过设置安全组隔离主机，具体参考如下链接：\u003C/span>\u003Cspan>\u003Cem>https://cloud.tencent.com/document/product/215/20089\u003C/em>\u003C/span>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Csection>\u003Csection>\u003Cstrong>\u003Cspan>2、阻断异常网络通信\u003C/span>\u003C/strong>\u003C/section>\u003C/section>\u003Cp>\u003Cbr>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>挖矿木马不仅会连接矿池，还有可能会连接黑客的C2服务器，接收并执行C2指令、投递其他恶意木马，所以需要及时进行网络阻断。\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>（1）检查主机防火墙当前生效的iptables规则中是否存在业务范围之外的可疑地址和端口，它们可能是挖矿木马的矿池或C2地址\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">iptables\u003C/span> -L -n\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>（2）从iptables规则中清除可疑地址和端口\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">vi\u003C/span> /etc/sysconfig/iptables\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>（3）阻断挖矿木马的网络通信\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003Cbr>\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"sql\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">iptables -A INPUT -s 可疑地址 -j \u003Cspan class=\"code-snippet__keyword\">DROP\u003C/span>\u003C/span>\u003C/code>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">iptables -A \u003Cspan class=\"code-snippet__keyword\">OUTPUT\u003C/span> -d 可疑地址 -j \u003Cspan class=\"code-snippet__keyword\">DROP\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cspan>\u003Cstrong>3、清除计划任务\u003C/strong>\u003C/span>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp>\u003Cbr>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>大部分挖矿木马会通过在受感染主机中写入计划任务实现持久化，如果仅仅只是清除挖矿进程，无法将其根除，到了预设的时间点，系统会通过计划任务从黑客的C2服务器重新下载并执行挖矿木马。\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>挖矿木马常见的计划任务通常是下载并执行sh脚本，如下图所示:\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>\u003Cimg src=\"/uploads/layedit/20211110/0c2e3c4bc6a62c916a6e21967b68a725.png\" alt=\"4.png\">\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>可以通过执行如下命令查看是否存在可疑定时任务，若有，则先保存相关记录用于后续分析，再进行删除：\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>查看系统当前用户的计划任务：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">crontab\u003C/span> -l\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>查看系统特定用户的计划任务：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">crontab\u003C/span> -u username -l\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>查看其他计划任务文件：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc/crontab\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/var/spool/cron\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc/anacrontab\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc/cron.d/\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc/cron.daily/\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc/cron.hourly/\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc/cron.weekly/\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc/cron.monthly/\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cat\u003C/span> \u003Cspan class=\"code-snippet__string\">/var/spool/cron/\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003C/section>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cspan>\u003Cstrong>4、清除启动项\u003C/strong>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>除了计划任务，挖矿木马通过添加启动项同样能实现持久化。可以使用如下命令查看开机启动项中是否有异常的启动服务。\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>CentOS7以下版本：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"cpp\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">chkconfig –\u003Cspan class=\"code-snippet__built_in\">list\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>CentOS7及以上版本：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"cpp\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">systemctl \u003Cspan class=\"code-snippet__built_in\">list\u003C/span>-unit-files\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>如果发现有恶意启动项，可以通过如下命令进行关闭：\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>CentOS7以下版本：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">chkconfig\u003C/span> 服务名 \u003Cspan class=\"code-snippet__literal\">off\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>CentOS7及以上版本：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"bash\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">systemctl \u003Cspan class=\"code-snippet__built_in\">disable\u003C/span> 服务名\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>另外，还需要仔细排查以下目录及文件，及时删除可疑的启动项：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003Cbr>\u003C/li>\u003C/ul>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">/usr/lib/systemd/system\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">/usr/lib/systemd/system/multi-user.target.wants\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">/etc/rc.local\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">/etc/inittab\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">/etc/rc0.d/\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>rc1.d/\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>rc2.d/\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>rc3.d/\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>rc4.d/\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>rc5.d/\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>rc6.d/\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>rc.d/\u003C/span>\u003C/code>\u003C/p>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>排查的时候，可以按照文件修改时间来排序，重点排查近期被创建服务项。如下图所示，系统近期被创建了一个名为bot.service的服务，该服务在系统启动时会启动/etc/kinsing这个木马文件，需要关闭bot服务，并删除/etc/kinsing文件。\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/3cd9e620ab95ebe7de5ca4753f69c5e5.jpg\" alt=\"5.jpg\">\u003Cbr>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cimg src=\"/uploads/layedit/20211110/1fbc612b14c0914856f326a2537f279c.jpg\" alt=\"6 (2).jpg\">\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cbr>\u003C/p>\u003Csection>\u003Csection>\u003Cspan>\u003Cstrong>5、清除预加载so\u003C/strong>\u003C/span>\u003C/section>\u003C/section>\u003Cp>\u003Cbr>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Csection style=\"text-align: justify;\">\u003Cspan>通\u003C/span>\u003Cspan>\u003C/span>\u003Cspan>过配置/etc/ld.so.preload，可以自定义程序运行前优先加载的动态链接库，部分木马通过修改该文\u003C/span>\u003Cspan>件，添加恶意so文件，从而实现挖矿进程的隐藏等恶意功能。\u003Cbr>\u003C/span>\u003Cp>\u003Cspan>检查/etc/ld.so.preload（该文件默认为空），清除异常的动态链接库。可以执行`&gt; /etc/ld.so.preload`命令进行清除。\u003C/span>\u003C/p>\u003Cp>\u003Cspan>\u003Cimg src=\"/uploads/layedit/20211110/58655aa5bbb2e5b77eb4d4fc24df6ccf.jpg\" alt=\"7 (2).jpg\">\u003Cbr>\u003C/span>\u003C/p>\u003C/section>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection data-form=\"0\" data-num=\"1\" style=\"text-align: center;\">\u003Cbr>\u003C/section>\u003C/section>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cstrong>6、清除SSH公钥\u003C/strong>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp>\u003Cbr>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>挖矿木马通常还会在~/.ssh/authoruzed_keys文件中写入黑客的SSH公钥，这样子就算用户将挖矿木马清除得一干二净，黑客还是可以免密登陆该主机，这也是常见的保持服务器控制权的手段。\u003Cbr>\u003C/span>\u003Cspan>\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>排查~/.ssh/authorized_keys文件，如果发现可疑的SSH公钥，直接删除。\u003C/span>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cstrong>7、清除挖矿木马\u003C/strong>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cstrong>\u003Cspan>（1）清除挖矿进程\u003C/span>\u003C/strong>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>挖矿木马最大的特点就是会在用户不知情的情况下，利用主机的算力进行挖矿，从而消耗主机大量的CPU资源，所以，通过执行如下命令排查系统中占用大量CPU资源的进程。\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003Cbr>\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"properties\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">top\u003C/span> \u003Cspan class=\"code-snippet__string\">-c\u003C/span>\u003C/span>\u003C/code>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">ps\u003C/span> \u003Cspan class=\"code-snippet__string\">-ef\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/6aa247d8242572deda75a4e080895c92.jpg\" alt=\"8 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>确认相关进程为挖矿进程后，按照如下步骤将其清除：\u003Cbr>获取并记录挖矿进程的文件路径：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">ls\u003C/span> -l /proc/\u003Cspan class=\"code-snippet__variable\">$PID\u003C/span>/exe\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>杀死挖矿进程：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"bash\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__built_in\">kill\u003C/span> -9 \u003Cspan class=\"code-snippet__variable\">$PID\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>删除挖矿进程对应的文件\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/2c0d016376dd6e9726aa9610bab964e2.jpg\" alt=\"9 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cstrong>\u003Cspan>（2）清除其它相关恶意进程\u003C/span>\u003C/strong>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>恶意进程与外部的C2服务器进行通信时，往往会开启端口进行监听。执行如下命令，查看服务器是否有未被授权的端口被监听。\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">netstat\u003C/span> -antp\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/67e15d39d20688f80b8f9ec64675a72e.jpg\" alt=\"10 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>若有未授权进程，按照如下步骤将其清除：\u003Cbr>获取并记录未授权进程的文件路径：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">ls\u003C/span> -l /proc/\u003Cspan class=\"code-snippet__variable\">$PID\u003C/span>/exe\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>杀死未授权进程：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"bash\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__built_in\">kill\u003C/span> -9 \u003Cspan class=\"code-snippet__variable\">$PID\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Csection style=\"text-align: justify;\">\u003Cspan>删除未授权进程对应的文件\u003C/span>\u003C/section>\u003Cp style=\"text-align: center;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/bb4b8bf875dba967d673db9555955b71.jpg\" alt=\"11 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>还可以通过如下命令排查近期新增的文件，清除相关木马\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003Cbr>\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"properties\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\"> \u003Cspan class=\"code-snippet__attr\">find\u003C/span> \u003Cspan class=\"code-snippet__string\">/etc -ctime -2 （这里指定目录为/etc，获取近2天内的新增文件）\u003C/span>\u003C/span>\u003C/code>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\"> \u003Cspan class=\"code-snippet__attr\">lsof\u003C/span> \u003Cspan class=\"code-snippet__string\">-c kinsing （这里要查看文件名为kinsing的相关进程信息）\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: center;\">\u003Cbr>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cp>\u003Cimg src=\"/uploads/layedit/20211110/bf50043d9165f8cdde46d34e4a5c6542.jpg\" alt=\"12 (2).jpg\">\u003Cbr>\u003C/p>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cspan>\u003Cstrong>8、风险排查、安全加固\u003C/strong>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>对系统进行风险排查和安全加固，避免挖矿木马卷土重来，详情可参考如下链接：\u003C/span>\u003Cspan>https://cloud.tencent.com/document/product/296/9604\u003C/span>\u003C/p>\u003Csection data-mpa-template=\"t\" mpa-from-tpl=\"t\" style=\"text-align: justify;\">\u003Csection mpa-from-tpl=\"t\" style=\"text-align: center;\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Csection mpa-from-tpl=\"t\">\u003Cp>\u003Cspan>\u003Cem>\u003Cstrong mpa-from-tpl=\"t\" mpa-is-content=\"t\">四. 常见问题\u003C/strong>\u003C/em>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cspan>\u003Cstrong>1、明明刚刚清理了挖矿木马，没过多久就又卷土重来？\u003C/strong>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>很多用户会反馈挖矿木马老是清理不干净，明明已经Kill了进程，删除了木马文件，没过多久，CPU占用率又上来了。究其根本，还是因为清除得不够彻底。大部分用户都只是Kill掉挖矿进程和对应文件，却没有清理计划任务和守护进程。\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>一般建议先清除计划任务、启动项、守护进程，再清除挖矿进程和其他恶意进程。\u003C/span>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cimg src=\"/uploads/layedit/20211110/ad765c9d5aa7922c53096f9aab27c5f5.jpg\" alt=\"13 (2).jpg\">\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cspan>\u003Cstrong>2、如何判定可疑进程是否为恶意进程？\u003C/strong>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cspan>如下图所示，未知进程kinsing监听本地31458端口，非常可疑，可通过如下方\u003C/span>\u003Cspan>法判定：\u003Cbr>（1）执行`ls -al /proc/$PID/exe`确认可疑进程对应的文件；\u003Cbr>（2）若文件未被删除，则直接上传文件到Virustotal进行检测，或者计算出文件对应的md5，使用md5去Virustotal进行查询；若文件已被删除，可执行`cat /proc/$PID/exe &gt; /tmp/t.bin`将进程dump到特定目录，再上传文件到Virustotal或者计算dump文件对应的md5到Virustotal进行查询。如果有多款杀毒引擎同时检出，那基本可以判定该进程为恶意进程。\u003C/span>\u003C/p>\u003Cp style=\"text-align: center;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/b179d99705c06e8726998fd62e9b3670.jpg\" alt=\"14 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/f28add191d146aa286aeebec4ef0a2ec.jpg\" alt=\"15 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>Virustotal地址：\u003C/span>\u003Cspan>\u003Cem>https://www.virustotal.com/gui/s\u003Cbr>\u003C/em>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>\u003C/span>\u003Cbr>\u003C/p>\u003Csection data-support=\"96编辑器\" data-style-id=\"26041\" style=\"text-align: justify;\">\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Csection>\u003Cbr>\u003C/section>\u003Csection data-form=\"0\" data-num=\"1\" style=\"text-align: center;\">\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003Csection>\u003Cbr>\u003C/section>\u003C/section>\u003Cp>\u003Cspan>\u003Cstrong>3、为什么系统CPU占用率接近100%，却看不到是哪个进程导致的？\u003C/strong>\u003C/span>\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003C/section>\u003Csection style=\"text-align: justify;\">\u003Cspan>\u003C/span>\u003Cspan>如下图所示，系统CPU占用率接近100%，却看不到是哪个进程导致的，这种情况一般是因为系统命令被木马篡改了，从而隐藏了木马进程的踪迹，让用户无法进行溯源分析。\u003C/span>\u003Cbr>\u003C/section>\u003Cp style=\"text-align: center;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/7ac92285edf0293e5cd2a20b6ca69948.jpg\" alt=\"16 (2).jpg\">\u003Cbr>\u003C/p>\u003Csection style=\"text-align: justify;\">\u003Cspan>命令篡改有多种方式，分别如下：\u003Cbr>（1）top源文件被篡改，恶意进程信息被过滤后返回\u003C/span>\u003C/section>\u003Cp style=\"text-align: center;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20211110/74024922668ffb4b0ebda2b3e07fc430.jpg\" alt=\"17 (2).jpg\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>通过执行如下命令即可复原：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"nginx\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attribute\">rm\u003C/span> -rf /usr/bin/top &amp;&amp; mv /usr/bin/top.original /usr/bin/top\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>【相关文章】\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>\u003C/span>\u003Cspan>\u003Cem>https://blog.csdn.net/chenmozhe22/article/details/112578057\u003C/em>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>（2）篡改预加载so文件，ls、top、ps等命令已经被木马的动态链接库劫持，无法获得木马进程相关的信息\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>\u003Cimg src=\"/uploads/layedit/20211110/a4b38ef8492bf89b0d7f1940eb74e2aa.jpg\" alt=\"18 (2).jpg\">\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>通过执行如下命令即可复原：\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cpre class=\"code-snippet__js\" data-lang=\"javascript\">\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">&gt; \u003Cspan class=\"code-snippet__regexp\">/etc/\u003C/span>ld.so.preload &amp;&amp; rm -rf 恶意so文件路径\u003C/span>\u003C/code>\u003C/pre>\u003C/section>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>（3）通过其他未知手段篡改系统命令\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>可分别尝试如下两种方案解决：\u003Cbr>i.从其他相同版本系统中拷贝命令源文件到当前系统中进行覆盖；可使用uname -a命令查看当前系统版本；\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>ii.或者安装busybox来对系统进行排查。\u003Cbr>\u003C/span>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan>busybox是一个集成了300多个最常用Linux命令和工具的软件，可以使用busybox替代系统命令对系统进行排查；\u003C/span>\u003C/p>\u003Csection class=\"code-snippet__fix code-snippet__js\" style=\"text-align: justify;\">\u003Cul class=\"code-snippet__line-index code-snippet__js\">\u003Cli style=\"text-align: right;\">\u003C/li>\u003C/ul>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">yum\u003C/span> \u003Cspan class=\"code-snippet__string\">-y install wget make gcc perl glibc-static ncurses-devel libgcrypt-devel\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">wget\u003C/span> \u003Cspan class=\"code-snippet__string\">http://busybox.net/downloads/busybox-1.33.0.tar.bz2\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">tar\u003C/span> \u003Cspan class=\"code-snippet__string\">-jxvf busybox-1.33.0.tar.bz2\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003Cp>\u003Ccode style=\"text-align: left;\">\u003Cspan class=\"code-snippet_outer\">\u003Cspan class=\"code-snippet__attr\">cd\u003C/span> \u003Cspan class=\"code-snippet__string\">busybox-1.33.0 &amp;&amp; make &amp;&amp; make install\u003C/span>\u003C/span>\u003C/code>\u003C/p>\u003C/section>\u003Cp>\u003Cspan>【相关文章】\u003C/span>\u003C/p>\u003Cp>\u003Cspan>\u003Cem>https://www.cnblogs.com/angryprogrammer/p/13456681.html\u003C/em>\u003C/span>\u003C/p>","***一、什么是挖矿木马***\n\n   挖矿木马会占用CPU进行超频运算，从而占用主机大量的CPU资源，严重影响服务器上的其他应用的正常运行。黑客为了得到更多的算力资源，一般都会对全网进行无差别扫描，同时利用SSH爆破和漏洞利用等手段攻击主机。\n\n部分挖矿木马还具备蠕虫化的特点，在主机被成功入侵之后，挖矿木马还会向内网渗透，并在被入侵的服务器上持久化驻留以获取最大收益。\n\n挖矿木马的整体攻击流程大致如下图所示：\n\n![1.jpg](/uploads/layedit/20211110/73a83cf25324be000806d35145752664.jpg)\n\n***二、挖矿木马中招特征***\n\n挖矿木马会在用户不知情的情况下利用主机的算力进行挖矿，最明显的特征就是主机的CPU被大量消耗，查看云主机CPU占用率的方法有两种：\n\n**控制台实例监控**\n\n**![2.jpg](/uploads/layedit/20211110/d68438c0482915789a8059a78e24cf78.jpg)\n**\n\n**主机执行TOP命令**\n\n如下图所示，通过执行top命令，即可在返回结果中看到当时系统的CPU占用率。\n\n-\n\n```\ntop -c\n```\n\n![3 (2).jpg](/uploads/layedit/20211110/ab5fcddaf033a9836e9043cc42854e2c.jpg)\n\n如果云主机CPU占用率居高不下，那么主机很有可能已经被植入了挖矿木马，会影响服务器上的其他应用的正常运行，需要立刻上机排查。\n\n***三、清理挖矿木马***\n\n**1、及时隔离主机**\n\n部分带有蠕虫功能的挖矿木马在取得主机的控制权后，会继续对公网的其他主机，或者以当前主机作为跳板机对同一局域网内的其他主机进行横向渗透，所以在发现主机被植入挖矿木马后，在不影响业务正常运行的前提下，应该及时隔离受感染的主机，然后进行下一步分析和清除工作。\n\n腾讯云主机可以通过设置安全组隔离主机，具体参考如下链接：\n\n*https://cloud.tencent.com/document/product/215/20089*\n\n**\n2、阻断异常网络通信\n**\n\n挖矿木马不仅会连接矿池，还有可能会连接黑客的C2服务器，接收并执行C2指令、投递其他恶意木马，所以需要及时进行网络阻断。\n\n（1）检查主机防火墙当前生效的iptables规则中是否存在业务范围之外的可疑地址和端口，它们可能是挖矿木马的矿池或C2地址\n\n-\n\n```\niptables -L -n\n```\n\n（2）从iptables规则中清除可疑地址和端口\n\n-\n\n```\nvi /etc/sysconfig/iptables\n```\n\n（3）阻断挖矿木马的网络通信\n\n-\n\n```\niptables -A INPUT -s 可疑地址 -j DROPiptables -A OUTPUT -d 可疑地址 -j DROP\n```\n\n**3、清除计划任务**\n\n大部分挖矿木马会通过在受感染主机中写入计划任务实现持久化，如果仅仅只是清除挖矿进程，无法将其根除，到了预设的时间点，系统会通过计划任务从黑客的C2服务器重新下载并执行挖矿木马。\n\n挖矿木马常见的计划任务通常是下载并执行sh脚本，如下图所示:\n\n![4.png](/uploads/layedit/20211110/0c2e3c4bc6a62c916a6e21967b68a725.png)\n\n可以通过执行如下命令查看是否存在可疑定时任务，若有，则先保存相关记录用于后续分析，再进行删除：\n\n查看系统当前用户的计划任务：\n\n-\n\n```\ncrontab -l\n```\n\n查看系统特定用户的计划任务：\n\n-\n\n```\ncrontab -u username -l\n```\n\n查看其他计划任务文件：\n\n-\n\n`\n\ncat\n\n/etc/crontab\n\n`\n\n`\n\ncat\n\n/var/spool/cron\n\n`\n\n`\n\ncat\n\n/etc/anacrontab\n\n`\n\n`\n\ncat\n\n/etc/cron.d/\n\n`\n\n`\n\ncat\n\n/etc/cron.daily/\n\n`\n\n`\n\ncat\n\n/etc/cron.hourly/\n\n`\n\n`\n\ncat\n\n/etc/cron.weekly/\n\n`\n\n`\n\ncat\n\n/etc/cron.monthly/\n\n`\n\n`\n\ncat\n\n/var/spool/cron/\n\n`\n\n**4、清除启动项**\n\n除了计划任务，挖矿木马通过添加启动项同样能实现持久化。可以使用如下命令查看开机启动项中是否有异常的启动服务。\n\nCentOS7以下版本：\n\n-\n\n```\nchkconfig –list\n```\n\nCentOS7及以上版本：\n\n-\n\n```\nsystemctl list-unit-files\n```\n\n如果发现有恶意启动项，可以通过如下命令进行关闭：\n\nCentOS7以下版本：\n\n-\n\n```\nchkconfig 服务名 off\n```\n\nCentOS7及以上版本：\n\n-\n\n```\nsystemctl disable 服务名\n```\n\n另外，还需要仔细排查以下目录及文件，及时删除可疑的启动项：\n\n-\n\n`\n/usr/lib/systemd/system\n`\n\n`\n/usr/lib/systemd/system/multi-user.target.wants\n`\n\n`\n/etc/rc.local\n`\n\n`\n/etc/inittab\n`\n\n`\n/etc/rc0.d/\n`\n\n`\n\n/etc/\nrc1.d/\n`\n\n`\n\n/etc/\nrc2.d/\n`\n\n`\n\n/etc/\nrc3.d/\n`\n\n`\n\n/etc/\nrc4.d/\n`\n\n`\n\n/etc/\nrc5.d/\n`\n\n`\n\n/etc/\nrc6.d/\n`\n\n`\n\n/etc/\nrc.d/\n`\n\n排查的时候，可以按照文件修改时间来排序，重点排查近期被创建服务项。如下图所示，系统近期被创建了一个名为bot.service的服务，该服务在系统启动时会启动/etc/kinsing这个木马文件，需要关闭bot服务，并删除/etc/kinsing文件。\n\n![5.jpg](/uploads/layedit/20211110/3cd9e620ab95ebe7de5ca4753f69c5e5.jpg)\n\n![6 (2).jpg](/uploads/layedit/20211110/1fbc612b14c0914856f326a2537f279c.jpg)\n\n**5、清除预加载so**\n\n通\n\n过配置/etc/ld.so.preload，可以自定义程序运行前优先加载的动态链接库，部分木马通过修改该文\n\n件，添加恶意so文件，从而实现挖矿进程的隐藏等恶意功能。\n\n检查/etc/ld.so.preload（该文件默认为空），清除异常的动态链接库。可以执行`> /etc/ld.so.preload`命令进行清除。\n\n![7 (2).jpg](/uploads/layedit/20211110/58655aa5bbb2e5b77eb4d4fc24df6ccf.jpg)\n\n**6、清除SSH公钥**\n\n挖矿木马通常还会在~/.ssh/authoruzed_keys文件中写入黑客的SSH公钥，这样子就算用户将挖矿木马清除得一干二净，黑客还是可以免密登陆该主机，这也是常见的保持服务器控制权的手段。\n\n排查~/.ssh/authorized_keys文件，如果发现可疑的SSH公钥，直接删除。\n\n**7、清除挖矿木马**\n\n**\n（1）清除挖矿进程\n**\n\n挖矿木马最大的特点就是会在用户不知情的情况下，利用主机的算力进行挖矿，从而消耗主机大量的CPU资源，所以，通过执行如下命令排查系统中占用大量CPU资源的进程。\n\n-\n\n```\ntop -cps -ef\n```\n\n![8 (2).jpg](/uploads/layedit/20211110/6aa247d8242572deda75a4e080895c92.jpg)\n\n确认相关进程为挖矿进程后，按照如下步骤将其清除：\n获取并记录挖矿进程的文件路径：\n\n-\n\n```\nls -l /proc/$PID/exe\n```\n\n杀死挖矿进程：\n\n-\n\n```\nkill -9 $PID\n```\n\n删除挖矿进程对应的文件\n\n![9 (2).jpg](/uploads/layedit/20211110/2c0d016376dd6e9726aa9610bab964e2.jpg)\n\n**\n（2）清除其它相关恶意进程\n**\n\n恶意进程与外部的C2服务器进行通信时，往往会开启端口进行监听。执行如下命令，查看服务器是否有未被授权的端口被监听。\n\n-\n\n```\nnetstat -antp\n```\n\n![10 (2).jpg](/uploads/layedit/20211110/67e15d39d20688f80b8f9ec64675a72e.jpg)\n\n若有未授权进程，按照如下步骤将其清除：\n获取并记录未授权进程的文件路径：\n\n-\n\n```\nls -l /proc/$PID/exe\n```\n\n杀死未授权进程：\n\n-\n\n```\nkill -9 $PID\n```\n\n删除未授权进程对应的文件\n\n![11 (2).jpg](/uploads/layedit/20211110/bb4b8bf875dba967d673db9555955b71.jpg)\n\n还可以通过如下命令排查近期新增的文件，清除相关木马\n\n-\n\n```\nfind /etc -ctime -2 （这里指定目录为/etc，获取近2天内的新增文件） lsof -c kinsing （这里要查看文件名为kinsing的相关进程信息）\n```\n\n![12 (2).jpg](/uploads/layedit/20211110/bf50043d9165f8cdde46d34e4a5c6542.jpg)\n\n**8、风险排查、安全加固**\n\n对系统进行风险排查和安全加固，避免挖矿木马卷土重来，详情可参考如下链接：\n\nhttps://cloud.tencent.com/document/product/296/9604\n\n***四. 常见问题***\n\n**1、明明刚刚清理了挖矿木马，没过多久就又卷土重来？**\n\n很多用户会反馈挖矿木马老是清理不干净，明明已经Kill了进程，删除了木马文件，没过多久，CPU占用率又上来了。究其根本，还是因为清除得不够彻底。大部分用户都只是Kill掉挖矿进程和对应文件，却没有清理计划任务和守护进程。\n\n一般建议先清除计划任务、启动项、守护进程，再清除挖矿进程和其他恶意进程。\n\n![13 (2).jpg](/uploads/layedit/20211110/ad765c9d5aa7922c53096f9aab27c5f5.jpg)\n\n**2、如何判定可疑进程是否为恶意进程？**\n\n如下图所示，未知进程kinsing监听本地31458端口，非常可疑，可通过如下方\n\n法判定：\n（1）执行`ls -al /proc/$PID/exe`确认可疑进程对应的文件；\n（2）若文件未被删除，则直接上传文件到Virustotal进行检测，或者计算出文件对应的md5，使用md5去Virustotal进行查询；若文件已被删除，可执行`cat /proc/$PID/exe > /tmp/t.bin`将进程dump到特定目录，再上传文件到Virustotal或者计算dump文件对应的md5到Virustotal进行查询。如果有多款杀毒引擎同时检出，那基本可以判定该进程为恶意进程。\n\n![14 (2).jpg](/uploads/layedit/20211110/b179d99705c06e8726998fd62e9b3670.jpg)\n\n![15 (2).jpg](/uploads/layedit/20211110/f28add191d146aa286aeebec4ef0a2ec.jpg)\n\nVirustotal地址：\n\n*https://www.virustotal.com/gui/s\n*\n\n**3、为什么系统CPU占用率接近100%，却看不到是哪个进程导致的？**\n\n如下图所示，系统CPU占用率接近100%，却看不到是哪个进程导致的，这种情况一般是因为系统命令被木马篡改了，从而隐藏了木马进程的踪迹，让用户无法进行溯源分析。\n\n![16 (2).jpg](/uploads/layedit/20211110/7ac92285edf0293e5cd2a20b6ca69948.jpg)\n\n命令篡改有多种方式，分别如下：\n（1）top源文件被篡改，恶意进程信息被过滤后返回\n\n![17 (2).jpg](/uploads/layedit/20211110/74024922668ffb4b0ebda2b3e07fc430.jpg)\n\n通过执行如下命令即可复原：\n\n-\n\n```\nrm -rf /usr/bin/top && mv /usr/bin/top.original /usr/bin/top\n```\n\n【相关文章】\n\n*https://blog.csdn.net/chenmozhe22/article/details/112578057*\n\n（2）篡改预加载so文件，ls、top、ps等命令已经被木马的动态链接库劫持，无法获得木马进程相关的信息\n\n![18 (2).jpg](/uploads/layedit/20211110/a4b38ef8492bf89b0d7f1940eb74e2aa.jpg)\n\n通过执行如下命令即可复原：\n\n-\n\n```\n> /etc/ld.so.preload && rm -rf 恶意so文件路径\n```\n\n（3）通过其他未知手段篡改系统命令\n\n可分别尝试如下两种方案解决：\ni.从其他相同版本系统中拷贝命令源文件到当前系统中进行覆盖；可使用uname -a命令查看当前系统版本；\n\nii.或者安装busybox来对系统进行排查。\n\nbusybox是一个集成了300多个最常用Linux命令和工具的软件，可以使用busybox替代系统命令对系统进行排查；\n\n-\n\n`\n\nyum\n\n-y install wget make gcc perl glibc-static ncurses-devel libgcrypt-devel\n\n`\n\n`\n\nwget\n\nhttp://busybox.net/downloads/busybox-1.33.0.tar.bz2\n\n`\n\n`\n\ntar\n\n-jxvf busybox-1.33.0.tar.bz2\n\n`\n\n`\n\ncd\n\nbusybox-1.33.0 && make && make install\n\n`\n\n【相关文章】\n\n*https://www.cnblogs.com/angryprogrammer/p/13456681.html*","/article/108",5333,"2021-11-10 12:06:10","2021-11-10 12:41:03",{"id":254,"category_id":44,"title":255,"keywords":256,"description":257,"image_url":6,"content":258,"content_md":259,"url":260,"hits":261,"is_recommend":73,"is_top":73,"create_time":262,"update_time":263},107,"Acme.sh 给 SSL 证书自动续期失败的解决方法","HTTP/1.1 200 OK,Server: Bayou Tech Web Srv 1.0,Content-Encoding: none,Content-Length: 5,Content-Type","一、Acme.sh 自动续期失败的症状问题描述如下，续期的时候，提示如下错误：root@dc:~# \"/data/acme.sh\"/acme.sh --cron --home \"/data/acme.sh\" &gt; /dev/null[Sun Nov 10 23:52:17 CST 2020] Error, can not get domain token entry example.com[Sun Nov 10 23:52:17 CST 2020] Please check log file","\u003Cp style=\"text-align: justify;\">一、Acme.sh 自动续期失败的症状\u003C/p>\u003Cp style=\"text-align: justify;\">问题描述如下，续期的时候，提示如下错误：\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">root@dc:~# \"/data/acme.sh\"/acme.sh --cron --home \"/data/acme.sh\" &gt; /dev/null\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] Error, can not get domain token entry example.com\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] Please check log file for more details: /data/acme.sh/acme.sh.log\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] Error renew example.com.\u003C/p>\u003Cp style=\"text-align: justify;\">经过查看 log，错误日志如下：\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:14 CST 2020] GET\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:14 CST 2020] url='https://acme-v01.api.letsencrypt.org/directory'\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:14 CST 2020] timeout=\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:15 CST 2020] _CURL='curl -L --silent --dump-header /data/acme.sh/http.header -g '\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:15 CST 2020] ret='0'\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:15 CST 2020] Could not get nonce, let's try again.\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] The new-authz request is ok.\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] entry\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] Error, can not get domain token entry example.com\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] pid\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] No need to restore nginx, skip.\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] _clearupdns\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] skip dns.\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] _on_issue_err\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] Please check log file for more details: /data/acme.sh/acme.sh.log\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] Return code: 1\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] Error renew example.com.\u003C/p>\u003Cp style=\"text-align: justify;\">[Sun Nov 10 23:52:17 CST 2020] ===End cron===\u003C/p>\u003Cp style=\"text-align: justify;\">二、Acme.sh 自动续期失败的解决方法\u003C/p>\u003Cp style=\"text-align: justify;\">网上搜了一堆文章之后，都没解决问题，最后在这篇文章中找到了问题所在：\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">https://community.letsencrypt.org/t/unable-to-issue-or-renew-certificates/102948\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">Your server is able to connect Letsencrypt, so that isn’t the problem.\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">But you use acme.sh. There are changes. First step: Update your acme.sh.\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">Yep, the nonce-problem:\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">Could not get nonce, let's try again.\u003C/p>\u003Cp style=\"text-align: justify;\">An update is required.\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">所以，问题原因就是 acme.sh 版本太低，解决方法很简单，升级 acme.sh 即可：\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">升级 acme.sh 到最新版 :\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">acme.sh --upgrade\u003C/p>\u003Cp style=\"text-align: justify;\">如果你不想手动升级, 可以开启自动升级:\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">acme.sh&nbsp; --upgrade&nbsp; --auto-upgrade\u003C/p>\u003Cp style=\"text-align: justify;\">之后, acme.sh 就会自动保持更新了.\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">你也可以随时关闭自动更新:\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">acme.sh --upgrade&nbsp; --auto-upgrade&nbsp; 0\u003C/p>\u003Cp style=\"text-align: justify;\">参考：https://github.com/Neilpang/acme.sh\u003C/p>","一、Acme.sh 自动续期失败的症状\n\n问题描述如下，续期的时候，提示如下错误：\n\nroot@dc:~# \"/data/acme.sh\"/acme.sh --cron --home \"/data/acme.sh\" > /dev/null\n\n[Sun Nov 10 23:52:17 CST 2020] Error, can not get domain token entry example.com\n\n[Sun Nov 10 23:52:17 CST 2020] Please check log file for more details: /data/acme.sh/acme.sh.log\n\n[Sun Nov 10 23:52:17 CST 2020] Error renew example.com.\n\n经过查看 log，错误日志如下：\n\n[Sun Nov 10 23:52:14 CST 2020] GET\n\n[Sun Nov 10 23:52:14 CST 2020] url='https://acme-v01.api.letsencrypt.org/directory'\n\n[Sun Nov 10 23:52:14 CST 2020] timeout=\n\n[Sun Nov 10 23:52:15 CST 2020] _CURL='curl -L --silent --dump-header /data/acme.sh/http.header -g '\n\n[Sun Nov 10 23:52:15 CST 2020] ret='0'\n\n[Sun Nov 10 23:52:15 CST 2020] Could not get nonce, let's try again.\n\n[Sun Nov 10 23:52:17 CST 2020] The new-authz request is ok.\n\n[Sun Nov 10 23:52:17 CST 2020] entry\n\n[Sun Nov 10 23:52:17 CST 2020] Error, can not get domain token entry example.com\n\n[Sun Nov 10 23:52:17 CST 2020] pid\n\n[Sun Nov 10 23:52:17 CST 2020] No need to restore nginx, skip.\n\n[Sun Nov 10 23:52:17 CST 2020] _clearupdns\n\n[Sun Nov 10 23:52:17 CST 2020] skip dns.\n\n[Sun Nov 10 23:52:17 CST 2020] _on_issue_err\n\n[Sun Nov 10 23:52:17 CST 2020] Please check log file for more details: /data/acme.sh/acme.sh.log\n\n[Sun Nov 10 23:52:17 CST 2020] Return code: 1\n\n[Sun Nov 10 23:52:17 CST 2020] Error renew example.com.\n\n[Sun Nov 10 23:52:17 CST 2020] ===End cron===\n\n二、Acme.sh 自动续期失败的解决方法\n\n网上搜了一堆文章之后，都没解决问题，最后在这篇文章中找到了问题所在：\n\nhttps://community.letsencrypt.org/t/unable-to-issue-or-renew-certificates/102948\n\nYour server is able to connect Letsencrypt, so that isn’t the problem.\n\nBut you use acme.sh. There are changes. First step: Update your acme.sh.\n\nYep, the nonce-problem:\n\nCould not get nonce, let's try again.\n\nAn update is required.\n\n所以，问题原因就是 acme.sh 版本太低，解决方法很简单，升级 acme.sh 即可：\n\n升级 acme.sh 到最新版 :\n\nacme.sh --upgrade\n\n如果你不想手动升级, 可以开启自动升级:\n\nacme.sh  --upgrade  --auto-upgrade\n\n之后, acme.sh 就会自动保持更新了.\n\n你也可以随时关闭自动更新:\n\nacme.sh --upgrade  --auto-upgrade  0\n\n参考：https://github.com/Neilpang/acme.sh","/article/107",12618,"2021-09-03 10:44:18","2021-09-03 10:46:23",{"id":265,"category_id":44,"title":266,"keywords":267,"description":268,"image_url":6,"content":269,"content_md":270,"url":271,"hits":272,"is_recommend":73,"is_top":73,"create_time":273,"update_time":274},105,"centos7环境下解决journal日志越来越大的问题","journal,centos","背景：线上的机器是使用的ECS，磁盘空间只有50G，而journal日志就占了4G左右，所以就要限制下存储大小和保存时间。介绍：1、查看journal占用磁盘空间大小：journalctl --disk-usage2、指定journal占用磁盘空间大小：journalctl --vacuum-size=1G3、指定journal日志保存时间：journalctl --vacuum-time=1years #年journalctl --vacuum-time=1month #月journalctl","\u003Cp>背景：\u003C/p>\u003Cp>线上的机器是使用的ECS，磁盘空间只有50G，而journal日志就占了4G左右，所以就要限制下存储大小和保存时间。\u003C/p>\u003Cp>介绍：\u003C/p>\u003Cp>1、查看journal占用磁盘空间大小：\u003C/p>\u003Cp>\u003Ccode>journalctl --disk-usage\u003C/code>\u003C/p>\u003Cp>2、指定journal占用磁盘空间大小：\u003C/p>\u003Cp>\u003Ccode>journalctl --vacuum-size=1G\u003C/code>\u003C/p>\u003Cp>3、指定journal日志保存时间：\u003C/p>\u003Cp>\u003Ccode>journalctl --vacuum-time=1years #年\u003C/code>\u003C/p>\u003Cp>\u003Ccode>journalctl --vacuum-time=1month #月\u003C/code>\u003C/p>\u003Cp>\u003Ccode>journalctl --vacuum-time=1d #天\u003C/code>\u003C/p>\u003Cp>\u003Ccode>\u003Cimg src=\"/uploads/layedit/20210525/553bdf241bef2200c043bd30cadca7e3.png\" alt=\"0525.png\">\u003Cbr>\u003C/code>\u003C/p>\u003Cp>4、查看具体服务的日志：\u003C/p>\u003Cp>\u003Ccode>journalctl -u nginx.service\u003C/code>\u003C/p>\u003Cp>\u003Ccode>journalctl -u nginx.service -f\u003C/code>&nbsp;&nbsp; 实时查看\u003C/p>\u003Cp>5、实时查看最新日志：\u003C/p>\u003Cp>\u003Ccode>journalctl -f\u003C/code>\u003C/p>\u003Cp>6、查看尾部最新的n行日志：\u003C/p>\u003Cp>\u003Ccode>journalctl -n 20\u003C/code>\u003C/p>\u003Cp>7、查看指定时间的日志：\u003C/p>\u003Cp>\u003Ccode>journalctl --since \"20 min ago\"\u003C/code>\u003C/p>\u003Cp>\u003Ccode>journalctl --since yesterday\u003C/code>\u003C/p>\u003Cp>\u003Ccode>journalctl --since 09:00 --until \"1 hour ago\"\u003C/code>\u003C/p>\u003Cp>8、查看内核日志：\u003C/p>\u003Cp>\u003Ccode>journalctl -k\u003C/code>\u003C/p>\u003Cp>9、查看系统启动日志：\u003C/p>\u003Cp>\u003Ccode>journalctl -b\u003C/code>\u003C/p>\u003Cp>\u003Cbr>\u003C/p>","背景：\n\n线上的机器是使用的ECS，磁盘空间只有50G，而journal日志就占了4G左右，所以就要限制下存储大小和保存时间。\n\n介绍：\n\n1、查看journal占用磁盘空间大小：\n\n`journalctl --disk-usage`\n\n2、指定journal占用磁盘空间大小：\n\n`journalctl --vacuum-size=1G`\n\n3、指定journal日志保存时间：\n\n`journalctl --vacuum-time=1years #年`\n\n`journalctl --vacuum-time=1month #月`\n\n`journalctl --vacuum-time=1d #天`\n\n`![0525.png](/uploads/layedit/20210525/553bdf241bef2200c043bd30cadca7e3.png)\n`\n\n4、查看具体服务的日志：\n\n`journalctl -u nginx.service`\n\n`journalctl -u nginx.service -f`   实时查看\n\n5、实时查看最新日志：\n\n`journalctl -f`\n\n6、查看尾部最新的n行日志：\n\n`journalctl -n 20`\n\n7、查看指定时间的日志：\n\n`journalctl --since \"20 min ago\"`\n\n`journalctl --since yesterday`\n\n`journalctl --since 09:00 --until \"1 hour ago\"`\n\n8、查看内核日志：\n\n`journalctl -k`\n\n9、查看系统启动日志：\n\n`journalctl -b`","/article/105",6330,"2021-05-25 11:31:34","2021-05-25 11:34:36",{"id":276,"category_id":44,"title":277,"keywords":278,"description":279,"image_url":6,"content":280,"content_md":281,"url":282,"hits":283,"is_recommend":73,"is_top":73,"create_time":284,"update_time":285},104,"mysql亿级大表 rename卡表 解决方法","error","背景当初表结构设计不合理，表自增id达到2147483647，无法继续写入 ；重新设计新表将id int(10)更改为id bigint(20),执行语句：RENAME TABLE t_crowd_user TO t_crowd_user_old_0606, t_crowd_user_tmp TO t_crowd_user;卡表，现象如下解决方案： 1、 查询影响的事务     MySQ","\u003Cp>\u003Cb>背景\u003C/b>\u003C/p>\u003Cp>当初表结构设计不合理，表自增id达到2147483647，数据无法继续写入 ；重新设计新表将id int(10)更改为id bigint(20),后将原表改名。\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20200606/11eeaa81bc89c43a7baaa745ef66eb23.png\" alt=\"06063.png\">\u003Cbr>\u003C/p>\u003Cp>执行语句：\u003C/p>\u003Cp>RENAME&nbsp;TABLE&nbsp;t_crowd_user&nbsp;TO&nbsp;t_crowd_user_old_0606,&nbsp;t_crowd_user_tmp&nbsp;TO&nbsp;t_crowd_user;\u003C/p>\u003Cp>卡表，现象如下\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20200606/22c7ed43a1ff08250bd84f7167420daf.png\" alt=\"06062.png\">\u003Cbr>\u003C/p>\u003Cp>\u003Cb>解决方案：\u003C/b>\u003C/p>\u003Cp>&nbsp;\u003Cb>1、 查询影响的事务&nbsp;\u003C/b>\u003C/p>\u003Cp>&nbsp; &nbsp; MySQL&nbsp;[db_ex_crowd]&gt;&nbsp;select&nbsp;*&nbsp;from&nbsp;information_schema.innodb_trx;\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20200606/384514a1eba58bec2a4eefee0ea4963f.png\" alt=\"06061.png\">\u003Cbr>\u003C/p>\u003Cp>\u003Cb>2、杀掉查询出的事务&nbsp;\u003C/b>\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kill&nbsp;540619506;\u003Cbr>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kill&nbsp;540636346;\u003Cbr>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kill&nbsp;540609552;\u003Cbr>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kill&nbsp;540544135;\u003Cbr>\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; kill&nbsp;540578535;\u003C/p>\u003Cp>\u003Cb>3、再次执行语句，发现已执行成功\u003C/b>\u003C/p>\u003Cp>RENAME&nbsp;TABLE&nbsp;t_crowd_user&nbsp;TO&nbsp;t_crowd_user_old_0606,&nbsp;t_crowd_user_tmp&nbsp;TO&nbsp;t_crowd_user;\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>\u003Cb>原因分析\u003C/b>\u003C/p>\u003Cp>&nbsp; &nbsp;代码程序设计不合理，没有合理释放mysql会话，导致只能等待mysql&nbsp;\u003Cspan>wait_timeout超时释放\u003C/span>\u003C/p>\u003Cp>\u003C/p>","**背景**\n\n当初表结构设计不合理，表自增id达到2147483647，数据无法继续写入 ；重新设计新表将id int(10)更改为id bigint(20),后将原表改名。\n\n![06063.png](/uploads/layedit/20200606/11eeaa81bc89c43a7baaa745ef66eb23.png)\n\n执行语句：\n\nRENAME TABLE t_crowd_user TO t_crowd_user_old_0606, t_crowd_user_tmp TO t_crowd_user;\n\n卡表，现象如下\n\n![06062.png](/uploads/layedit/20200606/22c7ed43a1ff08250bd84f7167420daf.png)\n\n**解决方案：**\n\n **1、 查询影响的事务 **\n\n    MySQL [db_ex_crowd]> select * from information_schema.innodb_trx;\n\n![06061.png](/uploads/layedit/20200606/384514a1eba58bec2a4eefee0ea4963f.png)\n\n**2、杀掉查询出的事务 **\n\n          kill 540619506;\n          kill 540636346;\n          kill 540609552;\n          kill 540544135;\n\n          kill 540578535;\n\n**3、再次执行语句，发现已执行成功**\n\nRENAME TABLE t_crowd_user TO t_crowd_user_old_0606, t_crowd_user_tmp TO t_crowd_user;\n\n**原因分析**\n\n   代码程序设计不合理，没有合理释放mysql会话，导致只能等待mysql \nwait_timeout超时释放","/article/104",8011,"2020-06-06 18:53:53","2020-06-06 19:11:09",{"id":287,"category_id":44,"title":288,"keywords":6,"description":289,"image_url":6,"content":290,"content_md":291,"url":292,"hits":293,"is_recommend":73,"is_top":73,"create_time":294,"update_time":295},103,"在线修改大表结构pt-online-schema-change","使用场景在线数据库的维护中，总会涉及到研发修改表结构的情况，修改一些小表影响很小，而修改大表时，往往影响业务的正常运转，如表数据量超过500W，1000W，甚至过亿时在线修改大表的可能影响在线修改大表的表结构执行时间往往不可预估，一般时间较长由于修改表结构是表级锁，因此在修改表结构时，影响表写入操作如果长时间的修改表结构，中途修改失败，由于修改表结构是一个事务，因此失败后会还原表结构，在这个过程中表都是锁着不可写入修改大表结构容易导致数据库CPU、IO等性能消耗，使MySQL服务器性能降低在线修","\u003Cp>\u003Cb>使用场景\u003C/b>\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>在线数据库的维护中，总会涉及到研发修改表结构的情况，修改一些小表影响很小，而修改大表时，往往影响业务的正常运转，如表数据量超过500W，1000W，甚至过亿时\u003C/p>\u003Cp>在线修改大表的可能影响\u003C/p>\u003Cp>在线修改大表的表结构执行时间往往不可预估，一般时间较长\u003C/p>\u003Cp>由于修改表结构是表级锁，因此在修改表结构时，影响表写入操作\u003C/p>\u003Cp>如果长时间的修改表结构，中途修改失败，由于修改表结构是一个事务，因此失败后会还原表结构，在这个过程中表都是锁着不可写入\u003C/p>\u003Cp>修改大表结构容易导致数据库CPU、IO等性能消耗，使MySQL服务器性能降低\u003C/p>\u003Cp>在线修改大表结构容易导致主从延时，从而影响业务读取\u003C/p>\u003Cp>pt-online-schema-change介绍\u003C/p>\u003Cp>pt-online-schema-change是percona公司开发的一个工具，在percona-toolkit包里面可以找到这个功能，它可以在线修改表结构\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>\u003Cb>原理:\u003C/b>\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>首先它会新建一张一模一样的表，表名一般是_new后缀\u003C/p>\u003Cp>然后在这个新表执行更改字段操作\u003C/p>\u003Cp>然后在原表上加三个触发器，DELETE/UPDATE/INSERT，将原表中要执行的语句也在新表中执行\u003C/p>\u003Cp>最后将原表的数据拷贝到新表中，然后替换掉原表\u003C/p>\u003Cp>使用pt-online-schema-change执行SQL的日志\u003C/p>\u003Cp>SQL语句:\u003C/p>\u003Cp>ALTER TABLE tmp_task_user ADD support tinyint(1) unsigned NOT NULL DEFAULT '1';\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>sh pt.sh tmp_task_user \"ADD COLUMN support tinyint(1) unsigned NOT NULL DEFAULT '1'\"\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>tmp_task_user\u003C/p>\u003Cp>ADD COLUMN support tinyint(1) unsigned NOT NULL DEFAULT '1'\u003C/p>\u003Cp>No slaves found.&nbsp; See --recursion-method if host h=127.0.0.1,P=3306 has slaves.\u003C/p>\u003Cp>Not checking slave lag because no slaves were found and --check-slave-lag was not specified.\u003C/p>\u003Cp>Operation, tries, wait:\u003C/p>\u003Cp>&nbsp; analyze_table, 10, 1\u003C/p>\u003Cp>&nbsp; copy_rows, 10, 0.25\u003C/p>\u003Cp>&nbsp; create_triggers, 10, 1\u003C/p>\u003Cp>&nbsp; drop_triggers, 10, 1\u003C/p>\u003Cp>&nbsp; swap_tables, 10, 1\u003C/p>\u003Cp>&nbsp; update_foreign_keys, 10, 1\u003C/p>\u003Cp>Altering `test_db`.`tmp_task_user`...\u003C/p>\u003Cp>Creating new table...\u003C/p>\u003Cp>Created new table test_db._tmp_task_user_new OK.\u003C/p>\u003Cp>Altering new table...\u003C/p>\u003Cp>Altered `test_db`.`_tmp_task_user_new` OK.\u003C/p>\u003Cp>2018-05-14T18:14:21 Creating triggers...\u003C/p>\u003Cp>2018-05-14T18:14:21 Created triggers OK.\u003C/p>\u003Cp>2018-05-14T18:14:21 Copying approximately 6 rows...\u003C/p>\u003Cp>2018-05-14T18:14:21 Copied rows OK.\u003C/p>\u003Cp>2018-05-14T18:14:21 Analyzing new table...\u003C/p>\u003Cp>2018-05-14T18:14:21 Swapping tables...\u003C/p>\u003Cp>2018-05-14T18:14:21 Swapped original and new tables OK.\u003C/p>\u003Cp>2018-05-14T18:14:21 Dropping old table...\u003C/p>\u003Cp>2018-05-14T18:14:21 Dropped old table `test_db`.`_tmp_task_user_old` OK.\u003C/p>\u003Cp>2018-05-14T18:14:21 Dropping triggers...\u003C/p>\u003Cp>2018-05-14T18:14:21 Dropped triggers OK.\u003C/p>\u003Cp>Successfully altered `test_db`.`tmp_task_user`.\u003C/p>\u003Cp>好处:\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>降低主从延时的风险\u003C/p>\u003Cp>可以限速、限资源，避免操作时MySQL负载过高\u003C/p>\u003Cp>建议:\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>在业务低峰期做，将影响降到最低\u003C/p>\u003Cp>pt-online-schema-change安装\u003C/p>\u003Cp>1.去官网下载对应的版本，官网下载地址:https://www.percona.com/downl...\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>\u003Cb>2.下载解压之后就可以看到pt-online-schema-change\u003C/b>\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20200512/c04eb46289014d981e00d47e7c1c7892.png\" alt=\"2.png\">\u003Cbr>\u003C/p>\u003Cp>\u003Cb>3.该工具需要一些依赖包，直接执行不成功时一般会有提示，这里可以提前yum安装\u003C/b>\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>yum&nbsp;install -y perl-DBI&nbsp;perl-DBD-MySQL&nbsp;perl-Time-HiRes&nbsp;perl-IO-Socket-SSL&nbsp;\u003Cspan>perl-Digest-MD5\u003C/span>\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>pt-online-schema-change使用\u003C/p>\u003Cp>1.参数\u003C/p>\u003Cp>./bin/pt-online-schema-change --help 可以查看参数的使用，我们只是要修改个表结构，只需要知道几个简单的参数就可以了\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>--user=&nbsp; &nbsp; &nbsp; &nbsp; 连接mysql的用户名\u003C/p>\u003Cp>--password=&nbsp; &nbsp; 连接mysql的密码\u003C/p>\u003Cp>--host=&nbsp; &nbsp; &nbsp; &nbsp; 连接mysql的地址\u003C/p>\u003Cp>P=3306&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;连接mysql的端口号\u003C/p>\u003Cp>D=&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;连接mysql的库名\u003C/p>\u003Cp>t=&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;连接mysql的表名\u003C/p>\u003Cp>--alter&nbsp; &nbsp; &nbsp; &nbsp; 修改表结构的语句\u003C/p>\u003Cp>--execute&nbsp; &nbsp; &nbsp; 执行修改表结构\u003C/p>\u003Cp>--charset=utf8 使用utf8编码，避免中文乱码\u003C/p>\u003Cp>--no-version-check&nbsp; 不检查版本，在阿里云服务器中一般加入此参数，否则会报错\u003C/p>\u003Cp>2.为避免每次都要输入一堆参数，写个脚本复用一下，pt.sh\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>#!/bin/bash\u003C/p>\u003Cp>table=$1\u003C/p>\u003Cp>alter_conment=$2\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>cnn_host='127.0.0.1'\u003C/p>\u003Cp>cnn_user='user'\u003C/p>\u003Cp>cnn_pwd='password'\u003C/p>\u003Cp>cnn_db='database_name'\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>echo \"$table\"\u003C/p>\u003Cp>echo \"$alter_conment\"\u003C/p>\u003Cp>/root/percona-toolkit-3.2.0/bin/pt-online-schema-change --charset=utf8 --no-version-check --user=${cnn_user} --password=${cnn_pwd} --host=${cnn_host}&nbsp; P=3306,D=${cnn_db},t=$table --alter&nbsp;\u003C/p>\u003Cp>\"${alter_conment}\" --execute\u003C/p>\u003Cp>\u003Cb>3.添加表字段\u003C/b>\u003C/p>\u003Cp>如添加表字段SQL语句为:\u003C/p>\u003Cp>ALTER TABLE tb_test ADD COLUMN column1 tinyint(4) DEFAULT NULL;\u003C/p>\u003Cp>那么使用pt-online-schema-change则可以这样写\u003C/p>\u003Cp>sh pt.sh tb_test \"ADD COLUMN column1 tinyint(4) DEFAULT NULL\"\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>\u003Cb>4.修改表字段\u003C/b>\u003C/p>\u003Cp>SQL语句：\u003C/p>\u003Cp>ALTER TABLE tb_test MODIFY COLUMN num int(11) unsigned NOT NULL DEFAULT '0';\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>pt-online-schema-change工具:\u003C/p>\u003Cp>sh pt.sh tb_test \"MODIFY COLUMN num int(11) unsigned NOT NULL DEFAULT '0'\"\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>\u003Cb>5.修改表字段名\u003C/b>\u003C/p>\u003Cp>SQL语句:\u003C/p>\u003Cp>ALTER TABLE tb_test CHANGE COLUMN age adress varchar(30);\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>pt-online-schema-change工具:\u003C/p>\u003Cp>sh pt.sh tb_test \"CHANGE COLUMN age address varchar(30)\"\u003C/p>\u003Cp>\u003Cb>\u003Cbr>\u003C/b>\u003C/p>\u003Cp>\u003Cb>6.添加索引\u003C/b>\u003C/p>\u003Cp>SQL语句:\u003C/p>\u003Cp>ALTER TABLE tb_test ADD INDEX idx_address(address);\u003C/p>\u003Cp>pt-online-schema-change工具:\u003C/p>\u003Cp>sh pt.sh tb_test \"ADD INDEX idx_address(address)\"\u003C/p>\u003Cp>\u003Cb>7.多字段添加\u003C/b>\u003C/p>\u003Cp>\u003Cb>\u003Cbr>\u003C/b>\u003C/p>\u003Cp>#! /bin/bash\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>stime=`date +%s`\u003C/p>\u003Cp>echo \"增加字段开始测试时间为：`date +%H:%M:%S`\"\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>pt-online-schema-change --alter 'ADD COLUMN col11 BIGINT(20) NULL DEFAULT -1 COMMENT \"字段注释1\" ,ADD COLUMN col2 INT(11) NULL DEFAULT -1 \\\u003C/p>\u003Cp>COMMENT \"字段注释2\" ,ADD COLUMN col3 INT(11) NULL DEFAULT -1 COMMENT \"字段注释3\";' \\\u003C/p>\u003Cp>--host=127.0.0.1 --user=root --password=mysqlpass --port=3306 D=db_order,t=tb_tablename \\\u003C/p>\u003Cp>--charset=utf8mb4 --no-check-replication-filters --max-lag 3 --check-interval 3 \\\u003C/p>\u003Cp>--chunk-size 1M --set-vars innodb_lock_wait_timeout=10,lock_wait_timeout=60 \\\u003C/p>\u003Cp>--tries create_triggers:10:1,drop_triggers:10:1,copy_rows:10:1,swap_tables:10:1 \\\u003C/p>\u003Cp>--recursion-method \"dsn=D=test,t=dsns\" --max-load Threads_running=25 --execute --statistics\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>etime=`date +%s`\u003C/p>\u003Cp>&nbsp;\u003C/p>\u003Cp>aa=`expr $etime - $stime`\u003C/p>\u003Cp>echo \"结束时间为：`date +%H:%M:%S`\"\u003C/p>\u003Cp>echo \"增加字段测试所需要的时间为：$aa\"\u003C/p>\u003Cp>\u003Ccode class=\"python string\">\u003Cbr>\u003C/code>\u003C/p>\u003Cp>\u003Cb>其他\u003C/b>\u003C/p>\u003Cp>pt-online-schema-change工具还有很多其他的参数，可以有很多限制，比如限制CPU、线程数量、从库状态等等，不过我做过一个超过6000W表的结构修改，发现几乎不影响性能，很稳定很流畅的就修改了表结构，所以，对以上常规参数的使用基本能满足业务\u003C/p>\u003Cp>一定要在业务低峰期做，这样才能确保万无一失\u003C/p>","**使用场景**\n\n在线数据库的维护中，总会涉及到研发修改表结构的情况，修改一些小表影响很小，而修改大表时，往往影响业务的正常运转，如表数据量超过500W，1000W，甚至过亿时\n\n在线修改大表的可能影响\n\n在线修改大表的表结构执行时间往往不可预估，一般时间较长\n\n由于修改表结构是表级锁，因此在修改表结构时，影响表写入操作\n\n如果长时间的修改表结构，中途修改失败，由于修改表结构是一个事务，因此失败后会还原表结构，在这个过程中表都是锁着不可写入\n\n修改大表结构容易导致数据库CPU、IO等性能消耗，使MySQL服务器性能降低\n\n在线修改大表结构容易导致主从延时，从而影响业务读取\n\npt-online-schema-change介绍\n\npt-online-schema-change是percona公司开发的一个工具，在percona-toolkit包里面可以找到这个功能，它可以在线修改表结构\n\n**原理:**\n\n首先它会新建一张一模一样的表，表名一般是_new后缀\n\n然后在这个新表执行更改字段操作\n\n然后在原表上加三个触发器，DELETE/UPDATE/INSERT，将原表中要执行的语句也在新表中执行\n\n最后将原表的数据拷贝到新表中，然后替换掉原表\n\n使用pt-online-schema-change执行SQL的日志\n\nSQL语句:\n\nALTER TABLE tmp_task_user ADD support tinyint(1) unsigned NOT NULL DEFAULT '1';\n\nsh pt.sh tmp_task_user \"ADD COLUMN support tinyint(1) unsigned NOT NULL DEFAULT '1'\"\n\ntmp_task_user\n\nADD COLUMN support tinyint(1) unsigned NOT NULL DEFAULT '1'\n\nNo slaves found.  See --recursion-method if host h=127.0.0.1,P=3306 has slaves.\n\nNot checking slave lag because no slaves were found and --check-slave-lag was not specified.\n\nOperation, tries, wait:\n\n  analyze_table, 10, 1\n\n  copy_rows, 10, 0.25\n\n  create_triggers, 10, 1\n\n  drop_triggers, 10, 1\n\n  swap_tables, 10, 1\n\n  update_foreign_keys, 10, 1\n\nAltering `test_db`.`tmp_task_user`...\n\nCreating new table...\n\nCreated new table test_db._tmp_task_user_new OK.\n\nAltering new table...\n\nAltered `test_db`.`_tmp_task_user_new` OK.\n\n2018-05-14T18:14:21 Creating triggers...\n\n2018-05-14T18:14:21 Created triggers OK.\n\n2018-05-14T18:14:21 Copying approximately 6 rows...\n\n2018-05-14T18:14:21 Copied rows OK.\n\n2018-05-14T18:14:21 Analyzing new table...\n\n2018-05-14T18:14:21 Swapping tables...\n\n2018-05-14T18:14:21 Swapped original and new tables OK.\n\n2018-05-14T18:14:21 Dropping old table...\n\n2018-05-14T18:14:21 Dropped old table `test_db`.`_tmp_task_user_old` OK.\n\n2018-05-14T18:14:21 Dropping triggers...\n\n2018-05-14T18:14:21 Dropped triggers OK.\n\nSuccessfully altered `test_db`.`tmp_task_user`.\n\n好处:\n\n降低主从延时的风险\n\n可以限速、限资源，避免操作时MySQL负载过高\n\n建议:\n\n在业务低峰期做，将影响降到最低\n\npt-online-schema-change安装\n\n1.去官网下载对应的版本，官网下载地址:https://www.percona.com/downl...\n\n**2.下载解压之后就可以看到pt-online-schema-change**\n\n![2.png](/uploads/layedit/20200512/c04eb46289014d981e00d47e7c1c7892.png)\n\n**3.该工具需要一些依赖包，直接执行不成功时一般会有提示，这里可以提前yum安装**\n\nyum install -y perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL \nperl-Digest-MD5\n\npt-online-schema-change使用\n\n1.参数\n\n./bin/pt-online-schema-change --help 可以查看参数的使用，我们只是要修改个表结构，只需要知道几个简单的参数就可以了\n\n--user=        连接mysql的用户名\n\n--password=    连接mysql的密码\n\n--host=        连接mysql的地址\n\nP=3306         连接mysql的端口号\n\nD=             连接mysql的库名\n\nt=             连接mysql的表名\n\n--alter        修改表结构的语句\n\n--execute      执行修改表结构\n\n--charset=utf8 使用utf8编码，避免中文乱码\n\n--no-version-check  不检查版本，在阿里云服务器中一般加入此参数，否则会报错\n\n2.为避免每次都要输入一堆参数，写个脚本复用一下，pt.sh\n\n#!/bin/bash\n\ntable=$1\n\nalter_conment=$2\n\ncnn_host='127.0.0.1'\n\ncnn_user='user'\n\ncnn_pwd='password'\n\ncnn_db='database_name'\n\necho \"$table\"\n\necho \"$alter_conment\"\n\n/root/percona-toolkit-3.2.0/bin/pt-online-schema-change --charset=utf8 --no-version-check --user=${cnn_user} --password=${cnn_pwd} --host=${cnn_host}  P=3306,D=${cnn_db},t=$table --alter \n\n\"${alter_conment}\" --execute\n\n**3.添加表字段**\n\n如添加表字段SQL语句为:\n\nALTER TABLE tb_test ADD COLUMN column1 tinyint(4) DEFAULT NULL;\n\n那么使用pt-online-schema-change则可以这样写\n\nsh pt.sh tb_test \"ADD COLUMN column1 tinyint(4) DEFAULT NULL\"\n\n**4.修改表字段**\n\nSQL语句：\n\nALTER TABLE tb_test MODIFY COLUMN num int(11) unsigned NOT NULL DEFAULT '0';\n\npt-online-schema-change工具:\n\nsh pt.sh tb_test \"MODIFY COLUMN num int(11) unsigned NOT NULL DEFAULT '0'\"\n\n**5.修改表字段名**\n\nSQL语句:\n\nALTER TABLE tb_test CHANGE COLUMN age adress varchar(30);\n\npt-online-schema-change工具:\n\nsh pt.sh tb_test \"CHANGE COLUMN age address varchar(30)\"\n\n**\n**\n\n**6.添加索引**\n\nSQL语句:\n\nALTER TABLE tb_test ADD INDEX idx_address(address);\n\npt-online-schema-change工具:\n\nsh pt.sh tb_test \"ADD INDEX idx_address(address)\"\n\n**7.多字段添加**\n\n**\n**\n\n#! /bin/bash\n\n \n\nstime=`date +%s`\n\necho \"增加字段开始测试时间为：`date +%H:%M:%S`\"\n\n \n\npt-online-schema-change --alter 'ADD COLUMN col11 BIGINT(20) NULL DEFAULT -1 COMMENT \"字段注释1\" ,ADD COLUMN col2 INT(11) NULL DEFAULT -1 \\\n\nCOMMENT \"字段注释2\" ,ADD COLUMN col3 INT(11) NULL DEFAULT -1 COMMENT \"字段注释3\";' \\\n\n--host=127.0.0.1 --user=root --password=mysqlpass --port=3306 D=db_order,t=tb_tablename \\\n\n--charset=utf8mb4 --no-check-replication-filters --max-lag 3 --check-interval 3 \\\n\n--chunk-size 1M --set-vars innodb_lock_wait_timeout=10,lock_wait_timeout=60 \\\n\n--tries create_triggers:10:1,drop_triggers:10:1,copy_rows:10:1,swap_tables:10:1 \\\n\n--recursion-method \"dsn=D=test,t=dsns\" --max-load Threads_running=25 --execute --statistics\n\n \n\netime=`date +%s`\n\n \n\naa=`expr $etime - $stime`\n\necho \"结束时间为：`date +%H:%M:%S`\"\n\necho \"增加字段测试所需要的时间为：$aa\"\n\n`\n`\n\n**其他**\n\npt-online-schema-change工具还有很多其他的参数，可以有很多限制，比如限制CPU、线程数量、从库状态等等，不过我做过一个超过6000W表的结构修改，发现几乎不影响性能，很稳定很流畅的就修改了表结构，所以，对以上常规参数的使用基本能满足业务\n\n一定要在业务低峰期做，这样才能确保万无一失","/article/103",7631,"2020-05-12 14:34:07","2020-05-22 00:51:26",{"id":297,"category_id":44,"title":298,"keywords":6,"description":299,"image_url":6,"content":300,"content_md":301,"url":302,"hits":303,"is_recommend":73,"is_top":73,"create_time":304,"update_time":305},102,"如何在MySQL中筛选全表扫描的SQL查询","描述提问如何在MySQL中筛选出全表扫描的SQL语句，而非通过explain命令一条条SQL语句进行查看。解决方案1、设置long_query_time时间足够大，尽量让非全表扫描且执行时间长的SQL语句不记录到慢查询日志（slow log）中；设置log_queries_not_using_indexes=on；至此全表扫描的SQL语句被记录到slow log中，值得注意的是，执行时间超过long_query_time的SQL语句也将记录到slow log中，无论该SQL语句是否使用索引。2、","\u003Cp>\u003Cstrong>\u003Cspan>描述\u003C/span>\u003C/strong>\u003C/p>\u003Cp>\u003Cspan>\u003Cspan>提问如何在\u003C/span>MySQL中筛选出全表扫描的SQL语句，而非通过explain命令一条条SQL语句进行查看。\u003C/span>\u003C/p>\u003Cp>\u003Cstrong>\u003Cspan>解决方案\u003C/span>\u003C/strong>\u003C/p>\u003Cp>\u003Cspan>1、\u003C/span>\u003Cspan>\u003Cspan>设置\u003C/span>long_query_time时间足够大，尽量让非全表扫描且执行时间长的SQL语句不记录到慢查询日志（slow log）中；\u003C/span>\u003Cspan>\u003Cbr>\u003C/span>\u003Cspan>\u003Cspan>设置\u003C/span>log_queries_not_using_indexes=on；\u003C/span>\u003Cspan>\u003Cbr>\u003C/span>\u003Cspan>\u003Cspan>至此全表扫描的\u003C/span>SQL语句被记录到slow log中，值得注意的是，执行时间超过long_query_time的SQL语句也将记录到slow log中，无论该SQL语句是否使用索引。\u003C/span>\u003C/p>\u003Cp>\u003Cspan>2、\u003C/span>\u003Cspan>\u003Cspan>使用\u003C/span>Percona Toolkit的pt-query-digest工具。\u003C/span>\u003C/p>\u003Cp>\u003Cstrong>\u003Cspan>知识点\u003C/span>\u003C/strong>\u003C/p>\u003Cp>\u003Cspan>1、\u003C/span>\u003Cspan>long_query_time参数含义：\u003C/span>\u003Cspan>\u003Cbr>\u003C/span>\u003Cspan>\u003Cspan>设置记录到\u003C/span>slow log中的SQL语句执行时间的最小值，即执行时间超过该值的SQL语句被记录到slow log中；前提为slow log为开启状态，否则该参数失效。\u003C/span>\u003C/p>\u003Cp>\u003Cspan>2、\u003C/span>\u003Cspan>log_queries_not_using_indexes参数含义：\u003C/span>\u003Cspan>\u003Cbr>\u003C/span>\u003Cspan>\u003Cspan>将没有使用索引的\u003C/span>SQL语句记录到slow log中；前提为slow log为打开\u003C/span>\u003C/p>","**\n描述\n**\n\n提问如何在\nMySQL中筛选出全表扫描的SQL语句，而非通过explain命令一条条SQL语句进行查看。\n\n**\n解决方案\n**\n\n1、\n\n设置\nlong_query_time时间足够大，尽量让非全表扫描且执行时间长的SQL语句不记录到慢查询日志（slow log）中；\n\n设置\nlog_queries_not_using_indexes=on；\n\n至此全表扫描的\nSQL语句被记录到slow log中，值得注意的是，执行时间超过long_query_time的SQL语句也将记录到slow log中，无论该SQL语句是否使用索引。\n\n2、\n\n使用\nPercona Toolkit的pt-query-digest工具。\n\n**\n知识点\n**\n\n1、\n\nlong_query_time参数含义：\n\n设置记录到\nslow log中的SQL语句执行时间的最小值，即执行时间超过该值的SQL语句被记录到slow log中；前提为slow log为开启状态，否则该参数失效。\n\n2、\n\nlog_queries_not_using_indexes参数含义：\n\n将没有使用索引的\nSQL语句记录到slow log中；前提为slow log为打开","/article/102",7526,"2020-03-04 23:14:22","2020-03-04 23:14:53",94,15,7,[310,311,312,313],{"create_time":6,"description":6,"id":44,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":23,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":53,"subtitle":6,"update_time":6,"url":59},{"create_time":6,"description":6,"id":45,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":61,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":56,"subtitle":6,"update_time":6,"url":62},{"create_time":6,"description":6,"id":46,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":64,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":65,"subtitle":6,"update_time":6,"url":66},{"create_time":6,"description":6,"id":47,"image_url":6,"index_template":52,"is_cover":53,"is_menu":53,"keywords":6,"list_template":54,"model_code":55,"model_id":56,"model_name":57,"name":68,"parent_id":39,"seo_description":6,"seo_keywords":6,"seo_title":6,"show_template":58,"sort":69,"subtitle":6,"update_time":6,"url":70},{"description":6,"keywords":6,"title":81},[316,327,328,338,349,360,361,372,383,393],{"id":317,"category_id":44,"title":318,"keywords":319,"description":320,"image_url":6,"content":321,"content_md":322,"url":323,"hits":324,"is_recommend":73,"is_top":73,"create_time":325,"update_time":326},101,"开启 HTTPS 并获得 ssllabs 满分的过程","开启,获得,满分,过程","准备工作确保你要申请证书的域名都解析到了这台服务器上，且能直接通过域名访问。使用官网推荐的CertBot获取证书。在CertBot官网选择一下环境(比如我选Nginx on Ubuntu 17.04)就可以看到入门教程了。安装CertBot12345apt-get updateapt-get install software-properties-commonadd-apt-repository ppa:certbot/certbotapt-get updateapt-get","\u003Cp style=\"text-align: justify;\">\u003Cb>一、准备工作\u003C/b>\u003C/p>\u003Cp style=\"text-align: justify;\">确保你要申请证书的域名都解析到了这台服务器上，且能直接通过域名访问。\u003C/p>\u003Cp style=\"text-align: justify;\">使用官网推荐的CertBot获取证书。\u003C/p>\u003Cp style=\"text-align: justify;\">在CertBot官网选择一下环境(比如我选Nginx on Ubuntu 17.04)就可以看到入门教程了。\u003C/p>\u003Cp style=\"text-align: justify;\">安装CertBot\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# apt-get update\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# apt-get install software-properties-common\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# add-apt-repository ppa:certbot/certbot\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# apt-get update\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# apt-get install python-certbot-nginx\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cb>二、获取证书\u003C/b>\u003C/p>\u003Cp style=\"text-align: justify;\">我是把几个域名都放到一张证书里的，这样可以支持一些比较旧的，不支持SNI的浏览器\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# certbot certonly --must-staple --rsa-key-size 4096 -d 域名1 -d 域名2...\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">这步的-rsa-key-size 4096是为了ssllabs满分，如果你不想弄这个可以不加，能略微提升网站访问速度。\u003C/p>\u003Cp style=\"text-align: justify;\">每个-d后面跟一个域名，有多少个域名跟多少个\u003C/p>\u003Cp style=\"text-align: justify;\">运行后它会让你选验证模式，我这里已经开启了nginx，因此选2，自己设置webroot\u003C/p>\u003Cp style=\"text-align: justify;\">选1然后输入你的网站静态文件所在的目录，如我的Nginx默认是/var/www/html\u003C/p>\u003Cp style=\"text-align: justify;\">之后每一个域名都需要设置，如果你所有域名都在一个目录，直接选2使用第一次输入的路径即可\u003C/p>\u003Cp style=\"text-align: justify;\">输入完最后一个域名后，它会提示你申请结果，如果失败请检查失败原因后重试，如果成功继续下一步\u003C/p>\u003Cp style=\"text-align: justify;\">我一开始因为用了国内的NS服务商，然后Let’s Encrypt访问不到就失败了，这货不会信任任何DNS服务器给出的服务器地址，必须要直接访问权威NS服务器查询的结果才可以，因此如果你因为这个失败了，建议更换一些国外的免费NS服务商。\u003C/p>\u003Cp style=\"text-align: justify;\">如果成功会告诉你申请成功，并给出你的证书路径，比如我的：/etc/letsencrypt/live/zhl123.cn/fullchain.pem\u003C/p>\u003Cp style=\"text-align: justify;\">记下这个路径(不包括fullchain.pem的部分，稍后用得着)\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cb>三、配置 DNS CAA\u003C/b>\u003C/p>\u003Cp style=\"text-align: justify;\">DNS CAA 可限制你的域名只有特定的证书签发机构可以签发证书，且无权签发的签发机构收到签发证书申请时会给你发邮件提醒\u003C/p>\u003Cp style=\"text-align: justify;\">这步不影响ssllabs评分，可不做\u003C/p>\u003Cp style=\"text-align: justify;\">你需要找一家支持CAA记录的NS服务商，国内似乎没有。。。\u003C/p>\u003Cp style=\"text-align: justify;\">我找了半天找到一家国外的：https://www.1984hosting.com/\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">通过修改域名的NS记录接入到你选择的NS服务商\u003C/p>\u003Cp style=\"text-align: justify;\">添加CAA记录，比如我的：\u003C/p>\u003Cp style=\"text-align: justify;\">issue \"letsencrypt.org\"\u003C/p>\u003Cp style=\"text-align: justify;\">iodef \"root@zhl123.cn\"\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">issue是允许哪家证书签发机构签发证书，iodef是你的邮箱地址\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">完成后可以通过dig caa 你的域名来验证是否添加成功\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cb>四、配置 nginx\u003C/b>\u003C/p>\u003Cp style=\"text-align: justify;\">编辑你每一个申请证书的域名的server配置，设置http直接跳到https\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">server {\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; listen 80;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; server_name 域名;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; return 301 https://$host$request_uri;\u003C/p>\u003Cp style=\"text-align: justify;\">}\u003C/p>\u003Cp style=\"text-align: justify;\">配置每一个域名的 https\u003C/p>\u003Cp style=\"text-align: justify;\">server {\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; # 如果 http2 报错说明你的 nginx 版本比较低不支持，删掉即可\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; listen 443 ssl http2;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; server_name 域名;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; ssl_certificate 证书路径/fullchain.pem;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; ssl_certificate_key 证书路径/privkey.pem;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; ssl_trusted_certificate 证书路径/chain.pem;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; # 强制域名使用 HTTPS 打开，且在证书不被信任时不允许用户跳过，这里设置的时间是 182.5 天\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; # includeSubDomains 表示包含子域名\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; # preload 表示允许被加入浏览器内置的强制 HTTPS 列表中\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; add_header Strict-Transport-Security \"max-age=15768000; includeSubDomains; preload\";\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; # 在检测到 XSS 时阻止网页加载\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; add_header X-XSS-Protection \"1; mode=block\";\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; # 禁止网页被嵌入 frame(算是避免运营商劫持的办法之一)\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; add_header X-Frame-Options DENY;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; # 后面可以写你的网站之前的代码，如 root /var/www/html;\u003C/p>\u003Cp style=\"text-align: justify;\">}\u003C/p>\u003Cp style=\"text-align: justify;\">配置 nginx.conf，删掉自带的 SSL 配置，用下面的覆盖\u003C/p>\u003Cp style=\"text-align: justify;\"># 只支持 TLS1.2，如果`openssl`在`1.1.1`以上，且`nginx`在`1.13`以上，可再加入`TLSv1.3`\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_protocols TLSv1.2;\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_prefer_server_ciphers on;\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_session_timeout 1d;\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_session_cache shared:SSL:10m;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_buffer_size 4k;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA';\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_ecdh_curve sect571r1:secp521r1:brainpoolP512r1:secp384r1:brainpoolP384r1:sect571k1;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_stapling on;\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_stapling_verify on;\u003C/p>\u003Cp style=\"text-align: justify;\">开启session_ticket\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">在 nginx 配置目录下执行\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# mkdir ssl\u003C/p>\u003Cp style=\"text-align: justify;\">[root@zhl123.cn ~]# openssl rand 80 &gt; ssl/ticket.key\u003C/p>\u003Cp style=\"text-align: justify;\">编辑nginx.conf，在SSL配置后面加入下面两行\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_session_ticket_key ssl/ticket.key;\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_session_tickets on;\u003C/p>\u003Cp style=\"text-align: justify;\">使用4096位加密\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">在 nginx 配置目录下执行\u003C/p>\u003Cp style=\"text-align: justify;\">openssl dhparam -out ssl/dhparam.pem 4096\u003C/p>\u003Cp style=\"text-align: justify;\">编辑nginx.conf，在SSL配置后面加入下面两行\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">ssl_dhparam ssl/dhparam.pem;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cb>五、一些额外的配置\u003C/b>\u003C/p>\u003Cp style=\"text-align: justify;\">开启 HPKP\u003C/p>\u003Cp style=\"text-align: justify;\">HPKP可以检查你的证书是不是指定的证书签发机构签的，如果不是会阻止访问，也可配置出现问题时向指定地址报告等\u003C/p>\u003Cp style=\"text-align: justify;\">在你的浏览器访问https://www.ssllabs.com/ssltest/analyze.html?d=你的域名\u003C/p>\u003Cp style=\"text-align: justify;\">等测试结束后，在页面搜索Certification Paths\u003C/p>\u003Cp style=\"text-align: justify;\">点击下面的展开\u003C/p>\u003Cp style=\"text-align: justify;\">把第一行不是你的域名的Pin SHA256的值记录下来\u003C/p>\u003Cp style=\"text-align: justify;\">换一个免费证书，再来一次，比如腾讯云可以申请赛门特克的免费证书\u003C/p>\u003Cp style=\"text-align: justify;\">把你刚刚记下来的几个值(至少4个，无顺序要求)，按下面的格式写入你每一个域名的server配置中\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\"># 如果有更多按照格式加就行\u003C/p>\u003Cp style=\"text-align: justify;\">add_header Public-Key-Pins 'pin-sha256=\"第一个值\"; pin-sha256=\"第二个值\"; pin-sha256=\"第三个值\"; pin-sha256=\"第四个值\"; max-age=15768000; includeSubDomains';\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">申请浏览器内置HSTS\u003C/p>\u003Cp style=\"text-align: justify;\">HSTS可以要求用户访问你的网站必须用HTTPS协议，然而需要至少访问一次才会生效，这一次仍然有可能被劫持，而且有可能被一些更无良的运营商给HTTPS强转HTTP，用户永远不会把你加进HSTS名单\u003C/p>\u003Cp style=\"text-align: justify;\">为了解决这个尴尬的问题，浏览器商们推出了一个申请地址，符合要求的域名可以申请把自己加入浏览器的源代码中，这样用户首次访问的时候也会强制用HTTPS访问\u003C/p>\u003Cp style=\"text-align: justify;\">请一定注意，一旦申请成功，就没有回头路了，如果哪天你不想用HTTPS了，那就只能换个域名了。\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">确保你申请证书的时候包含你的主域名，如我的是zhl123.cn，不能带任何子域名，如www.zhl123.cn无效\u003C/p>\u003Cp style=\"text-align: justify;\">确保你照做了上面的4.2\u003C/p>\u003Cp style=\"text-align: justify;\">访问申请页面，输入你的主域名，提交即可，稍后的提示确认，打勾后再提交即可\u003C/p>\u003Cp style=\"text-align: justify;\">耐心等待审核，一般一个月内可审核完成，审核完成之前请不要修改网站配置。\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cb>六、自动重新签发证书\u003C/b>\u003C/p>\u003Cp style=\"text-align: justify;\">Let’s Encrypt申请的证书只有3个月有效期，每隔3个月都手动来重新签发一次。\u003C/p>\u003Cp style=\"text-align: justify;\">通过crontab在每月1号自动重新签发证书\u003C/p>\u003Cp style=\"text-align: justify;\">执行crontab -e,添加下面一行保存即可\u003C/p>\u003Cp style=\"text-align: justify;\">0 0 1 * * certbot renew --force-renew &amp;&amp; /etc/init.d/nginx reload\u003C/p>\u003Col style=\"text-align: justify;\">\u003Cli>\u003Cfigure class=\"highlight plain\">\u003C/figure>\u003C/li>\u003C/ol>","**一、准备工作**\n\n确保你要申请证书的域名都解析到了这台服务器上，且能直接通过域名访问。\n\n使用官网推荐的CertBot获取证书。\n\n在CertBot官网选择一下环境(比如我选Nginx on Ubuntu 17.04)就可以看到入门教程了。\n\n安装CertBot\n\n[root@zhl123.cn ~]# apt-get update\n\n[root@zhl123.cn ~]# apt-get install software-properties-common\n\n[root@zhl123.cn ~]# add-apt-repository ppa:certbot/certbot\n\n[root@zhl123.cn ~]# apt-get update\n\n[root@zhl123.cn ~]# apt-get install python-certbot-nginx\n\n**二、获取证书**\n\n我是把几个域名都放到一张证书里的，这样可以支持一些比较旧的，不支持SNI的浏览器\n\n[root@zhl123.cn ~]# certbot certonly --must-staple --rsa-key-size 4096 -d 域名1 -d 域名2...\n\n这步的-rsa-key-size 4096是为了ssllabs满分，如果你不想弄这个可以不加，能略微提升网站访问速度。\n\n每个-d后面跟一个域名，有多少个域名跟多少个\n\n运行后它会让你选验证模式，我这里已经开启了nginx，因此选2，自己设置webroot\n\n选1然后输入你的网站静态文件所在的目录，如我的Nginx默认是/var/www/html\n\n之后每一个域名都需要设置，如果你所有域名都在一个目录，直接选2使用第一次输入的路径即可\n\n输入完最后一个域名后，它会提示你申请结果，如果失败请检查失败原因后重试，如果成功继续下一步\n\n我一开始因为用了国内的NS服务商，然后Let’s Encrypt访问不到就失败了，这货不会信任任何DNS服务器给出的服务器地址，必须要直接访问权威NS服务器查询的结果才可以，因此如果你因为这个失败了，建议更换一些国外的免费NS服务商。\n\n如果成功会告诉你申请成功，并给出你的证书路径，比如我的：/etc/letsencrypt/live/zhl123.cn/fullchain.pem\n\n记下这个路径(不包括fullchain.pem的部分，稍后用得着)\n\n**三、配置 DNS CAA**\n\nDNS CAA 可限制你的域名只有特定的证书签发机构可以签发证书，且无权签发的签发机构收到签发证书申请时会给你发邮件提醒\n\n这步不影响ssllabs评分，可不做\n\n你需要找一家支持CAA记录的NS服务商，国内似乎没有。。。\n\n我找了半天找到一家国外的：https://www.1984hosting.com/\n\n通过修改域名的NS记录接入到你选择的NS服务商\n\n添加CAA记录，比如我的：\n\nissue \"letsencrypt.org\"\n\niodef \"root@zhl123.cn\"\n\nissue是允许哪家证书签发机构签发证书，iodef是你的邮箱地址\n\n完成后可以通过dig caa 你的域名来验证是否添加成功\n\n**四、配置 nginx**\n\n编辑你每一个申请证书的域名的server配置，设置http直接跳到https\n\nserver {\n\n  listen 80;\n\n  server_name 域名;\n\n  return 301 https://$host$request_uri;\n\n}\n\n配置每一个域名的 https\n\nserver {\n\n  # 如果 http2 报错说明你的 nginx 版本比较低不支持，删掉即可\n\n  listen 443 ssl http2;\n\n  server_name 域名;\n\n  ssl_certificate 证书路径/fullchain.pem;\n\n  ssl_certificate_key 证书路径/privkey.pem;\n\n  ssl_trusted_certificate 证书路径/chain.pem;\n\n  # 强制域名使用 HTTPS 打开，且在证书不被信任时不允许用户跳过，这里设置的时间是 182.5 天\n\n  # includeSubDomains 表示包含子域名\n\n  # preload 表示允许被加入浏览器内置的强制 HTTPS 列表中\n\n  add_header Strict-Transport-Security \"max-age=15768000; includeSubDomains; preload\";\n\n  # 在检测到 XSS 时阻止网页加载\n\n  add_header X-XSS-Protection \"1; mode=block\";\n\n  # 禁止网页被嵌入 frame(算是避免运营商劫持的办法之一)\n\n  add_header X-Frame-Options DENY;\n\n  # 后面可以写你的网站之前的代码，如 root /var/www/html;\n\n}\n\n配置 nginx.conf，删掉自带的 SSL 配置，用下面的覆盖\n\n# 只支持 TLS1.2，如果`openssl`在`1.1.1`以上，且`nginx`在`1.13`以上，可再加入`TLSv1.3`\n\nssl_protocols TLSv1.2;\n\nssl_prefer_server_ciphers on;\n\nssl_session_timeout 1d;\n\nssl_session_cache shared:SSL:10m;\n\nssl_buffer_size 4k;\n\nssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA';\n\nssl_ecdh_curve sect571r1:secp521r1:brainpoolP512r1:secp384r1:brainpoolP384r1:sect571k1;\n\nssl_stapling on;\n\nssl_stapling_verify on;\n\n开启session_ticket\n\n在 nginx 配置目录下执行\n\n[root@zhl123.cn ~]# mkdir ssl\n\n[root@zhl123.cn ~]# openssl rand 80 > ssl/ticket.key\n\n编辑nginx.conf，在SSL配置后面加入下面两行\n\nssl_session_ticket_key ssl/ticket.key;\n\nssl_session_tickets on;\n\n使用4096位加密\n\n在 nginx 配置目录下执行\n\nopenssl dhparam -out ssl/dhparam.pem 4096\n\n编辑nginx.conf，在SSL配置后面加入下面两行\n\nssl_dhparam ssl/dhparam.pem;\n\n**五、一些额外的配置**\n\n开启 HPKP\n\nHPKP可以检查你的证书是不是指定的证书签发机构签的，如果不是会阻止访问，也可配置出现问题时向指定地址报告等\n\n在你的浏览器访问https://www.ssllabs.com/ssltest/analyze.html?d=你的域名\n\n等测试结束后，在页面搜索Certification Paths\n\n点击下面的展开\n\n把第一行不是你的域名的Pin SHA256的值记录下来\n\n换一个免费证书，再来一次，比如腾讯云可以申请赛门特克的免费证书\n\n把你刚刚记下来的几个值(至少4个，无顺序要求)，按下面的格式写入你每一个域名的server配置中\n\n# 如果有更多按照格式加就行\n\nadd_header Public-Key-Pins 'pin-sha256=\"第一个值\"; pin-sha256=\"第二个值\"; pin-sha256=\"第三个值\"; pin-sha256=\"第四个值\"; max-age=15768000; includeSubDomains';\n\n申请浏览器内置HSTS\n\nHSTS可以要求用户访问你的网站必须用HTTPS协议，然而需要至少访问一次才会生效，这一次仍然有可能被劫持，而且有可能被一些更无良的运营商给HTTPS强转HTTP，用户永远不会把你加进HSTS名单\n\n为了解决这个尴尬的问题，浏览器商们推出了一个申请地址，符合要求的域名可以申请把自己加入浏览器的源代码中，这样用户首次访问的时候也会强制用HTTPS访问\n\n请一定注意，一旦申请成功，就没有回头路了，如果哪天你不想用HTTPS了，那就只能换个域名了。\n\n确保你申请证书的时候包含你的主域名，如我的是zhl123.cn，不能带任何子域名，如www.zhl123.cn无效\n\n确保你照做了上面的4.2\n\n访问申请页面，输入你的主域名，提交即可，稍后的提示确认，打勾后再提交即可\n\n耐心等待审核，一般一个月内可审核完成，审核完成之前请不要修改网站配置。\n\n**六、自动重新签发证书**\n\nLet’s Encrypt申请的证书只有3个月有效期，每隔3个月都手动来重新签发一次。\n\n通过crontab在每月1号自动重新签发证书\n\n执行crontab -e,添加下面一行保存即可\n\n0 0 1 * * certbot renew --force-renew && /etc/init.d/nginx reload\n\n1.","/article/101",18546,"2019-11-26 16:12:11","2019-11-26 16:23:16",{"id":210,"category_id":44,"title":211,"keywords":212,"description":213,"image_url":6,"content":214,"content_md":215,"url":216,"hits":217,"is_recommend":73,"is_top":73,"create_time":218,"update_time":219},{"id":306,"category_id":44,"title":329,"keywords":330,"description":331,"image_url":6,"content":332,"content_md":333,"url":334,"hits":335,"is_recommend":53,"is_top":73,"create_time":336,"update_time":337},"Centos7 安装 openvas ","openvas,开放式漏洞评估系统，installing openvas centos-7","一、描述OpenVAS，即开放式漏洞评估系统，是一个用于评估目标漏洞的杰出框架。功能十分强大，最重要的是，它是“开源”的——就是免费的意思啦～它与著名的Nessus“本是同根生”，在Nessus商业化之后仍然坚持开源，号称“当前最好用的开源漏洞扫描工具”。最新版的Kali Linux(kali 3.0)不再自带OpenVAS了，所以我们要自己部署OpenVAS漏洞检测系统。其核心部件是一个服务器，包括一套网络漏洞测试程序，可以检测远程系统和应用程序中的安全问题。但是它的最常用用途是检测目标网络或","\u003Cp>一、描述\u003C/p>\u003Cp>\u003Cspan>\u003Cspan>OpenVAS，即开放式漏洞评估系统，是一个用于评估目标漏洞的杰出框架。功能十分强大，最重要的是，它是“开源”的——就是免费的意思啦～\u003C/span>\u003C/span>\u003C/p>\u003Cp>它与著名的Nessus“本是同根生”，在Nessus商业化之后仍然坚持开源，号称“当前最好用的开源漏洞扫描工具”。最新版的Kali Linux(kali 3.0)不再自带OpenVAS了，所以我们要自己部署OpenVAS漏洞检测系统。其核心部件是一个服务器，包括一套网络漏洞测试程序，可以检测远程系统和应用程序中的安全问题。\u003C/p>\u003Cp>但是它的最常用用途是检测目标网络或主机的安全性。它的评估能力来源于数万个漏洞测试程序，这些程序都是以插件的形式存在。openvas是基于C/S（客户端/服务器），B/S(浏览器/服务器)架构进行工作，用户通过浏览器或者专用客户端程序来下达扫描任务，服务器端负责授权，执行扫描操作并提供扫描结果。\u003C/p>\u003Cp>二、OpenVAS系统架构\u003C/p>\u003Cp>\u003Cspan>\u003C/span>\u003C/p>\u003Cp>一套完整的openvas系统包括服务器端和客户端的多个组件，如下图所示：\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20190114/e4fd816cd295568501641e3c5f19a504.png\" alt=\"openvas.png\">\u003Cbr>\u003C/p>\u003Cp>三、安装部署\u003C/p>\u003Cp>1、安装CentOS 7\u003C/p>\u003Cp>首先，我首先选择最小的CentOS安装。安装花费的时间更少，文件系统占用的空间更少，我鄙视更新我从未使用过的软件包！下载最新版本的CentOS 7并完成标准安装。如果你虚拟安装OpenVAS，我建议至少2个CPU，3GB内存和30GB硬盘（这取决于扫描次数和你将保留多少数据）。\u003C/p>\u003Cp>配置CentOS\u003C/p>\u003Cp>如果您启用SELinux，OpenVAS将会访问异常，因此请使用以下命令禁用它。\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>[root@localhost ~]# sed -i's / = enforcing / = disabled /'/ etc / selinux / config\u003C/p>\u003Cp>[root@localhost ~]#&nbsp;setenforce 0\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>同时打开OpenVAS Web界面的必要端口。\u003C/p>\u003Cp>[root@localhost ~]# firewall-cmd --zone = public --add-port = 9392 / tcp --permanent\u003C/p>\u003Cp>[root@localhost ~]# firewall-cmd --reload\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>2、安装OpenVAS\u003C/p>\u003Cp>[root@localhost ~]# yum -y install wget net-tools\u003C/p>\u003Cp>[root@localhost ~]# wget -q -O&nbsp; -&nbsp; https://www.zhl123.com/download/linux/openvas/atomic | sh\u003C/p>\u003Cp>[root@localhost ~]# yum -y install openvas\u003C/p>\u003Cp>当yum完成时，使用下面的“sed”命令取消注释/etc/redis.conf文件中的以下2个与unixsocket相关的行。\u003C/p>\u003Cp>#unixsocket /tmp/redis.sock\u003C/p>\u003Cp>#unixsocketperm 700\u003C/p>\u003Cp>[root@localhost ~]# sed -i '/^#.*unixsocket/s/^# //' /etc/redis.conf\u003C/p>\u003Cp>启用redis服务\u003C/p>\u003Cp>[root@localhost ~]# systemctl enable redis &amp;&amp; systemctl restart redis\u003C/p>\u003Cp>3、配置OpenVAS\u003C/p>\u003Cp>运行openvas-setup并接受rsync作为默认值。这可能需要一段时间，所以要耐心等待\u003C/p>\u003Cp>[root@localhost ~]#&nbsp;&nbsp;\u003Cspan style=\"text-align: justify;\">openvas-setup\u003C/span>\u003C/p>\u003Cpre style=\"text-align: justify;\">-- Output --\nOpenvas Setup, Version: 3.0\n\nStep 1: Update NVT, CERT, and SCAP data\nPlease note this step could take some time.\nOnce completed, this will be updated automatically every 24 hours\n\nSelect download method\n* wget (NVT download only)\n* curl (NVT download only)\n* rsync\n\nNote: If rsync requires a proxy, you should define that before this step.&nbsp;\u003C/pre>\u003Cp>\u003Cspan style=\"text-align: justify;\">Downloader [Default: rsync]\u003C/span>\u003C/p>\u003Cpre style=\"text-align: justify;\">openvas-check-setup --v9\n-- Output --\n...\nStep 10: Checking presence of optional tools ...\nOK: pdflatex found.\nWARNING: PDF generation failed, most likely due to missing LaTeX packages. The PDF report format will not work.\nSUGGEST: Install required LaTeX packages.\n&nbsp;\u003C/pre>\u003Cp style=\"text-align: justify;\">访问OpenVAS Web界面\u003C/p>\u003Cp style=\"text-align: justify;\">通过访问https:// &lt;您的IP地址&gt;：9392从任何浏览器访问Web界面。\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cimg src=\"/uploads/layedit/20190114/936c2eaa9b339597b99c5703b316f0ac.png\" alt=\"openvas_login.png\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">4、配置自动更新Feed\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cspan style=\"text-align: start;\">[root@localhost ~]#&nbsp;\u003C/span>crontab -e\u003C/p>\u003Cp style=\"text-align: justify;\">35 1 * * * /usr/sbin/greenbone-nvt-sync &gt; /dev/null&nbsp;\u003C/p>\u003Cp style=\"text-align: justify;\">5 0 * * * /usr/sbin/greenbone-scapdata-sync &gt; /dev/null&nbsp;\u003C/p>\u003Cp style=\"text-align: justify;\">5 1 * * * /usr/sbin/greenbone-certdata-sync &gt; /dev/null&nbsp;\u003C/p>\u003Cp>5、配置pdf报告输出\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cfont>[root@localhost ~]# yum -y install texlive-collection-fontsrecommended texlive-collection-latexrecommended texlive-changepage texlive-titlesec\u003C/font>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cfont>\u003Cspan style=\"text-align: start;\">[root@localhost ~]#&nbsp;\u003C/span>\u003C/font>mkdir -p /usr/share/texlive/texmf-local/tex/latex/comment\u003C/p>\u003Cp style=\"text-align: start;\">[root@localhost ~]#&nbsp; cd /usr/share/texlive/texmf-local/tex/latex/comment\u003C/p>\u003Cp style=\"text-align: start;\">[root@localhost ~]#&nbsp; wget https://www.zhl123.com/download/linux/openvas/comment.sty\u003C/p>\u003Cp style=\"text-align: start;\">[root@localhost ~]#&nbsp; chmod 644 comment.sty\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cfont>\u003Cspan style=\"text-align: start;\">[root@localhost ~]#&nbsp;&nbsp;\u003C/span>\u003C/font>\u003Cspan>openvas-check-setup --v9\u003C/span>\u003C/p>\u003Cpre style=\"text-align: justify;\">-- Output --\n...\nStep 10: Checking presence of optional tools ...\nOK: pdflatex found.\nOK: PDF generation successful. The PDF report format is likely to work.\u003C/pre>","一、描述\n\nOpenVAS，即开放式漏洞评估系统，是一个用于评估目标漏洞的杰出框架。功能十分强大，最重要的是，它是“开源”的——就是免费的意思啦～\n\n它与著名的Nessus“本是同根生”，在Nessus商业化之后仍然坚持开源，号称“当前最好用的开源漏洞扫描工具”。最新版的Kali Linux(kali 3.0)不再自带OpenVAS了，所以我们要自己部署OpenVAS漏洞检测系统。其核心部件是一个服务器，包括一套网络漏洞测试程序，可以检测远程系统和应用程序中的安全问题。\n\n但是它的最常用用途是检测目标网络或主机的安全性。它的评估能力来源于数万个漏洞测试程序，这些程序都是以插件的形式存在。openvas是基于C/S（客户端/服务器），B/S(浏览器/服务器)架构进行工作，用户通过浏览器或者专用客户端程序来下达扫描任务，服务器端负责授权，执行扫描操作并提供扫描结果。\n\n二、OpenVAS系统架构\n\n一套完整的openvas系统包括服务器端和客户端的多个组件，如下图所示：\n\n![openvas.png](/uploads/layedit/20190114/e4fd816cd295568501641e3c5f19a504.png)\n\n三、安装部署\n\n1、安装CentOS 7\n\n首先，我首先选择最小的CentOS安装。安装花费的时间更少，文件系统占用的空间更少，我鄙视更新我从未使用过的软件包！下载最新版本的CentOS 7并完成标准安装。如果你虚拟安装OpenVAS，我建议至少2个CPU，3GB内存和30GB硬盘（这取决于扫描次数和你将保留多少数据）。\n\n配置CentOS\n\n如果您启用SELinux，OpenVAS将会访问异常，因此请使用以下命令禁用它。\n\n[root@localhost ~]# sed -i's / = enforcing / = disabled /'/ etc / selinux / config\n\n[root@localhost ~]# setenforce 0\n\n同时打开OpenVAS Web界面的必要端口。\n\n[root@localhost ~]# firewall-cmd --zone = public --add-port = 9392 / tcp --permanent\n\n[root@localhost ~]# firewall-cmd --reload\n\n2、安装OpenVAS\n\n[root@localhost ~]# yum -y install wget net-tools\n\n[root@localhost ~]# wget -q -O  -  https://www.zhl123.com/download/linux/openvas/atomic | sh\n\n[root@localhost ~]# yum -y install openvas\n\n当yum完成时，使用下面的“sed”命令取消注释/etc/redis.conf文件中的以下2个与unixsocket相关的行。\n\n#unixsocket /tmp/redis.sock\n\n#unixsocketperm 700\n\n[root@localhost ~]# sed -i '/^#.*unixsocket/s/^# //' /etc/redis.conf\n\n启用redis服务\n\n[root@localhost ~]# systemctl enable redis && systemctl restart redis\n\n3、配置OpenVAS\n\n运行openvas-setup并接受rsync作为默认值。这可能需要一段时间，所以要耐心等待\n\n[root@localhost ~]#  \nopenvas-setup\n\n```\n-- Output --\nOpenvas Setup, Version: 3.0\n\nStep 1: Update NVT, CERT, and SCAP data\nPlease note this step could take some time.\nOnce completed, this will be updated automatically every 24 hours\n\nSelect download method\n* wget (NVT download only)\n* curl (NVT download only)\n* rsync\n\nNote: If rsync requires a proxy, you should define that before this step. \n```\n\nDownloader [Default: rsync]\n\n```\nopenvas-check-setup --v9\n-- Output --\n...\nStep 10: Checking presence of optional tools ...\nOK: pdflatex found.\nWARNING: PDF generation failed, most likely due to missing LaTeX packages. The PDF report format will not work.\nSUGGEST: Install required LaTeX packages.\n \n```\n\n访问OpenVAS Web界面\n\n通过访问https:// ：9392从任何浏览器访问Web界面。\n\n![openvas_login.png](/uploads/layedit/20190114/936c2eaa9b339597b99c5703b316f0ac.png)\n\n4、配置自动更新Feed\n\n[root@localhost ~]# \ncrontab -e\n\n35 1 * * * /usr/sbin/greenbone-nvt-sync > /dev/null \n\n5 0 * * * /usr/sbin/greenbone-scapdata-sync > /dev/null \n\n5 1 * * * /usr/sbin/greenbone-certdata-sync > /dev/null \n\n5、配置pdf报告输出\n\n[root@localhost ~]# yum -y install texlive-collection-fontsrecommended texlive-collection-latexrecommended texlive-changepage texlive-titlesec\n\n[root@localhost ~]# \n\nmkdir -p /usr/share/texlive/texmf-local/tex/latex/comment\n\n[root@localhost ~]#  cd /usr/share/texlive/texmf-local/tex/latex/comment\n\n[root@localhost ~]#  wget https://www.zhl123.com/download/linux/openvas/comment.sty\n\n[root@localhost ~]#  chmod 644 comment.sty\n\n[root@localhost ~]#  \n\nopenvas-check-setup --v9\n\n```\n-- Output --\n...\nStep 10: Checking presence of optional tools ...\nOK: pdflatex found.\nOK: PDF generation successful. The PDF report format is likely to work.\n```","/article/94",14690,"2019-01-14 17:43:42","2019-01-14 18:16:36",{"id":339,"category_id":44,"title":340,"keywords":341,"description":342,"image_url":6,"content":343,"content_md":344,"url":345,"hits":346,"is_recommend":73,"is_top":73,"create_time":347,"update_time":348},99,"Centos7 利用iptables防止nmap工具防端口扫描","iptables","一、Nmap介绍       Nmap（NetworkMapper）是一款开放源代码的网络探测和安全审核工具。它用于快速扫描一个网络和一台主机开放的端口，还能使用TCP/IP协议栈特征探测远程主机的操作系统类型。nmap支持很多扫描技术，例如：UDP、TCPconnect()、TCPSYN(半开扫描)、ftp代理(bounce攻击)、反向标志、ICMP、FIN、ACK扫描、圣诞树(XmasTree)、SYN扫描和null扫描。Nmap最初是用于Unix系统","\u003Cp align=\"justify\">\u003Cspan>一、\u003C/span>Nmap介绍\u003C/p>\u003Cp align=\"justify\">\u003Cspan>&nbsp; &nbsp; &nbsp; &nbsp;Nmap\u003Cspan>（\u003C/span>\u003Cspan>NetworkMapper\u003C/span>\u003Cspan>）是一款开放源代码的网络探测和安全审核工具。它用于快速扫描一个网络和一台主机开放的端口，还能使用\u003C/span>\u003Cspan>TCP/IP\u003C/span>\u003Cspan>协议栈特征探测远程主机的操作系统类型。nmap\u003C/span>\u003C/span>\u003Cspan>支持很多扫描技术，例如：\u003Cspan>UDP\u003C/span>\u003Cspan>、\u003C/span>\u003Cspan>TCP\u003C/span>\u003Cspan>connect()\u003C/span>\u003Cspan>、\u003C/span>\u003Cspan>TCP\u003C/span>\u003Cspan>SYN(\u003C/span>\u003Cspan>半开扫描\u003C/span>\u003Cspan>)\u003C/span>\u003Cspan>、\u003C/span>\u003Cspan>ftp\u003C/span>\u003Cspan>代理\u003C/span>\u003Cspan>(bounce\u003C/span>\u003Cspan>攻击\u003C/span>\u003Cspan>)\u003C/span>\u003Cspan>、反向标志、\u003C/span>\u003Cspan>ICMP\u003C/span>\u003Cspan>、\u003C/span>\u003Cspan>FIN\u003C/span>\u003Cspan>、\u003C/span>\u003Cspan>ACK\u003C/span>\u003Cspan>扫描、圣诞树\u003C/span>\u003Cspan>(Xmas\u003C/span>\u003Cspan>Tree)\u003C/span>\u003Cspan>、\u003C/span>\u003Cspan>SYN\u003C/span>\u003Cspan>扫描和\u003C/span>\u003Cspan>null\u003C/span>\u003Cspan>扫描。\u003C/span>\u003Cspan>Nmap\u003C/span>\u003Cspan>最初是用于Unix\u003C/span>\u003C/span>\u003Cspan>系统的命令行应用程序。\u003C/span>\u003C/p>\u003Cp align=\"justify\">\u003Cspan>二、描述\u003C/span>\u003C/p>\u003Cp align=\"justify\">\u003Cspan>&nbsp; &nbsp; &nbsp; &nbsp;既然\u003Cspan>nmap\u003C/span>\u003Cspan>这个工具能探测到网络中的某一台主机开放的端口、用了什么协议等等，从而成为黑客攻击前踩点的工具，一旦得逞，后果将不堪设想。那么我们如何利用\u003C/span>\u003Cspan>iptables\u003C/span>\u003Cspan>来防止\u003C/span>\u003Cspan>nmap\u003C/span>\u003Cspan>这个工具的嗅探呢？有攻就必有防，\u003C/span>\u003Cspan>Linux\u003C/span>\u003Cspan>系统的\u003C/span>\u003Cspan>iptables\u003C/span>\u003Cspan>可以对封包起到一个过滤、限制的作用。\u003C/span>\u003C/span>\u003C/p>\u003Cp align=\"justify\">\u003Cspan>\u003Cspan>三、演练与实战\u003C/span>\u003C/span>\u003C/p>\u003Cp align=\"justify\">\u003Cspan>\u003Cspan>&nbsp; &nbsp; &nbsp;1、\u003C/span>\u003C/span>\u003Cspan>下面我在\u003C/span>\u003Cspan>虚拟机\u003C/span>\u003Cspan>使用\u003C/span>\u003Cspan>nmap\u003C/span>\u003Cspan>工具扫描测试\u003C/span>\u003Cspan>Linux\u003C/span>\u003Cspan>主机，在测试的\u003C/span>\u003Cspan>Linux\u003C/span>\u003Cspan>主机\u003C/span>\u003Cspan>iptables\u003C/span>\u003Cspan>不做任何防范的情况下先扫描看看，如下\u003C/span>\u003C/p>\u003Cp align=\"justify\">\u003Cspan>\u003Cimg src=\"/uploads/layedit/20190709/1f199a47370236d7fcb4d5586b683589.png\" alt=\"iptables-01.png\">\u003Cbr>\u003C/span>\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; 从上图可看出，这台机器开启了22、80、443端口\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp;2、现在开启iptables规则，进行防御看看效果\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp;a、首先关闭Centos7自带的\u003Cspan>firewalld，安装iptables服务\u003C/span>\u003C/p>\u003Cp align=\"justify\">\u003Cspan>&nbsp; &nbsp;\u003C/span>[root@VM_0_15_centos ~]#&nbsp;systemctl disable firewalld.service &amp;&amp;&nbsp;systemctl stop firewalld.service\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp;[root@VM_0_15_centos ~]# yum install iptables-services iptables-devel&nbsp; -y\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp;[root@VM_0_15_centos ~]# systemctl enable iptables&nbsp;\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp;b、 配置iptables\u003C/p>\u003Cp align=\"justify\">&nbsp; [root@VM_0_15_centos ~]# vim /etc/sysconfig/iptables\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Generated by iptables-save v1.4.21 on Tue Jul&nbsp; 9 21:09:09 2019\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; *filter\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:INPUT ACCEPT [0:0]\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:FORWARD ACCEPT [0:0]&nbsp;\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j REJECT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j REJECT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j REJECT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -p icmp -j ACCEPT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -i lo -j ACCEPT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A INPUT -j REJECT --reject-with icmp-host-prohibited\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-A FORWARD -j REJECT --reject-with icmp-host-prohibited\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;COMMIT\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Completed on Tue Jul&nbsp; 9 21:09:09 2019\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp;c、启动iptables\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp;[root@VM_0_15_centos ~]#&nbsp;systemctl start iptables\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp;d、同样用nmap -A 进行扫描一下，结果如下：\u003C/p>\u003Cp align=\"justify\">&nbsp; &nbsp; &nbsp;&nbsp;\u003Cimg src=\"/uploads/layedit/20190709/0fdb30f3b00a7e9e68fe1c24091023dd.png\" alt=\"iptables-02.png\">\u003C/p>","一、\nNmap介绍\n\n       Nmap\n（\n\nNetworkMapper\n\n）是一款开放源代码的网络探测和安全审核工具。它用于快速扫描一个网络和一台主机开放的端口，还能使用\n\nTCP/IP\n\n协议栈特征探测远程主机的操作系统类型。nmap\n\n支持很多扫描技术，例如：\nUDP\n\n、\n\nTCP\n\nconnect()\n\n、\n\nTCP\n\nSYN(\n\n半开扫描\n\n)\n\n、\n\nftp\n\n代理\n\n(bounce\n\n攻击\n\n)\n\n、反向标志、\n\nICMP\n\n、\n\nFIN\n\n、\n\nACK\n\n扫描、圣诞树\n\n(Xmas\n\nTree)\n\n、\n\nSYN\n\n扫描和\n\nnull\n\n扫描。\n\nNmap\n\n最初是用于Unix\n\n系统的命令行应用程序。\n\n二、描述\n\n       既然\nnmap\n\n这个工具能探测到网络中的某一台主机开放的端口、用了什么协议等等，从而成为黑客攻击前踩点的工具，一旦得逞，后果将不堪设想。那么我们如何利用\n\niptables\n\n来防止\n\nnmap\n\n这个工具的嗅探呢？有攻就必有防，\n\nLinux\n\n系统的\n\niptables\n\n可以对封包起到一个过滤、限制的作用。\n\n三、演练与实战\n\n     1、\n\n下面我在\n\n虚拟机\n\n使用\n\nnmap\n\n工具扫描测试\n\nLinux\n\n主机，在测试的\n\nLinux\n\n主机\n\niptables\n\n不做任何防范的情况下先扫描看看，如下\n\n![iptables-01.png](/uploads/layedit/20190709/1f199a47370236d7fcb4d5586b683589.png)\n\n    从上图可看出，这台机器开启了22、80、443端口\n\n   2、现在开启iptables规则，进行防御看看效果\n\n   a、首先关闭Centos7自带的\nfirewalld，安装iptables服务\n\n   \n[root@VM_0_15_centos ~]# systemctl disable firewalld.service && systemctl stop firewalld.service\n\n   [root@VM_0_15_centos ~]# yum install iptables-services iptables-devel  -y\n\n   [root@VM_0_15_centos ~]# systemctl enable iptables \n\n   b、 配置iptables\n\n  [root@VM_0_15_centos ~]# vim /etc/sysconfig/iptables\n\n         # Generated by iptables-save v1.4.21 on Tue Jul  9 21:09:09 2019\n\n        *filter\n\n         :INPUT ACCEPT [0:0]\n\n         :FORWARD ACCEPT [0:0] \n\n         -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j REJECT\n\n         -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j REJECT\n\n         -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j REJECT\n\n         -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n\n         -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT\n\n         -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT\n\n         -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT\n\n         -A INPUT -p icmp -j ACCEPT\n\n         -A INPUT -i lo -j ACCEPT\n\n         -A INPUT -j REJECT --reject-with icmp-host-prohibited\n\n         -A FORWARD -j REJECT --reject-with icmp-host-prohibited\n\n         COMMIT\n\n         # Completed on Tue Jul  9 21:09:09 2019\n\n     c、启动iptables\n\n     [root@VM_0_15_centos ~]# systemctl start iptables\n\n     d、同样用nmap -A 进行扫描一下，结果如下：\n\n      ![iptables-02.png](/uploads/layedit/20190709/0fdb30f3b00a7e9e68fe1c24091023dd.png)","/article/99",14415,"2019-07-09 21:27:00","2019-07-09 21:57:53",{"id":350,"category_id":46,"title":351,"keywords":352,"description":353,"image_url":6,"content":354,"content_md":355,"url":356,"hits":357,"is_recommend":73,"is_top":73,"create_time":358,"update_time":359},61,"Docker 推荐的启动方式","推荐,启动,方式","# cat DockerfileFROM openjdk:8-alpineWORKDIR /ADD ./target/*.jar app.jarEXPOSE 9999COPY docker-entrypoint.sh /RUN chmod +x /docker-entrypoint.shENTRYPOINT [“/docker-entrypoint.sh”]CMD [“java”,”-server”,”-Duser.timezone=GMT+08″,”-jar”,”/app.jar”]# cat","\u003Cp># cat Dockerfile\u003Cbr>FROM openjdk:8-alpine\u003Cbr>WORKDIR /\u003Cbr>ADD ./target/*.jar app.jar\u003Cbr>EXPOSE 9999\u003Cbr>COPY docker-entrypoint.sh /\u003Cbr>RUN chmod +x /docker-entrypoint.sh\u003Cbr>ENTRYPOINT [“/docker-entrypoint.sh”]\u003Cbr>CMD [“java”,”-server”,”-Duser.timezone=GMT+08″,”-jar”,”/app.jar”]\u003C/p>\u003Cp># cat docker-entrypoint.sh\u003Cbr>#!/bin/sh\u003Cbr>set -e\u003Cbr>需要做的操作，比如更改文件夹权限，或者其他命令\u003Cbr>exec “$@”\u003C/p>","# cat Dockerfile\nFROM openjdk:8-alpine\nWORKDIR /\nADD ./target/*.jar app.jar\nEXPOSE 9999\nCOPY docker-entrypoint.sh /\nRUN chmod +x /docker-entrypoint.sh\nENTRYPOINT [“/docker-entrypoint.sh”]\nCMD [“java”,”-server”,”-Duser.timezone=GMT+08″,”-jar”,”/app.jar”]\n\n# cat docker-entrypoint.sh\n#!/bin/sh\nset -e\n需要做的操作，比如更改文件夹权限，或者其他命令\nexec “$@”","/article/61",14347,"2018-10-22 13:55:47","2018-10-22 13:56:10",{"id":254,"category_id":44,"title":255,"keywords":256,"description":257,"image_url":6,"content":258,"content_md":259,"url":260,"hits":261,"is_recommend":73,"is_top":73,"create_time":262,"update_time":263},{"id":362,"category_id":44,"title":363,"keywords":364,"description":365,"image_url":6,"content":366,"content_md":367,"url":368,"hits":369,"is_recommend":53,"is_top":73,"create_time":370,"update_time":371},93,"ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台","Filebeat,Kafka","一、说明1.Filebeat是一个日志文件托运工具，在你的服务器上安装客户端后，filebeat会监控日志目录或者指定的日志文件，追踪读取这些文件（追踪文件的变化，不停的读）2.Kafka是一种高吞吐量的分布式发布订阅消息系统，它可以处理消费者规模的网站中的所有动作流数据3.Logstash是一根具备实时数据传输能力的管道，负责将数据信息从管道的输入端传输到管道的输出端；与此同时这根管道还可以让你根据自己的需求在中间加上滤网，Logstash提供里很多功能强大的滤网以满足你的各种应用场景4.El","\u003Cp>\u003C/p>\u003Cp>\u003Cb>一、说明\u003C/b>\u003C/p>\u003Cp>\u003Cspan>1.Filebeat是一个日志文件托运工具，在你的服务器上安装客户端后，filebeat会监控日志目录或者指定的日志文件，追踪读取这些文件（追踪文件的变化，不停的读）\u003C/span>\u003C/p>\u003Cp>\u003Cspan>2.Kafka是一种高吞吐量的分布式发布订阅消息系统，它可以处理消费者规模的网站中的所有动作流数据\u003C/span>\u003C/p>\u003Cp>\u003Cspan>3.Logstash是一根具备实时数据传输能力的管道，负责将数据信息从管道的输入端传输到管道的输出端；与此同时这根管道还可以让你根据自己的需求在中间加上滤网，Logstash提供里很多功能强大的滤网以满足你的各种应用场景\u003C/span>\u003Cbr>\u003Cspan>4.ElasticSearch它提供了一个分布式多用户能力的全文搜索引擎，基于RESTful web接口\u003C/span>\u003Cbr>\u003C/p>\u003Cp>\u003Cspan>5.Kibana是ElasticSearch的用户界面\u003C/span>\u003C/p>\u003Cp>\u003Cspan>6.在实际应用场景下，为了满足大数据实时检索的场景，利用Filebeat去监控日志文件，将Kafka作为Filebeat的输出端，Kafka实时接收到Filebeat后以Logstash作为输出端输出，到Logstash的数据也许还不是我们想要的格式化或者特定业务的数据，这时可以通过Logstash的一些过了插件对数据进行过滤最后达到想要的数据格式以ElasticSearch作为输出端输出，数据到ElasticSearch就可以进行丰富的分布式检索了\u003C/span>\u003C/p>\u003Cp>\u003Cb>二、系统环境\u003C/b>\u003C/p>\u003Cp>软件版本：filebeat6.5 logstash6.5 Centos7&nbsp;&nbsp;yjava-1.8.0-openjdk&nbsp;\u003C/p>\u003Cp>\u003C/p>\u003Cp>\u003C/p>\u003Cp>数据流向：filebeat ---&gt;&gt; kafka---&gt;&gt; logstash\u003C/p>\u003Cp>\u003Cb>三、安装\u003C/b>\u003C/p>\u003Cp>1、Filebeat安装\u003C/p>\u003Cp>[root@test ~]# yum install https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.5.4-x86_64.rpm\u003C/p>\u003Cp>2.Logstash的安装\u003C/p>\u003Cp>[root@test ~]# yum install https://artifacts.elastic.co/downloads/logstash/logstash-6.5.4.rpm\u003C/p>\u003Cp>3.kafka的安装\u003C/p>\u003Cp>[root@localhost ~]#&nbsp; wget https://www.apache.org/dyn/closer.cgi?path=/kafka/2.1.0/kafka_2.12-2.1.0.tgz\u003C/p>\u003Cp>[root@localhost ~]# wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz\u003C/p>\u003Cp>[root@localhost ~]# tar xf zookeeper-3.4.10.tar.gz -C /usr/local/\u003C/p>\u003Cp>[root@localhost ~]# tar xf kafka_2.12-2.1.0.tgz -C /usr/local/\u003C/p>\u003Cp>[root@localhost ~]# mv /usr/local/zookeeper-3.4.10/conf/zoo_sample.cfg /usr/local/zookeeper-3.4.10/conf/zoo.cfg\u003C/p>\u003Cp>[root@localhost ~]# /usr/local/zookeeper-3.4.10/bin/zkServer.sh start\u003C/p>\u003Cp>[root@localhost ~]# vim&nbsp; /usr/local/kafka_2.12-2.1.0/config/server.properties&nbsp;\u003C/p>\u003Cp>broker.id=0\u003C/p>\u003Cp>listeners=PLAINTEXT://192.168.30.160:9092&nbsp; # 默认监听所有地址，这个需要指定一个IP，否则在filebeat那往kafka中发送数据会失败。\u003C/p>\u003Cp>num.network.threads=3\u003C/p>\u003Cp>num.io.threads=8\u003C/p>\u003Cp>socket.send.buffer.bytes=102400\u003C/p>\u003Cp>socket.receive.buffer.bytes=102400\u003C/p>\u003Cp>socket.request.max.bytes=104857600\u003C/p>\u003Cp>log.dirs=/tmp/kafka-logs\u003C/p>\u003Cp>num.partitions=1\u003C/p>\u003Cp>num.recovery.threads.per.data.dir=1\u003C/p>\u003Cp>offsets.topic.replication.factor=1\u003C/p>\u003Cp>transaction.state.log.replication.factor=1\u003C/p>\u003Cp>transaction.state.log.min.isr=1\u003C/p>\u003Cp>log.retention.hours=24\u003C/p>\u003Cp>log.segment.bytes=1073741824\u003C/p>\u003Cp>log.cleaner.enable=true\u003C/p>\u003Cp>log.retention.check.interval.ms=300000\u003C/p>\u003Cp>zookeeper.connect=192.168.30.160:2181\u003C/p>\u003Cp>zookeeper.connection.timeout.ms=600\u003C/p>\u003Cp>group.initial.rebalance.delay.ms=0\u003C/p>\u003Cp>[root@localhost ~]#&nbsp;&nbsp;/usr/local/kafka_2.12-2.1.0/bin/kafka-server-start.sh -daemon /usr/local/kafka_2.12-2.1.0/config/server.properties\u003C/p>\u003Cp>[root@localhost ~]# ss -tunl|grep 9092\u003C/p>\u003Cp>tcp&nbsp; &nbsp; LISTEN&nbsp; &nbsp; &nbsp;0&nbsp; &nbsp; &nbsp; 50&nbsp; &nbsp; &nbsp;::ffff:192.168.30.160:9092&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:::*&nbsp; &nbsp; &nbsp;\u003C/p>\u003Cp>备注：一定得注意filebeat版本所兼容的kafka版本，详细查看：https://www.elastic.co/guide/en/beats/filebeat/current/kafka-output.html#_configuration_options_9\u003C/p>\u003Cp>\u003Cb>四、filebeat配置\u003C/b>\u003C/p>\u003Cp>[root@test ~]# cat /etc/filebeat/filebeat.yml\u003C/p>\u003Cp>filebeat.inputs:\u003C/p>\u003Cp>- type: log\u003C/p>\u003Cp>&nbsp; enabled: true\u003C/p>\u003Cp>&nbsp; paths:\u003C/p>\u003Cp>&nbsp; &nbsp; - /var/log/httpd/access_log\u003C/p>\u003Cp>&nbsp; fields:\u003C/p>\u003Cp>&nbsp; &nbsp; log_topics: httpd\u003C/p>\u003Cp>&nbsp; tags: [\"httpd\"]\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>- type: log\u003C/p>\u003Cp>&nbsp; enabled: true\u003C/p>\u003Cp>&nbsp; paths:\u003C/p>\u003Cp>&nbsp; - /var/log/messages\u003C/p>\u003Cp>&nbsp; fields:\u003C/p>\u003Cp>&nbsp; &nbsp; log_topics: messages\u003C/p>\u003Cp>&nbsp; tags: [\"messages\"]\u003C/p>\u003Cp>&nbsp;&nbsp;include_lines: ['^Dec'] # 匹配需要行\u003C/p>\u003Cp>&nbsp; tail_files: true # 从文件尾开始监控文件新增内容\u003C/p>\u003Cp>processors:\u003C/p>\u003Cp>- drop_fields:&nbsp;&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp;fields: [\"beat\",\"input\",\"source\",\"offset\"] # 过滤不需要的字段\u003C/p>\u003Cp>name api-server # 添加字段，标记主机的日志来源\u003C/p>\u003Cp>output.kafka:\u003C/p>\u003Cp>&nbsp; enabled: true&nbsp;&nbsp;\u003C/p>\u003Cp>&nbsp; codec.format:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 默认json格式\u003C/p>\u003Cp>&nbsp; &nbsp; string: '%{[message]}'&nbsp; &nbsp;# 只输原始日志格式\u003C/p>\u003Cp>&nbsp; hosts: [\"192.168.30.160:9092\"]\u003C/p>\u003Cp>&nbsp; topic: '%{[fields][log_topics]}'\u003C/p>\u003Cp>&nbsp; partition.round_robin: # 集群是否开启kafka的partition分区\u003C/p>\u003Cp>&nbsp; &nbsp; reachable_only: false\u003C/p>\u003Cp>&nbsp; worker: 2\u003C/p>\u003Cp>&nbsp; required_acks: 1\u003C/p>\u003Cp>&nbsp; compression: gzip # 压缩格式\u003C/p>\u003Cp>&nbsp; max_message_bytes: 10000000 # 压缩格式字节大小\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>配置文件测试\u003C/p>\u003Cp>filebeat test config -c filebeat.yml&nbsp;\u003C/p>\u003Cp>[root@test ~]# systemctl start filebeat &amp;&amp; systemctl enable filebeat\u003C/p>\u003Cp>\u003Cb>五、logstash配置文件\u003C/b>\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>[root@test ~]# cat /etc/logstash/conf.d/logstash.conf\u003C/p>\u003Cp>input {\u003C/p>\u003Cp>&nbsp; kafka {\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; bootstrap_servers =&gt; \"192.168.30.160:9092\"\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; topics =&gt; [\"httpd\",\"messages\"]\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; codec =&gt; \"json\"&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; consumer_threads =&gt; 4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 消费进程数\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; enable_auto_commit =&gt; true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 自动提交offset\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; auto_commit_interval_ms =&gt; \"1000\"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# consumer 隔多久提交&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # offsets --消费指针\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; auto_offset_reset =&gt; \"latest\"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# earliest&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 当各分区下有已提交的offset时，从提交的offset开始消费；无提交的offset时，从头开始消费&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # latest&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 当各分区下有已提交的offset时，从提交的offset开始消费；无提交的offset时，消费新产生的该分区下的数据&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # none&nbsp;\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # topic各分区都存在已提交的offset时，从offset后开始消费；只要有一个分区不存在已提交的offset，则抛出异常\u003C/p>\u003Cp>&nbsp; }\u003C/p>\u003Cp>}\u003C/p>\u003Cp>output {\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp;if [tags] == \"httpd\" {\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;elasticsearch {\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hosts =&gt; [\"192.168.30.160:9200\"]\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;index =&gt; \"logstash-httpd-%{+YYYY.MM.dd}\"\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; manage_template =&gt; true\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; }\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp;if [tags] == \"messages\" {\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;elasticsearch {\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hosts =&gt; [\"192.168.30.160:9200\"]\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;index =&gt; \"logstash-messages-%{+YYYY.MM.dd}\"\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; manage_template =&gt; true\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp; &nbsp; }\u003C/p>\u003Cp>&nbsp; &nbsp; &nbsp;}\u003C/p>\u003Cp>}\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>&nbsp; #stdout { codec =&gt; rubydebug }\u003C/p>\u003Cp>&nbsp; #path =&gt; \"/tmp/logstash.log\"\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>}\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>配置文件测试\u003C/p>\u003Cp>/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/logstash.conf -t\u003C/p>\u003Cp>[root@test ~]# systemctl start logstash&nbsp;&amp;&amp; systemctl enable logstash\u003C/p>\u003Cp>\u003Cb>六、kafka常用命令\u003C/b>\u003C/p>\u003Cp>创建kafka topic\u003C/p>\u003Cp>bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic test --partitions 1&nbsp; --replication-factor 1\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>删除kafka-topic\u003C/p>\u003Cp>bin/kafka-topics.sh --zookeeper localhost:2181&nbsp; --delete&nbsp; --topic test\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>查看所有topic列表\u003C/p>\u003Cp>bin/kafka-topics.sh --zookeeper localhost:2181 --list\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>查看指定topic信息\u003C/p>\u003Cp>bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic test\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>控制台向topic生产数据\u003C/p>\u003Cp>bin/kafka-console-producer.sh --broker-list 192.168.30.160:9092 --topic test\u003C/p>\u003Cp>\u003Cbr>\u003C/p>\u003Cp>控制台消费topic的数据\u003C/p>\u003Cp>bin/kafka-console-consumer.sh --bootstrap-server 192.168.30.160:9092 --topic test --from-beginning\u003C/p>\u003Cdiv>\u003Cbr>\u003C/div>","**一、说明**\n\n1.Filebeat是一个日志文件托运工具，在你的服务器上安装客户端后，filebeat会监控日志目录或者指定的日志文件，追踪读取这些文件（追踪文件的变化，不停的读）\n\n2.Kafka是一种高吞吐量的分布式发布订阅消息系统，它可以处理消费者规模的网站中的所有动作流数据\n\n3.Logstash是一根具备实时数据传输能力的管道，负责将数据信息从管道的输入端传输到管道的输出端；与此同时这根管道还可以让你根据自己的需求在中间加上滤网，Logstash提供里很多功能强大的滤网以满足你的各种应用场景\n\n4.ElasticSearch它提供了一个分布式多用户能力的全文搜索引擎，基于RESTful web接口\n\n5.Kibana是ElasticSearch的用户界面\n\n6.在实际应用场景下，为了满足大数据实时检索的场景，利用Filebeat去监控日志文件，将Kafka作为Filebeat的输出端，Kafka实时接收到Filebeat后以Logstash作为输出端输出，到Logstash的数据也许还不是我们想要的格式化或者特定业务的数据，这时可以通过Logstash的一些过了插件对数据进行过滤最后达到想要的数据格式以ElasticSearch作为输出端输出，数据到ElasticSearch就可以进行丰富的分布式检索了\n\n**二、系统环境**\n\n软件版本：filebeat6.5 logstash6.5 Centos7  yjava-1.8.0-openjdk \n\n数据流向：filebeat --->> kafka--->> logstash\n\n**三、安装**\n\n1、Filebeat安装\n\n[root@test ~]# yum install https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.5.4-x86_64.rpm\n\n2.Logstash的安装\n\n[root@test ~]# yum install https://artifacts.elastic.co/downloads/logstash/logstash-6.5.4.rpm\n\n3.kafka的安装\n\n[root@localhost ~]#  wget https://www.apache.org/dyn/closer.cgi?path=/kafka/2.1.0/kafka_2.12-2.1.0.tgz\n\n[root@localhost ~]# wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz\n\n[root@localhost ~]# tar xf zookeeper-3.4.10.tar.gz -C /usr/local/\n\n[root@localhost ~]# tar xf kafka_2.12-2.1.0.tgz -C /usr/local/\n\n[root@localhost ~]# mv /usr/local/zookeeper-3.4.10/conf/zoo_sample.cfg /usr/local/zookeeper-3.4.10/conf/zoo.cfg\n\n[root@localhost ~]# /usr/local/zookeeper-3.4.10/bin/zkServer.sh start\n\n[root@localhost ~]# vim  /usr/local/kafka_2.12-2.1.0/config/server.properties \n\nbroker.id=0\n\nlisteners=PLAINTEXT://192.168.30.160:9092  # 默认监听所有地址，这个需要指定一个IP，否则在filebeat那往kafka中发送数据会失败。\n\nnum.network.threads=3\n\nnum.io.threads=8\n\nsocket.send.buffer.bytes=102400\n\nsocket.receive.buffer.bytes=102400\n\nsocket.request.max.bytes=104857600\n\nlog.dirs=/tmp/kafka-logs\n\nnum.partitions=1\n\nnum.recovery.threads.per.data.dir=1\n\noffsets.topic.replication.factor=1\n\ntransaction.state.log.replication.factor=1\n\ntransaction.state.log.min.isr=1\n\nlog.retention.hours=24\n\nlog.segment.bytes=1073741824\n\nlog.cleaner.enable=true\n\nlog.retention.check.interval.ms=300000\n\nzookeeper.connect=192.168.30.160:2181\n\nzookeeper.connection.timeout.ms=600\n\ngroup.initial.rebalance.delay.ms=0\n\n[root@localhost ~]#  /usr/local/kafka_2.12-2.1.0/bin/kafka-server-start.sh -daemon /usr/local/kafka_2.12-2.1.0/config/server.properties\n\n[root@localhost ~]# ss -tunl|grep 9092\n\ntcp    LISTEN     0      50     ::ffff:192.168.30.160:9092                 :::*     \n\n备注：一定得注意filebeat版本所兼容的kafka版本，详细查看：https://www.elastic.co/guide/en/beats/filebeat/current/kafka-output.html#_configuration_options_9\n\n**四、filebeat配置**\n\n[root@test ~]# cat /etc/filebeat/filebeat.yml\n\nfilebeat.inputs:\n\n- type: log\n\n  enabled: true\n\n  paths:\n\n    - /var/log/httpd/access_log\n\n  fields:\n\n    log_topics: httpd\n\n  tags: [\"httpd\"]\n\n- type: log\n\n  enabled: true\n\n  paths:\n\n  - /var/log/messages\n\n  fields:\n\n    log_topics: messages\n\n  tags: [\"messages\"]\n\n  include_lines: ['^Dec'] # 匹配需要行\n\n  tail_files: true # 从文件尾开始监控文件新增内容\n\nprocessors:\n\n- drop_fields:  \n\n     fields: [\"beat\",\"input\",\"source\",\"offset\"] # 过滤不需要的字段\n\nname api-server # 添加字段，标记主机的日志来源\n\noutput.kafka:\n\n  enabled: true  \n\n  codec.format:                # 默认json格式\n\n    string: '%{[message]}'   # 只输原始日志格式\n\n  hosts: [\"192.168.30.160:9092\"]\n\n  topic: '%{[fields][log_topics]}'\n\n  partition.round_robin: # 集群是否开启kafka的partition分区\n\n    reachable_only: false\n\n  worker: 2\n\n  required_acks: 1\n\n  compression: gzip # 压缩格式\n\n  max_message_bytes: 10000000 # 压缩格式字节大小\n\n配置文件测试\n\nfilebeat test config -c filebeat.yml \n\n[root@test ~]# systemctl start filebeat && systemctl enable filebeat\n\n**五、logstash配置文件**\n\n[root@test ~]# cat /etc/logstash/conf.d/logstash.conf\n\ninput {\n\n  kafka {\n\n        bootstrap_servers => \"192.168.30.160:9092\"\n\n        topics => [\"httpd\",\"messages\"]\n\n        codec => \"json\" \n\n        consumer_threads => 4                                   # 消费进程数\n\n        enable_auto_commit => true                              # 自动提交offset\n\n        auto_commit_interval_ms => \"1000\"                       # consumer 隔多久提交 \n\n                                                                # offsets --消费指针\n\n        auto_offset_reset => \"latest\"                           # earliest \n\n                                                                # 当各分区下有已提交的offset时，从提交的offset开始消费；无提交的offset时，从头开始消费 \n\n                                                                # latest \n\n                                                                # 当各分区下有已提交的offset时，从提交的offset开始消费；无提交的offset时，消费新产生的该分区下的数据 \n\n                                                                # none \n\n                                                                # topic各分区都存在已提交的offset时，从offset后开始消费；只要有一个分区不存在已提交的offset，则抛出异常\n\n  }\n\n}\n\noutput {\n\n     if [tags] == \"httpd\" {\n\n         elasticsearch {\n\n         hosts => [\"192.168.30.160:9200\"]\n\n         index => \"logstash-httpd-%{+YYYY.MM.dd}\"\n\n              manage_template => true\n\n         }\n\n      }\n\n     if [tags] == \"messages\" {\n\n         elasticsearch {\n\n         hosts => [\"192.168.30.160:9200\"]\n\n         index => \"logstash-messages-%{+YYYY.MM.dd}\"\n\n              manage_template => true\n\n        }\n\n     }\n\n}\n\n  #stdout { codec => rubydebug }\n\n  #path => \"/tmp/logstash.log\"\n\n}\n\n配置文件测试\n\n/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/logstash.conf -t\n\n[root@test ~]# systemctl start logstash && systemctl enable logstash\n\n**六、kafka常用命令**\n\n创建kafka topic\n\nbin/kafka-topics.sh --zookeeper localhost:2181 --create --topic test --partitions 1  --replication-factor 1\n\n删除kafka-topic\n\nbin/kafka-topics.sh --zookeeper localhost:2181  --delete  --topic test\n\n查看所有topic列表\n\nbin/kafka-topics.sh --zookeeper localhost:2181 --list\n\n查看指定topic信息\n\nbin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic test\n\n控制台向topic生产数据\n\nbin/kafka-console-producer.sh --broker-list 192.168.30.160:9092 --topic test\n\n控制台消费topic的数据\n\nbin/kafka-console-consumer.sh --bootstrap-server 192.168.30.160:9092 --topic test --from-beginning","/article/93",12190,"2018-12-24 16:40:08","2018-12-26 11:53:38",{"id":373,"category_id":46,"title":374,"keywords":375,"description":376,"image_url":6,"content":377,"content_md":378,"url":379,"hits":380,"is_recommend":53,"is_top":73,"create_time":381,"update_time":382},81,"kubernetes 1.12.1 高可用安装之部署Dashboard","安装Dashboard","创建Dashboard需要CoreDNS部署成功之后再安装Dashboard。[root@master01 ~]# wget https://zhl123.com/download/k8s/Dashboard.tgz[root@master01 ~]# tar xf Dashboard.tgz[root@master01 ~]# kubectl create -f Dashboard/[root@master01 Dashboard]# kubectl get svc -n kube-syste","\u003Ch2>创建Dashboard\u003C/h2>\u003Cp>需要CoreDNS部署成功之后再安装Dashboard。\u003C/p>\u003Cpre>\u003Cp>\u003C/p>\u003Cp>\u003Cfont face=\"monospace\">[root@master01 ~]# wget https://zhl123.com/download/k8s/dashboard.tgz\n[root@master01 ~]# tar xf dashboard.tgz \n[root@master01 ~]# kubectl create -f dashboard/\n[root@master01 ~]# kubectl cluster-info\u003C/font>\u003C/p>\u003Cfont face=\"monospace\">Kubernetes master is running at https://10.80.4.200:6443\nCoreDNS is running at https://10.80.4.200:6443/api/v1/namespaces/kube-system/services/coredns:dns/proxy\nkubernetes-dashboard is running at https://10.80.4.200:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy\n\nTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.\u003C/font>\u003Cp>\u003C/p>\u003Ccode>\n\u003C/code>\u003C/pre>\u003Cp>\u003Cb>访问Dashboard\u003C/b>\u003C/p>\u003Cp>\u003Cspan>https://10.80.4.200:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy\u003C/span>\u003C/p>\u003Cp>用户名:admin 密码：admin 选择Token令牌模式登录。\u003C/p>\u003Cp>\u003Cb>获取Token\u003C/b>\u003C/p>\u003Cp>\u003Ccode>[root@master01 ~]# kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')\u003C/code>\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20181026/6ff5bcbe473c509f6501b161611cf6dd.png\" alt=\"26-1.png\">\u003Cbr>\u003C/p>\u003Cp>\u003Cimg src=\"/uploads/layedit/20181026/450b4fe0d6e6702d2bb505cf47decfab.png\" alt=\"26-2.png\">\u003Cbr>\u003C/p>","## 创建Dashboard\n\n需要CoreDNS部署成功之后再安装Dashboard。\n\n```\n[root@master01 ~]# wget https://zhl123.com/download/k8s/dashboard.tgz\n[root@master01 ~]# tar xf dashboard.tgz\n[root@master01 ~]# kubectl create -f dashboard/\n[root@master01 ~]# kubectl cluster-infoKubernetes master is running at https://10.80.4.200:6443\nCoreDNS is running at https://10.80.4.200:6443/api/v1/namespaces/kube-system/services/coredns:dns/proxy\nkubernetes-dashboard is running at https://10.80.4.200:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy\n\nTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.\n```\n\n**访问Dashboard**\n\nhttps://10.80.4.200:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy\n\n用户名:admin 密码：admin 选择Token令牌模式登录。\n\n**获取Token**\n\n`[root@master01 ~]# kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')`\n\n![26-1.png](/uploads/layedit/20181026/6ff5bcbe473c509f6501b161611cf6dd.png)\n\n![26-2.png](/uploads/layedit/20181026/450b4fe0d6e6702d2bb505cf47decfab.png)","/article/81",12037,"2018-10-26 09:54:41","2018-10-26 16:59:19",{"id":384,"category_id":44,"title":385,"keywords":6,"description":386,"image_url":6,"content":387,"content_md":388,"url":389,"hits":390,"is_recommend":73,"is_top":73,"create_time":391,"update_time":392},100,"用 Nginx 给 Cookie 增加 Secure 和 HttpOnly","在 nginx 的 location 中配置12# 只支持 proxy 模式下设置，SameSite 不需要可删除，如果想更安全可以把 SameSite 设置为 Strictproxy_cookie_path / \"/; httponly; secure; SameSite=Lax\";示例1234567891011121314151617181920212223242526server {    listen 443 ssl http2;    server_name www.zhl123.cn","\u003Cp style=\"text-align: justify;\">在 nginx 的 location 中配置\u003C/p>\u003Cp style=\"text-align: justify;\"># 只支持 proxy 模式下设置，SameSite 不需要可删除，如果想更安全可以把 SameSite 设置为 Strict\u003C/p>\u003Cp style=\"text-align: justify;\">proxy_cookie_path / \"/; httponly; secure; SameSite=Lax\";\u003C/p>\u003Cp style=\"text-align: justify;\">示例\u003C/p>\u003Cp style=\"text-align: justify;\">server {\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; listen 443 ssl http2;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; server_name www.zhl123.cn;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; ssl_certificate /etc/letsencrypt/live/zhl123.cn/fullchain.pem;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; ssl_certificate_key /etc/letsencrypt/live/zhl123.cn/privkey.pem;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; ssl_trusted_certificate /etc/letsencrypt/live/zhl123.cn/chain.pem;\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; add_header X-XSS-Protection \"1; mode=block\";\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; add_header X-Frame-Options SAMEORIGIN;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; add_header Strict-Transport-Security \"max-age=15768000\";\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; location / {\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; &nbsp; &nbsp; root /var/www/html;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; }\u003C/p>\u003Cp style=\"text-align: justify;\">\u003Cbr>\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; location /123 {\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass http://localhost:8080;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header Host $host;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header X-Real-IP $remote_addr;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; &nbsp; &nbsp; # 在这里设置\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; &nbsp; &nbsp; proxy_cookie_path / \"/; httponly; secure; SameSite=Lax\";\u003C/p>\u003Cp style=\"text-align: justify;\">&nbsp; &nbsp; }\u003C/p>\u003Cp style=\"text-align: justify;\">}\u003C/p>\u003Cfigure class=\"highlight nginx\" style=\"text-align: justify;\">\u003C/figure>","在 nginx 的 location 中配置\n\n# 只支持 proxy 模式下设置，SameSite 不需要可删除，如果想更安全可以把 SameSite 设置为 Strict\n\nproxy_cookie_path / \"/; httponly; secure; SameSite=Lax\";\n\n示例\n\nserver {\n\n    listen 443 ssl http2;\n\n    server_name www.zhl123.cn;\n\n    ssl_certificate /etc/letsencrypt/live/zhl123.cn/fullchain.pem;\n\n    ssl_certificate_key /etc/letsencrypt/live/zhl123.cn/privkey.pem;\n\n    ssl_trusted_certificate /etc/letsencrypt/live/zhl123.cn/chain.pem;\n\n    add_header X-XSS-Protection \"1; mode=block\";\n\n    add_header X-Frame-Options SAMEORIGIN;\n\n    add_header Strict-Transport-Security \"max-age=15768000\";\n\n    location / {\n\n        root /var/www/html;\n\n    }\n\n    location /123 {\n\n        proxy_pass http://localhost:8080;\n\n        proxy_set_header Host $host;\n\n        proxy_set_header X-Real-IP $remote_addr;\n\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\n        # 在这里设置\n\n        proxy_cookie_path / \"/; httponly; secure; SameSite=Lax\";\n\n    }\n\n}","/article/100",11848,"2019-11-26 16:10:57","2019-11-26 16:23:45",{"id":394,"category_id":44,"title":395,"keywords":396,"description":397,"image_url":6,"content":398,"content_md":399,"url":400,"hits":401,"is_recommend":73,"is_top":73,"create_time":402,"update_time":403},41,"Tomcat 安全配置与性能优化","tomcat，性能优化","1. JVM&nbsp;1.1. 使用 Server JRE 替代JDK。&nbsp;服务器上不要安装JDK，请使用 Server JRE. 服务器上根本不需要编译器，代码应该在Release服务器上完成编译打包工作。&nbsp;理由：一旦服务器被控制，可以防止在其服务器上编译其他恶意代码并植入到你的程序中。&nbsp;1.2. JAVA_OPTS&nbsp;export JAVA_OPTS=\"-server -Xms512m -Xmx4096m &nbsp;-XX:PermSize=64M -","\u003Cp>\u003Cfont size=\"5\">\u003Cb>1. JVM\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"5\">\u003Cb>\u003Cfont size=\"4\">1.1. 使用 Server JRE 替代JDK。\u003C/font>\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>服务器上不要安装JDK，请使用 Server JRE. 服务器上根本不需要编译器，代码应该在Release服务器上完成编译打包工作。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>理由：一旦服务器被控制，可以防止在其服务器上编译其他恶意代码并植入到你的程序中。&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>1.2. JAVA_OPTS\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>export JAVA_OPTS=\"-server -Xms512m -Xmx4096m &nbsp;-XX:PermSize=64M -XX:MaxPermSize=512m\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>-Xms 指定初始化时化的栈内存&nbsp;\u003C/span>\u003Cbr>\u003Cspan>-Xmx 指定最大栈内存&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>提示\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>Java 8 以后 -XX:PermSize 与 -XX:MaxPermSize 两个配置项被废弃&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"5\">\u003Cb>2. Tomcat 优化\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>2.1. maxThreads 连接数限制\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>maxThreads 是 Tomcat 所能接受最大连接数。一般设置不要超过8000以上，如果你的网站访问量非常大可能使用运行多个Tomcat实例的方法。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>即，在一个服务器上启动多个tomcat然后做负载均衡处理。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&lt;Connector port=\"8080\" address=\"localhost\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;maxThreads=\"2048\" maxHttpHeaderSize=\"8192\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;emptySessionPath=\"true\" protocol=\"HTTP/1.1\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;enableLookups=\"false\" redirectPort=\"8181\" acceptCount=\"100\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;connectionTimeout=\"20000\" disableUploadTimeout=\"true\" /&gt;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>提示\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>很多做过php运维的朋友在这里会犯一个大错误，php优化服务器通常怎做法是安装cpu以及内存的情况配置连接数，连接数过万都很正常，但java不同jvm配置要非常小心，稍有差错就会崩溃。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>maxThreads 配置要结合 JVM -Xmx 参数调整，也就是要考虑内存开销。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>maxThreads &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;客户请求最大线程数&nbsp;\u003C/span>\u003Cbr>\u003Cspan>minSpareThreads &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;初始化时创建的 socket 线程数&nbsp;\u003C/span>\u003Cbr>\u003Cspan>maxSpareThreads &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 连接器的最大空闲 socket 线程数&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>2.2. 虚拟主机\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>不要使用Tomcat的虚拟主机，每个站点一个实例。即，启动多个tomcat.&nbsp;\u003C/span>\u003Cbr>\u003Cspan>这也是PHP运维在这里常犯的错误，PHP的做法是一个Web下面放置多个虚拟主机，而不是每个主机启动一个web服务器。Tomcat 是多线程,共享内存，任何一个虚拟主机中的应用出现崩溃，会影响到所有应用程序。采用多个实例方式虽然开销比较大，但保证了应用程序隔离与安全。&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>2.3. 压错传输\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>通常所说的gzip压缩，Tomcat通过在server.xml配置设置压缩的选项。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&lt;Connector port=\"8080\" protocol=\"HTTP/1.1\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connectionTimeout=\"20000\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; redirectPort=\"8443\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compression=\"on\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compressionMinSize1=\"2048\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; noCompressionUserAgents=\"gozilla, traviata\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compressableMimeType=\"text/html,text/xml,text/javascript,text/css,text/plain,,application/octet-stream\"/&gt;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>提示\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>压缩会增加Tomcat负担，最好采用Nginx + Tomcat 或者 Apache + Tomcat 方式，压缩交由Nginx/Apache 去做。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>compression &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 打开压缩功能 &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>compressionMinSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 启用压缩的输出内容大小，这里面默认为2KB&nbsp;\u003C/span>\u003Cbr>\u003Cspan>compressableMimeType &nbsp; &nbsp; &nbsp; &nbsp; 压缩类型 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cfont size=\"5\">\u003Cb>3. Tomcat 安全配置\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>3.1. 禁用8005端口\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>telnet localhost 8005 然后输入 SHUTDOWN 就可以关闭 Tomcat，为了安全我们要禁用该功能&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&lt;Server port=\"-1\" shutdown=\"SHUTDOWN\"&gt;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>3.2. 安装后初始化配置\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>当Tomcat完成安装后你首先要做的事情如下：&nbsp;\u003C/span>\u003Cbr>\u003Cspan>首次安装完成后立即删除webapps下面的所有代码&nbsp;\u003C/span>\u003Cbr>\u003Cspan>rm -rf /srv/apache-tomcat/webapps/*&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>注释或删除 tomcat-users.xml 所有用户权限，看上去如下：&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan># cat conf/tomcat-users.xml&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&lt;?xml version='1.0' encoding='utf-8'?&gt;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&lt;tomcat-users&gt;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&lt;/tomcat-users&gt;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cfont size=\"3\">\u003Cb>3.2.1. 隐藏版本信息\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>隐藏Tomcat版本信息，首先隐藏HTTP头中的版本信息&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>vim $CATALINA_HOME/conf/server.xml&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp;&lt;Connector port=\"80\" protocol=\"HTTP/1.1\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connectionTimeout=\"20000\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; redirectPort=\"8443\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;maxThreads=\"8192\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;minSpareThreads=\"64\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;maxSpareThreads=\"128\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;acceptCount=\"128\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;enableLookups=\"false\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;server=\"Neo App Srv 1.0\"/&gt;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan># curl -I&nbsp;\u003C/span>\u003Ca href=\"http://localhost:8080/\" target=\"_blank\">http://localhost:8080/\u003C/a>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cspan>HTTP/1.1 400 Bad Request&nbsp;\u003C/span>\u003Cbr>\u003Cspan>Transfer-Encoding: chunked&nbsp;\u003C/span>\u003Cbr>\u003Cspan>Date: Thu, 20 Oct 2011 09:51:55 GMT&nbsp;\u003C/span>\u003Cbr>\u003Cspan>Connection: close&nbsp;\u003C/span>\u003Cbr>\u003Cspan>Server: Neo App Srv 1.0&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>服务器信息已经被改为 Server: Neo App Srv 1.0&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>注意：当出现 404 页面时仍可能看到Tomcat的版本信息\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>HTTP Status 404 - /sdf&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>type Status report&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>message /sdf&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>description The requested resource is not available.&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>Apache Tomcat/8.0.32 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>隐藏Tomcat 404页面版本信息的方法如下&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>mkdir -p apache-tomcat-8.0.33/lib/org/apache/catalina/util&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>cat &gt;&gt; apache-tomcat-8.0.33/lib/org/apache/catalina/util/ServerInfo.properties &lt;&lt;EOF&nbsp;\u003C/span>\u003Cbr>\u003Cspan>server.info=Apache&nbsp;\u003C/span>\u003Cbr>\u003Cspan>server.number=&nbsp;\u003C/span>\u003Cbr>\u003Cspan>server.built=&nbsp;\u003C/span>\u003Cbr>\u003Cspan>EOF&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>测试&nbsp;\u003C/span>\u003Cbr>\u003Cspan>HTTP Status 404 - /sdf&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>type Status report&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>message /sdf&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>description The requested resource is not available.&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>Apache&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cfont size=\"3\">\u003Cb>3.2.2. 应用程序安全\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>关闭war自动部署 unpackWARs=\"false\" autoDeploy=\"false\"。防止被植入木马等恶意程序&nbsp;\u003C/span>\u003Cbr>\u003Cspan>关闭 reloadable=\"false\" 也用于防止被植入木马&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cfont size=\"3\">\u003Cb>3.2.3. JSESSIONID\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>修改 Cookie 变量 JSESSIONID， 这个cookie 是用于维持Session关系。建议你改为PHPSESSID。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&lt;Context path=\"\" docBase=\"path/to/your\" reloadable=\"false\" sessionCookiePath=\"/\" sessionCookieName=\"PHPSESSID\"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cfont size=\"4\">\u003Cb>3.3. 启动用户与端口\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>不要使用root用户启动tomcat，Java程序与C程序不同。nginx,httpd 使用root用户启动守护80端口，子进程/线程会通过setuid(),setgid()两个函数切换到普通用户。即父进程所有者是root用户，子进程与多线程所有者是一个非root用户，这个用户没有shell，无法通过ssh与控制台登陆系统，Java 的JVM 是与系统无关的，是建立在OS之上的，你使用什么用户启动Tomcat，那麽Tomcat 就会继承该所有者的权限。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>这造成了一个问题，Linux系统小于1024的端口只有root可以使用，这也是为什么Tomcat默认端口是8080。如果你想使用80端口只能使用root启动Tomcat。这有带来了很多安全问题。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>解决方案是创建一个普通用户，如：&nbsp;\u003C/span>\u003Cbr>\u003Cspan>groupadd -g 80 daemon&nbsp;\u003C/span>\u003Cbr>\u003Cspan>adduser -o --home /daemon --shell /sbin/nologin --uid 80 --gid 80 -c \"Web Server\" daemon&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>注意 /sbin/nologin , 意味着该用户不能登录，同时我也没有给它指定密码，这个用户只能用于启动tomcat，没有Shell权限就以为只被注入后无法运行linux命令。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>chown daemon:daemon -R /srv/*&nbsp;\u003C/span>\u003Cbr>\u003Cspan>su - daemon -c \"/srv/apache-tomcat/bin/startup.sh\"&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>接下来解决80端口问题, 思路就是80去调用8080，或者映射端口。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>下面是影射方案,80 跳转 8080&nbsp;\u003C/span>\u003Cbr>\u003Cspan>iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>取消跳转&nbsp;\u003C/span>\u003Cbr>\u003Cspan>iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>查看规则&nbsp;\u003C/span>\u003Cbr>\u003Cspan>iptables -t nat -L&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>另一个就是从80请求去调用8080的方案&nbsp;\u003C/span>\u003Cbr>\u003Cspan>这个方案可以在 Tomcat 前段增加反向代理，例如：Nginx,Apache,Squid,Varnish或者F5， Array这类设备等等&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cfont size=\"5\">\u003Cb>4. 如何部署应用程序\u003C/b>\u003C/font>\u003Cspan>&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cbr>\u003Cspan>应用程序部署与tomcat启动,不能使用同一个用户。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>我的tomcat 安装在 /srv目录下，Tomcat启动用户为daemon; 应用程序放在/www目录下www所有者是www用户。这样的目的是一旦tomcat被植入web shell程序，它将不能创建或编辑/www目录下面的任何内容。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>adduser --home /www -c \"Web Application\" www&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>我的Tomcat安装在/srv目录下，但应用程序放在/www目录下，一般是这样的结构。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>/www/example.com/www.example.com&nbsp;\u003C/span>\u003Cbr>\u003Cspan>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u003C/span>\u003Cbr>\u003Cbr>\u003Cspan>每次升级将压错包解压到 /www/example.com/目录下，\u003C/span>\u003Ca href=\"http://www.example.com/\" target=\"_blank\">www.example.com\u003C/a>\u003Cspan>&nbsp;是符号连接，连接到刚刚解压的目录。&nbsp;\u003C/span>\u003Cbr>\u003Cspan>这个可以实现通过符号连接在多个版本之间快速切换。\u003C/span>\u003C/p>","**1. JVM**\n\n \n\n**\n1.1. 使用 Server JRE 替代JDK。\n**\n\n \n\n服务器上不要安装JDK，请使用 Server JRE. 服务器上根本不需要编译器，代码应该在Release服务器上完成编译打包工作。 \n\n理由：一旦服务器被控制，可以防止在其服务器上编译其他恶意代码并植入到你的程序中。 \n\n**1.2. JAVA_OPTS**\n\n \n\nexport JAVA_OPTS=\"-server -Xms512m -Xmx4096m  -XX:PermSize=64M -XX:MaxPermSize=512m\" \n\n                         \n\n-Xms 指定初始化时化的栈内存 \n\n-Xmx 指定最大栈内存 \n\n**提示**\n\n \n\nJava 8 以后 -XX:PermSize 与 -XX:MaxPermSize 两个配置项被废弃 \n\n**2. Tomcat 优化**\n\n \n\n**2.1. maxThreads 连接数限制**\n\n \n\nmaxThreads 是 Tomcat 所能接受最大连接数。一般设置不要超过8000以上，如果你的网站访问量非常大可能使用运行多个Tomcat实例的方法。 \n\n即，在一个服务器上启动多个tomcat然后做负载均衡处理。 \n\n                         \n\n \n\n                                           \n\n**提示**\n\n \n\n很多做过php运维的朋友在这里会犯一个大错误，php优化服务器通常怎做法是安装cpu以及内存的情况配置连接数，连接数过万都很正常，但java不同jvm配置要非常小心，稍有差错就会崩溃。 \n\nmaxThreads 配置要结合 JVM -Xmx 参数调整，也就是要考虑内存开销。 \n\nmaxThreads                  客户请求最大线程数 \n\nminSpareThreads            初始化时创建的 socket 线程数 \n\nmaxSpareThreads           连接器的最大空闲 socket 线程数 \n\n                         \n\n**2.2. 虚拟主机**\n\n \n\n不要使用Tomcat的虚拟主机，每个站点一个实例。即，启动多个tomcat. \n\n这也是PHP运维在这里常犯的错误，PHP的做法是一个Web下面放置多个虚拟主机，而不是每个主机启动一个web服务器。Tomcat 是多线程,共享内存，任何一个虚拟主机中的应用出现崩溃，会影响到所有应用程序。采用多个实例方式虽然开销比较大，但保证了应用程序隔离与安全。 \n\n**2.3. 压错传输**\n\n \n\n通常所说的gzip压缩，Tomcat通过在server.xml配置设置压缩的选项。 \n\n                         \n\n \n\n                         \n\n                         \n\n**提示**\n\n \n\n压缩会增加Tomcat负担，最好采用Nginx + Tomcat 或者 Apache + Tomcat 方式，压缩交由Nginx/Apache 去做。 \n\ncompression                         打开压缩功能   \n\ncompressionMinSize           启用压缩的输出内容大小，这里面默认为2KB \n\ncompressableMimeType         压缩类型                         \n\n                         \n\n**3. Tomcat 安全配置**\n\n \n\n**3.1. 禁用8005端口**\n\n \n\ntelnet localhost 8005 然后输入 SHUTDOWN 就可以关闭 Tomcat，为了安全我们要禁用该功能 \n\n                         \n\n \n\n                         \n\n                         \n\n**3.2. 安装后初始化配置**\n\n \n\n当Tomcat完成安装后你首先要做的事情如下： \n\n首次安装完成后立即删除webapps下面的所有代码 \n\nrm -rf /srv/apache-tomcat/webapps/* \n\n                         \n\n注释或删除 tomcat-users.xml 所有用户权限，看上去如下： \n\n                         \n\n# cat conf/tomcat-users.xml \n\n \n\n \n\n \n\n                         \n\n                         \n\n**3.2.1. 隐藏版本信息**\n\n \n\n隐藏Tomcat版本信息，首先隐藏HTTP头中的版本信息 \n\n                                 \n\nvim $CATALINA_HOME/conf/server.xml \n\n     \n\n# curl -I \n[http://localhost:8080/](http://localhost:8080/)\n \n\nHTTP/1.1 400 Bad Request \n\nTransfer-Encoding: chunked \n\nDate: Thu, 20 Oct 2011 09:51:55 GMT \n\nConnection: close \n\nServer: Neo App Srv 1.0 \n\n                                 \n\n                                 \n\n服务器信息已经被改为 Server: Neo App Srv 1.0 \n\n**注意：当出现 404 页面时仍可能看到Tomcat的版本信息**\n\n \n\nHTTP Status 404 - /sdf \n\ntype Status report \n\nmessage /sdf \n\ndescription The requested resource is not available. \n\nApache Tomcat/8.0.32                                         \n\n                                         \n\n隐藏Tomcat 404页面版本信息的方法如下 \n\n                                         \n\nmkdir -p apache-tomcat-8.0.33/lib/org/apache/catalina/util \n\ncat >> apache-tomcat-8.0.33/lib/org/apache/catalina/util/ServerInfo.properties","/article/41",11623,"2016-09-01 17:06:36","2018-10-18 17:06:58",[405,406,407,408,409,410,411,412,413,414],{"id":150,"category_id":44,"title":151,"keywords":6,"description":152,"image_url":6,"content":153,"content_md":154,"url":155,"hits":156,"is_recommend":73,"is_top":73,"create_time":157,"update_time":158},{"id":160,"category_id":46,"title":161,"keywords":6,"description":162,"image_url":6,"content":163,"content_md":164,"url":165,"hits":166,"is_recommend":73,"is_top":73,"create_time":167,"update_time":168},{"id":170,"category_id":44,"title":171,"keywords":6,"description":172,"image_url":6,"content":173,"content_md":174,"url":175,"hits":176,"is_recommend":73,"is_top":73,"create_time":177,"update_time":178},{"id":180,"category_id":44,"title":181,"keywords":6,"description":182,"image_url":6,"content":183,"content_md":184,"url":185,"hits":186,"is_recommend":73,"is_top":73,"create_time":187,"update_time":188},{"id":190,"category_id":44,"title":191,"keywords":6,"description":192,"image_url":6,"content":193,"content_md":194,"url":195,"hits":196,"is_recommend":73,"is_top":73,"create_time":197,"update_time":198},{"id":200,"category_id":44,"title":201,"keywords":6,"description":202,"image_url":6,"content":203,"content_md":204,"url":205,"hits":206,"is_recommend":73,"is_top":73,"create_time":207,"update_time":208},{"id":210,"category_id":44,"title":211,"keywords":212,"description":213,"image_url":6,"content":214,"content_md":215,"url":216,"hits":217,"is_recommend":73,"is_top":73,"create_time":218,"update_time":219},{"id":221,"category_id":44,"title":222,"keywords":223,"description":224,"image_url":6,"content":225,"content_md":226,"url":227,"hits":228,"is_recommend":73,"is_top":73,"create_time":229,"update_time":230},{"id":232,"category_id":44,"title":233,"keywords":234,"description":235,"image_url":6,"content":236,"content_md":237,"url":238,"hits":239,"is_recommend":73,"is_top":73,"create_time":240,"update_time":241},{"id":243,"category_id":44,"title":244,"keywords":245,"description":246,"image_url":6,"content":247,"content_md":248,"url":249,"hits":250,"is_recommend":73,"is_top":73,"create_time":251,"update_time":252},1783340869404]