1 bio

1.1 baota

01.BaoTa
    a.安装
        官方版
        wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
        wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh
        -----------------------------------------------------------------------------------------------------
        纯净版
        yum install -y wget && wget -O install.sh http://v7.hostcli.com/install/install_6.0.sh && sh install.sh
    b.登录
        外网面板地址: http://101.200.59.179:9999/4e55fa31
        内网面板地址: http://192.168.2.128:8888/4033665/  或 http://192.168.2.138:8888/01c62172
        username: myslayers
        password: 4033665X
    c.绑定
        宝塔账号:15135890769
        宝塔密码:4033665X
    d.远程
        ssh [email protected]
        XXXXXXX
    e.设置
        bt                                                                  --超级面板
        /etc/init.d/bt default                                              --查看面板入口
        rm -f /www/server/panel/data/admin_path.pl                          --关闭安全入口
    f.卸载
        wget http://download.bt.cn/install/bt-uninstall.sh
        sh bt-uninstall.sh

02.BaoTa
    a.位置
        网站:/www/wwwroot/192.168.2.128
        -----------------------------------------------------------------------------------------------------
        mongodb:/www/server/mongodb
        mysql:/www/server/mysql
        nginx:/www/server/nginx
        nvm:/www/server/nvm
        php:/www/server/php
        phpmyadmin:/www/server/phpmyadmin
        pure-ftpd:/www/server/pure-ftpd
        redis:/www/server/redis
        tomcat9:/www/server/tomcat9
        jdk:/usr/java/jdk1.8.0_121/
        -----------------------------------------------------------------------------------------------------
        jdk:/data/jdk1.8.0_202/
        maven:/data/apache-maven-3.6.3/
        tomcat:/data/apache-tomcat-9.0.78/
        node:/data/node-v16.20.1-linux-x64/
    b.安全
        SSH          22
        FTP          20
        nginx        80
        mysql        3306
        redis        6379         bind 0.0.0.0
        tomcat       8080
        mongodb      27017
        phpMyAdmin   888
        全部放开     22-9999
        -----------------------------------------------------------------------------------------------------
        bt           8888
        Portainer    9000
    c.网站
        略

1.2 panel

01.常用配置
    a.软件
        Jellyfin                                                                    --多媒体
        Navidrome                                                                   --音乐服务器
        Bitwarden                                                                   --密码管理服务
        Mailserver                                                                  --邮件服务器
        YesPlayMusic                                                                --网易云
        HomeAssistant                                                               --开源家庭自动化
        -----------------------------------------------------------------------------------------------------
        思源笔记                                                                     --自建
        Lsky-pro                                                                    --图床
        Easylmage                                                                   --图床
        ObsidianLiveSync                                                            --Obsidian在线同步插件
    b.网络
        frps                                                                   【√】--服务端
        frpc                                                                        --客户端
        ddns-go                                                                【√】--DNS动态域名解析,自动获得你的公网IPv4或IPv6地址,并解析到对应的域名服务
        RustDesk                                                                    --远程桌面软件
        DomainAdmin                                                                 --域名SSL证书监测平台
        cloudflared                                                                 --CloudflareTunnel客户端
        -----------------------------------------------------------------------------------------------------
        AList                                                                       --私人网盘
        SFTPGo                                                                      --SFTP服务器
        Seafile                                                                     --支持WebDAV,支持COS存储桶
        Cloudreve                                                                   --支持多家云存储的云盘系统
        nextcloud                                                                   --支持WebDAV,支持S3对象存储,或兼容S3实现如minio、腾讯cos
    c.数据库
        mysql                                                                  【√】--数据库
        redis                                                                  【√】--数据库
        mongodb                                                                【√】--数据库
        postgresql                                                             【√】--数据库
        -----------------------------------------------------------------------------------------------------
        phpMyAdmin                                                                  --MySQL和MariaDB的Web界面
        CloudBeaver                                                                 --云数据库管理器
        mongo-express                                                               --MongoDB管理界面
        Redpanda Console                                                            --KafkaWeb管理工具
        Redis-Commander                                                             --Redis Web管理工具
        -----------------------------------------------------------------------------------------------------
        RabbitMQ                                                                    --中间件
        Kafka                                                                       --中间件
        -----------------------------------------------------------------------------------------------------
        DataEase                                                                    --数据可视化分析工具
    d.Web服务器
        Go                                                                          --web环境
        Java                                                                        --web环境
        PHP8                                                                        --web环境
        .NET                                                                        --web环境
        Python                                                                      --web环境
        Node.js                                                                     --web环境
        -----------------------------------------------------------------------------------------------------
        minio                                                                       --对象存储服务器
        Nacos                                                                       --服务发现
        Jenkins                                                                     --持续集成工具
        Sentinel                                                                    --限流、熔断降级
        -----------------------------------------------------------------------------------------------------
        青龙                                                                        --定时任务管理平台
        KubePi                                                                      --现代化的 K8s 面板
        openresty                                                              【√】--基于Nginx的高性能Web应用服务器
        OpenLiteSpeed                                                               --高性能、轻量级、开源的HTTP服务器
        ApacheTomcat                                                                --开源的Web月服务器和Servlet容器
        NginxProxy Manager:Nginx 可视化管理工具
    e.大模型
        Ollama                                                                      --本地运行Llama2模型
        LocalAI                                                                     --免费的开源原OpenAI替代品
        -----------------------------------------------------------------------------------------------------
        new-api                                                                     --中转API
        one-api                                                                     --中转API
        -----------------------------------------------------------------------------------------------------
        MaxKB                                                                       --知识库问答系统
        LobeChat                                                                    --客户端API
        ChatGPT-Next-Web                                                            --客户端API

02.1panel面板
    a.环境要求
        操作系统:支持主流 Linux 发行版本(基于 Debian / RedHat,包括国产操作系统);
        服务器架构:x86_64、aarch64、armv7l、ppc64le、s390x;
        内存要求:建议可用内存在 1GB 以上;
        浏览器要求:请使用 Chrome、FireFox、IE10+、Edge等现代浏览器;
        可访问互联网。
    b.安装部署
        RedHat / CentOS
        curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sh quick_start.sh
        -----------------------------------------------------------------------------------------------------
        Ubuntu
        curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
        -----------------------------------------------------------------------------------------------------
        Debian
        curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && bash quick_start.sh
    c.安装成功后,控制台会打印面板访问信息,可通过浏览器访问 1Panel:
        http://目标服务器 IP 地址:目标端口/安全入口
        -----------------------------------------------------------------------------------------------------
        安全组规则:开放8080端口
        安全入口:1pctl user-info
    d.命令行工具
        1Panel 默认内置了命令行运维工具 1pctl,通过执行 1pctl help,可以查看相关的命令说明。
        Usage:
          1pctl [COMMAND] [ARGS...]
          1pctl --help
        Commands:
          status              查看 1Panel 服务运行状态
          start               启动 1Panel 服务
          stop                停止 1Panel 服务
          restart             重启 1Panel 服务
          uninstall           卸载 1Panel 服务
          user-info           获取 1Panel 用户信息
          listen-ip           切换 1Panel 监听 IP
          version             查看 1Panel 版本信息
          update              修改 1Panel 系统信息
          reset               重置 1Panel 系统信息
          restore             恢复 1Panel 服务及数据
        -----------------------------------------------------------------------------------------------------
        重置 1Panel 系统信息,包括取消安全入口登录,取消两步验证等
        Usage:
          1pctl reset [COMMAND] [ARGS...]
          1pctl reset --help
        Commands:
          domain              取消 1Panel 访问域名绑定
          entrance            取消 1Panel 安全入口
          https               取消 1Panel https 方式登录
          ips                 取消 1Panel 授权 IP 限制
          mfa                 取消 1Panel 两步验证
        -----------------------------------------------------------------------------------------------------
        修改 1Panel 监听 IP
        Usage:
          1pctl listen-ip [COMMAND] [ARGS...]
          1pctl listen-ip --help
        Commands:
          ipv4                监听 IPv4
          ipv6                监听 IPv6
        -----------------------------------------------------------------------------------------------------
        修改 1Panel 系统信息
        Usage:
          1pctl update [COMMAND] [ARGS...]
          1pctl update --help
        Commands:
          username            修改面板用户
          password            修改面板密码
          port                修改面板端口
        -----------------------------------------------------------------------------------------------------
        应用商店相关命令,包括初始化应用等
        Usage:
          1panel app [COMMAND] [ARGS...]
          1panel app --help
        Commands:
          init                初始化应用
        创建应用名为 app_name,版本为 v1.0.0 的应用,命令如下:
          1panel app init -k app_name -v v1.0.0

03.1Panel多因素认证
    a.设置流程(首次绑定)
        a.路径
            登录 1Panel -> 点击右上角头像 -> 安全设置 -> 两步验证。
        b.操作
            点击“开启两步验证”。
            屏幕上会出现一个巨大的 二维码。
            打开手机上的 Microsoft Authenticator App。
            点击 App 里的“+”号 -> 选择“工作或学校帐户” (或其他) -> 选择“扫描二维码”。
            对准屏幕扫描。
            App 会显示一个 6 位数字,将其填入 1Panel 的确认框。
            极其重要:1Panel 会给你一组 “应急备用码”。请抄写下来或打印,如果以后换手机或丢了手机,全靠这串码救急。
    b.使用流程(动态验证)
        a.登录时
            浏览器输入 1Panel 地址(如 http://192.168.1.249:10086)。
            输入用户名和密码。
            关键点:此时不会直接进系统,而是跳出一个新界面,要求输入 “MFA 验证码”。
            你打开手机 App,查看当前显示的 6 位数字(例如 839402)。
            输入并回车,登录成功。

03.1panel授权
    a.说明
        1Panel V2 专业版 买断授权正版授权,未激活直接转赠到你帐号。官网原价 ¥1400,只卖688元,不到五折,购买立省712元。
        注意:现在正式版已发布,可以稳定使用。
    b.套餐内容
        1台 1Panel V2 专业版永久授权(原价 ¥1200)
        赠送 1 个 受管社区版节点
        加送 1 个 社区版节点(原价 ¥200)
        最多可同时管理 3 台服务器
        节点扩容:超出部分 ¥200/个,可无限扩展
        入门套餐适合90%用户,轻松管理多服务器!
    c.专业功能亮点(含V1所有功能)
        多机统一管理(Linux)
        APP 手机端管理
        节点互传、负载均衡
        MySQL/PostgreSQL 主从复制支持
        Redis 集群可视化管理
        持续增强,稳定更新
    d.购买须知
        买断授权,永久可用
        全新未激活,包含500条短信
        确认收货后提供 ID 或手机号,直接官方转赠授权
        本人是长期深度用户(V1、V2均在用),欢迎交流!

1.3 mirror

01.快速开始
    a.Win10
        物理机
        Docker(WSL)
    b.VMware
        docker start mysql5
        docker start mysql8
        docker start redis
        docker start mongo
        docker start rabbit
        docker start elasticsearch
    c.Remote
        SSH
        Docker
        Dockerfile
        codespace
        Jetbrains
    d.Centos7
        a.Command
            01.network_bt.ova
            02.network_bt_compile(mysql_redis_mongo_tomcat_nginx).ova              【NOW-bigdata01】
            03.network_bt_compile(mysql_redis_mongo_tomcat_nginx)_python-3.7.2.ova
            04.network_jdk_docker.ova
            05.network_jdk_docker(mysql_redis_mongo_rabbitmq_es).ova
            06.network_jdk_docker_remote(mysql_redis_mongo_rabbitmq_es).ova        【NOW-bigdata02】
            07.network_bt_partition                                                【NOW-bigdata03】123456
        b.Graphical
            01.network_jdk_docker.ova                                              【NOW-bigdata04】
            02.network_jdk_docker(mysql_redis_mongo_rabbitmq_es).ova
    e.Debain10
        a.Command
            01.network.ova
            02.network_bt.ova
            03.network_bt_compile(mysql_redis_mongo_tomcat_nginx).ova              【NOW-debain01】
            04.network_docker.ova
            05.network_docker_remote(mysql_redis_mongo_rabbitmq_es).ova            【NOW-debain02】
            06.network_docker_remote(mysql_redis_mongo_rabbitmq_es)_k-vim.ova
        b.Graphical
            01.network.ova                                                         【NOW-debain03】
            02.network_bt.ova
            03.network_bt_compile(mysql_redis_mongo_tomcat_nginx).ova
    f.Developer
        a.Basic
            07.network_bt_partition                                                【NOW-bigdata03】123456
        b.Senior
            192.168.2.128                                                           bt_docker(portainer_rabbitmq_es)_compile(nginx_mysql_redis_mongodb_Java项目一键部署)_install(jdk_maven_tomcat)_deploy(ruoyi_ruoyi-vue)
            192.168.2.129                                                           bt_docker(Portainer_mysql_redis_mongo_rabbitmq_es)_docker(gitlab_jenkins_harbor_sonarqube)_install(git_jdk_maven_tomcat)
            192.168.2.130_1                                                         bt_docker(Portainer_mysql_redis_mongo_rabbitmq_es)_
            192.168.2.130_2                                                         bt_docker(Portainer)_deploy(ruoyi)
            192.168.2.130_3                                                         bt_docker(Portainer)_deploy(ruoyi-vue)
            192.168.2.131                                                           k8s-master
            192.168.2.132                                                           k8s-worker

02.常见镜像
    a.类型
        云服务器:ECS
        轻量应用:SWAS
        弹性容器:ECI
        容器集群:ACK
        对象存储:OSS
        监控分组:CMS
        托管实例
        弹性高性能计算
    b.轻量应用服务器(简化ECS):应用镜像
        LAMP:linux + apache + mysql +php
        LNMP:linux + nginx + mysql + php
        Docker
        Node.js
        PhPwind
        -----------------------------------------------------------------------------------------------------
        Typecho
        NextCloud
        Cloudreve
        wordPress
        -----------------------------------------------------------------------------------------------------
        1Panel
        宝塔Linux面板
        宝塔Windows面板
    c.轻量应用服务器(简化ECS):系统镜像
        Ubuntu
        CentOS
        CentOS Stream
        Debian
        Windows
        -----------------------------------------------------------------------------------------------------
        Alma Linux
        Rocky Linux
        Alibaba Cloud Linux
    d.云服务器(标准ECS):应用管理
        宝塔面板社区版               1panel运维面板社区版          Dify社区版                 AutoMQ for Kafka BYOC
        Java 运行环境                AutoMQ for Kafka BYOC版      Python运行环境             Docker社区版
        Node.js运行环境              LNMP运行环境                 WordPress社区版             LobeChat社区版
        LAMP运行环境                 PHP运行环境                  Golang运行环境              RagFlow社区版
        -------------------------------------------------------------------------------------------------
        Stable diffusion DeepGPU     云XR实时渲染平台             Langflow社区版              Sky CostPilot
        ChatGPTNextWeb社区版         MySQL社区版                  ComfyUIDeepGPU加速社区版    Zabbix社区版
        ChatGPT-on-WeChat社区版      Flowise社区版                JumpServer社区版            HeyForm社区版
        Appsmith社区版               OneAPI社区版                 NebulaGraph社区版           Jenkins社区版
        -------------------------------------------------------------------------------------------------
        OpenWebUI社区版              LibreChat社区版              Metabase社区版              Yunikorn社区版
        MongoDB社区版                Waline社区版                 Gitlab社区版                Discuz社区版
        翼龙面板社区版                Maybe社区版                  Prometheus社区版            Halo社区版
        FaceChain社区版              ArgoWorkflows社区版          Authorizer社区版            Jupyterhub社区版
        -------------------------------------------------------------------------------------------------
        Websoft9多应用托管平台        Keygen社区版                 Typebot社区版               PostgreSQL社区版
        Bytebase社区版                Grafana社区版                Drupal社区版                Chef社区版
        Puppet企业版                  Typecho社区版                SaltStack社区版             Ansible Semaphore社区版
    e.云服务器(标准ECS):计算巢
        DeepSeekR1                   宝塔面板社区版                幻兽帕鲁-快速部署           幻兽帕鲁-迁移到计算巢
        1panel运维面板社区版          Dify社区版                   AutoMQ for Kafka BBYOC     雾锁王国-迁移到计算巢
        Java运行环境                 我的世界-快速部署             AutoMQ for Kafka BYOC版    Python运行环境
        2048小程序一键部署            Docker社区版                 Node.js运行环境            TuGraph高性能图数据库
        LNMP运行环境                 七日杀-快速部署               WordPress社区版            LobeChat社区版
        LAMP运行环境                 悦数图数据库                  PHP运行环境                灵魂面甲-快速部署
        Stable Diffusion社区版       SQLynx                       雾锁王国-快速部署           Golang运行环境
        RagFlow社区版                基于NVIDIA NIM快速部署LLM模型 LLM Riddles社区版          夜族崛起-快速部署
        Stable diffusion DeepGPU     站式企业专属Chatbot           ChatTTS社区版             云XR实时渲染平台
        计算巢SaaSBoost社区版         Langflow社区版               Sky CostPilot             ChatGPTNextWeb社区版
        Volcano社区版                 MySQL社区版                  neo4j社区版               TOPIAM数字身份管控平台-社区版
        Cloudreve社区版               MaxKB社区版                  ComfyUIDeepGPU加速社区版  JHGitLab
        ChatGPT-on-WeChat社区版       Zabbix社区版                 Flowise社区版             Hologres+PAI5分钟一键部署企业级
        MemVerge MMCloud V3          Nocobase社区版               数擎全量预置服务           AlphaFold2社区版
        JumpServer社区版              HeyForm社区版                OneAPI社区版              NebulaGraph社区版
        Jenkins社区版                 LAMMPS社区版                 EMQX Enterprise Cluster  Appsmith社区版
        Open WebUI社区版              LibreChat社区版              九象(SkyDataPilot)        Alluxio分布式超大规模数据编排系统
        Metabase社区版                企业建站系统WordPress        Yunikorn社区版            MongoDB社区版
        Waline社区版                  Xinference社区版             Qdrant社区版              Gitlab社区版
        Discuz!社区版                 Istio社区版                  通义千问-开源大模型        翼龙面板社区版
        达梦数据库DM8社区版            MAPPIC-密态计算云平台        CoAI社区版                Nextcloud社区版
        ChaosMesh社区版               Maybe社区版                  Jupyter Notebook社区版    Prometheus社区版
        Halo社区版                    WPS文档中台-长虹佳华          PAI+NAS搭建企业级AIGC绘画 FaceChain社区版
        ArgoCD社区版                  ArgoWorkflows社区版          Authorizer社区版          在线文件管理/云存储系统Nextcloud
        Jupyterhub社区版              Moodle在线学习管理系统        宝塔Linux面板             Teable社区版
        DataEase社区版                云数据库TiDB                  五子棋网页游戏            扫雷网页游戏
        Websoft9多应用托管平台         云数据库Klustron             harbor社区版              万博云迁移
        turtle画布                    飞塔FortinettSDWAN           Keycloak社区版21.1.2      OpenFOAM社区版
        云数据库StoneDB软件           Walrus社区版                  AutoDockVina社区版        Redis社区版
        Java运行环境(CentOS7.9ARM版) MappingSpace                  用友U9 cloud             宝塔Llnux面板-7.9.9倚天版
        Tapdata Cloud Agent          用友U8 cloud                   Keygen社区版             Nginx-单机部署

03.常用部署
    a.vercel
        a.分类1
            Angular
            CreateReactApp
            -------------------------------------------------------------------------------------------------
            Hexo
            Hugo
            Jekyll
            Next.js
            Nuxt.js
            Preact
            -------------------------------------------------------------------------------------------------
            Vite
            VitePress
            Vue.js
            VuePress
            Other
        b.分类2
            Astro
            Blitz.js(Legacy)
            Brunch
            Docusaurus(v1)
            Docusaurus(v2)
            Dojo
            Eleventy
            Ember.js
            FastHTML(Experimental)
            -------------------------------------------------------------------------------------------------
            Gatsby.js
            Gridsome
            Hydrogen (v1)
            lonicAngular
            lonic React
            Middleman
            Parcel
            Polymer
            ReactRouter
            RedwoodJS
            Remix
            -------------------------------------------------------------------------------------------------
            Saber
            Sanity
            Sanity (v3)
            Sapper
            Scully
            SolidStart (vO)
            SolidStart (v1)
            Stencil
            Storybook
            Svelte
            SvelteKit (vO)
            SvelteKit (v1)
            UmiJS
            Zola
    b.zeabur
        a.价格
            免费试用计划
            一键部署任何服务,无需信用卡
            Google Cloud 的免费部署体验
            无需信用卡
            项目将在 24 小时后自动删除
            社区支持
            -------------------------------------------------------------------------------------------------
            开发者计划
            从每月开始:5美元
            部署无服务器和容器化服务并提供优先支持。
            部署任何类型的服务
            服务数据自动备份
            部署预构建映像
            优先技术支持
            -------------------------------------------------------------------------------------------------
            Free Trial
            HongKong
            Tokyo, Japan
            Taipei, Taiwan
            Shanghai, China
            Frankfurt, Germany
            California, United States
            Singapore、
            -------------------------------------------------------------------------------------------------
            Node.js:Astro、Express、NestS、Next.js、Nue、Nuxt、Qwik、Remix、Svelte Kit、Umi、Vite、Waku
            Bun:ElysiaJS、Hono
            Java:Spring Boot
            PHP:Laravel、Symfony
            Python:Django、Flask、Reflex
            Go
            Deno:Fresh、TypeScript
            Rust
            Swift:Vapor
            Dart:Flutter
            静态网站:Hugo、MkDocs
            .NET
        b.分类1
            Halo
            Hexo
            Gblog
            WordPress
            RSSHub
            Wechat2RSS
            wechat_gpt
            wechat-server
            -------------------------------------------------------------------------------------------------
            n8n
            Frp
            v2ray
            Nginx
            Supabase
            -------------------------------------------------------------------------------------------------
            Alist
            Pintree
            Cloudreve
            Nextcloud
            SiYuanNote
            Vaultwarden
        c.分类2
            Dify
            MaxKB
            Ollama
            -------------------------------------------------------------------------------------------------
            VoAPI
            NewAPI
            OneAPI
            MaxAPI
            OneHub
            -------------------------------------------------------------------------------------------------
            LobeChat
            NextChat
            LibreChat
            -------------------------------------------------------------------------------------------------
            ChatNio
            chat2api
            search2ai
            ChatGPTPlus
            ChatGPT-Mirror
            ChatGPT-Next-Web
            ChatGPT-Midjourney
        d.分类3
            MySQL
            LibSQL
            MariaDB
            PostgreSQL
            -------------------------------------------------------------------------------------------------
            Redis
            Kafka
            MongoDB
            RabbitMQ
            -------------------------------------------------------------------------------------------------
            SurrealDB
            Dragonfly
            ClickHouse
        e.分类4
            Gin-Starter
            FastAPI-Starter
            FastAPl-PostgreSQL
            Express.js Starter
            Kotlin Spring Boot Starter

1.4 storage

01.OSS对象存储
    a.RAM 访问控制
        用户:管理对急存储服务(OSS)权限、只读访问对象存储服务(OSS的权限)、管理云盒OSS的权限
        用户组:管理对象存储服务(OSS)权限、只读访问对象存储服务(OSS)的权限
    b.每个Bucket都需要单独设置跨越、授权策略,如troyekk-beijing、troyekk-zhangjiakou
        跨越设置:app://obsidian.md、capacitor://localhost、http://localhost;GET、POST、PUT、DELETE、HEAD
        授权策略:所有账号、读/写

02.客户端
    a.OSS Browser
        Endpoint:默认(公共云)、HTTPS加密(勾选)
        -----------------------------------------------------------------------------------------------------
        预设OSS路径:无
        备注:无
    b.S3 Browser
        Display name:troyekk-beijing
        Account type:S3 Compatible Storage
        REST Endpoint:oss-cn-beijing.aliyuncs.com
        Encrypt Access Keys with a password:不勾选
        Use secure transfer(SSL/TLS):勾选
        -----------------------------------------------------------------------------------------------------
        Display name:troyekk-zhangjiakou
        Account type:S3 Compatible Storage
        REST Endpoint:oss-cn-zhangjiakou.aliyuncs.com
        Encrypt Access Keys with a password:不勾选
        Use secure transfer(SSL/TLS):勾选
        -----------------------------------------------------------------------------------------------------
        由于OSS仅支持S3的virtual hosted style访问方式,也是S3推荐方式,而目前S3 Browser默认使用的是Path style
        因此,需要【Advanced S3-compatible storage settings】->【Addressing model:Virtual hosted style】
    c.Remotely Save
        服务地址(Endpoint):oss-cn-beijing.aliyuncs.com         --外网访问
        区域(Region):oss-cn-beijing-internal.aliyuncs.com      --ECS的经典网络访问(内网)
        存储桶(Bucket)的名字:troyekk-beijing
        -----------------------------------------------------------------------------------------------------
        自动运行:每1分钟
        启动后自动运行一次:启动后第1秒运行一次
    d.FolderSync
        连接地址:oss-cn-beijing.aliyuncs.com
        区域:ChinaBeijing
    e.Cloudberry Edxplorer
        Select Cloud Storage:Alibaba
        Display name:troyekk-beijing
        -----------------------------------------------------------------------------------------------------
        由于OSS仅支持S3的virtual hosted style访问方式,也是S3推荐方式,而目前S3 Browser默认使用的是Path style
        因此,需要打开【C:\Users\mysla\AppData\Local\CloudBerryLab\CloudBerry Explorer\settings.list】
        打开配置文件将对应用户的RequestStyle标签改为VHost,如下图所示,保存退出后重启CloudBerry即可生效。

1.5 docker-cli

01.开启Docker-Engine远程访问的支持
    a.配置:找到 ExecStart,增加 -H tcp://0.0.0.0:2375
        vi /lib/systemd/system/docker.service
        ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H fd:// --containerd=/run/containerd/containerd.sock
    b.重启
        systemctl daemon-reload && service docker restart
    c.防火墙
        firewall-cmd --zone=public --add-port=2375/tcp --permanent
        firewall-cmd --reload
        firewall-cmd --zone=public --list-ports

02.下载和配置docker-cli-builder
    a.安装
        https://github.com/StefanScherer/docker-cli-builder/releases/
    b.配置
        docker context create bigdata01 --docker "host=ssh://192.168.2.128"         --连接远程节点1(SSH)
        docker context create bigdata01 --docker "host=tcp://192.168.2.128:2375"    --连接远程节点1(TCP)
        docker context update bigdata01 --docker "host=tcp://192.168.2.128:2375"    --更新远程节点1(TCP)
        docker context ls                                                           --查看全部节点
        docker context rm -f bigdata01                                              --移除节点1
        docker context use bigdata01                                                --切换节点1
   c.导入与导出
        docker context export bigdata01                                             --导出节点1
        cat bigdata01.dockercontext                                                 --查看配置1
        docker context import bigdata01 bigdata01.dockercontext                     --将配置1导入到节点1
   d.使用
        docker info                                                                 --查看容器信息
        docker ps -a                                                                --查看全部镜像

03.使用远程容器开发
    a.远程主机上创建项目
        a.新建一个目录,例如 ~/newproj, 并编写如下Dockerfile:
            FROM python
            ENV DEBIAN_FRONTEND=noninteractive
            apt-get update
        b.先创建镜像,再启动容器(tail -f:容器保持运行)
            docker build . -t <image tag>
            docker run -d --name <container name> -v ~/newproj:/workspaces/newproj <image tag> tail -f /dev/null
    b.本地访问远程容器
        a.切换节点
            Docker Contexts: Use
        b.选择节点中需要使用的容器
            Remote-Containers: Attach to Running Container

1.6 codespace

01.原则
    a.创建代码空间
        ①将虚拟机和存储分配给代码空间
        ②创建容器:默认使用默认映像,自定义【.devcontainer文件夹下的devcontainer.json、Dockerfile】
        ③连接到代码空间:打开【浏览器】或【本地开发】
        ④创建后设置:调用dotfile仓库,可以实现【个性化CodeSpace】
    b.生命周期
        ①在代码空间中保存文件:默认几秒钟保存一次,没有交互30分钟后自动关闭
        ②关闭或停止代码空间:关闭【浏览器】或【本地开发】
        ③运行应用程序:默认所有端口都是私有,可以设置公有访问网址
    c.开发容器
        a.使用默认开发容器配置
            GitHub 使用默认 Linux 映像创建代码空间,适用于【临时修改文件】;
            直接使用【codespace】打开【repo】,在【Terminal】仍可检测到【java -version、mvn -v、node -v】
            -------------------------------------------------------------------------------------------------
            devcontainer-info content-url                                              默认linux配置
            -------------------------------------------------------------------------------------------------
            java -version                                                              17.0.2
            mvn -v                                                                     3.8.5
            gradle -v                                                                  7.4.2
            gcc                                                                        9.4.0
            curl www.baidu.com -i | iconv -f utf-8 -t gbk                              html
            -------------------------------------------------------------------------------------------------
            node -v                                                                    16.14.2
            yarn -v                                                                    1.22.15
            -------------------------------------------------------------------------------------------------
            go version                                                                 1.18.2
            pip --version                                                              22.1.1
            python --version                                                           3.10.4
            -------------------------------------------------------------------------------------------------
            mysql -V                                                                   无
            redis-cli.exe -h 127.0.0.1 -p 6379 -a myslayers                            无
            mongo                                                                      无
        b.使用预定义的开发容器配置
            Ctrl+Shift+P
            -> Codespaces: Add Development Container Configuration Files...
            -> Show All Definitions...
            -> Java 8
            -> Install Maven
            -> Rebuild now
        c.创建自定义开发容器配置
            https://github.com/halavah/demo
            -> Configure and create codespace
            -> Dev container configuration:.devcontainer.json                         默认配置
            -> Dev container configuration:.devcontainer/devcontainer.json            默认配置
            -> Dev container configuration:.devcontainer/teamA/devcontainer.json
            -> Dev container configuration:.devcontainer/teamB/devcontainer.json
            或
            https://github.com/settings
            -> CodeSpaces
            -> Dotfiles:Automatically install dotfiles
            -> GPG verification
            -> Access and security
        d.将配置更改应用于代码空间
            Ctrl+Shift+P
            -> Codespaces: Rebuild Container                                           代码空间:【重启】
    d.插件引导学习
        a.开始:打开演练
            Ctrl+Shift+P
            -> Get Started:Open Walkthrough...
        b.Learn the Fundamentals                                                       学习基础知识
            Redefine your editing skills                                               重新定义编辑技能
            Limitless extensibility                                                    无限的可扩展性
            Tune your settings                                                         调整您的设置
            Lean back and learn                                                        精益求精学习
        c.Boost your Productivity(提高工作效率)
            Side by side editing                                                       并排编辑
            Watch your code in action                                                  观察代码的运行情况
            Track your code with Git                                                   使用 Git 跟踪您的代码
            Automate your project tasks                                                自动化项目任务
            Customize your shortcuts                                                   自定义快捷键
        d.Get Started with VS Code in the Web(开始使用 Web 的 VS Code)
            Choose the look you want                                                   选择您想要的外观
            Sync to and from other devices                                             从其他设备同步
            One shortcut to access everything                                          一个快捷键访问全部内容
            Just the right amount of Ul                                                切换菜单栏
            Rich support for all your languages                                        对语言丰富的支持
            Quickly navigate between your files                                        在文件之间快速导航

02.配置
    a.插件
        浏览器:CODESPACES INSTALLED    48
        浏览器:BROWSER INSTALLED       00
        浏览器:RECOMMENDED             02
        -----------------------------------------------------------------------------------------------------
        本地开发:CODESPACES INSTALLED  57
        本地开发:BROWSER INSTALLED     48
        本地开发:RECOMMENDED           05
    b.快捷键
        浏览器:如需跟本地一致,必须覆盖配置文件
        浏览器:并不会自动设置【Settings 程序配置文件】、【Keyboard Shortcuts 键盘配置文件】,均为默认
        -----------------------------------------------------------------------------------------------------
        本地开发:会自动读取【Settings 程序配置文件】、【Keyboard Shortcuts 键盘配置文件】,均为自定义
        本地开发:若【Open in VS Code】,注意!!!此时【浏览器】就会拉取本地配置,与本地保持一致
    c.优先级
        如果在多个作用域中定义了设置,工作区设置优先级最高,远程 [Codespaces] 次之,最后是用户
        您可以在两个地方定义 VS 代码 的默认编辑器设置
        一是,在存储库的 .vscode/settings.json 文件中定义的编辑器设置将作为代码空间中工作区范围的设置进行应用
        二是,devcontainer.json 文件的 settings 键中定义的编辑器设置在代码空间中用作 Remote Codespaces 范围的设置

03.使用
    a.文件位置
        浏览器:均为github repo内的文件
        本地开发:均为github repo内的文件
    b.编辑文件
        1个仓库,1个配置
        文件都在远程,【浏览器】与【本地】通过port进行相连
        打开 package.json 插入任意文字,无论从本地还是浏览器均会【及时响应】
    c.运行文件
        浏览器:调用【https://halavah-demo-x6x4qppw2vr55-3000.githubpreview.dev/】中的【3000端口】
        本地开发:调用【http://127.0.0.1:3000/】中的【3000端口】
    d.识别JAVA环境
        必须为纯净的Java项目,项目最好不要嵌套

04.VScode开发Java项目
    a.准备
        a.Extension Pack for Java
            Maven for Java                                  --Java:扩展(无)
            Java Test Runner                                --Java:测试器(无)
            Debugger for Java                               --Java:调试器(无)
            Java Dependency Viewer                          --Java:依赖查看(无)
            Visual Studio IntelliCode                       --Java:代码提示(无)
            Language Support for Java(TM) by Red Hat        --JAVA:代码导航、自动补全、重构、代码片段(无)
        b.Spring Boot Extension Pack
            Spring Boot Tools                               --SpringBoot:工具(无)
            Spring Boot Dashboard                           --SpringBoot:仪表盘(launch.json)(无)
            Concourse CI Pipeline Editor                    --SpringBoot:对项目文件提供支持(无)
            Spring Initializr Java Support                  --SpringBoot:项目生成器(无)
            Cloudfoundry Manifest YML Support               --SpringBoot:对YML文件提供支持(无)
    b.新建Java工程
        a.命令
            Java: New Java Class                            --Java: 创建Java类
            Java: Create Java Project...                    --Java: 创建Java项目…
            Java: Open Java Extension Log File              --Java: 打开Java插件日志文件
            Java: Open Java Formatter Settings              --Java: 打开Java格式设置
            Java: Open Java Language Server Log File        --Java: 打开Java语言服务器日志文件
            Java: Open All Log Files                        --Java: 打开所有日志文件
            Java: Switch to Standard Mode                   --Java: 切换到标准模式
            Java: Clean Java Language Server Workspace      --Java: 清理Java语言服务器工作区
            Java: Show Build Job Status                     --Java: 显示工作状态
            Java: Debug Tests                               --Java: 调试测试用例
            Java: Run Tests                                 --Java: 运行测试用例
            Java: Configure Classpath
            Java: Configure Java Runtime
            Java: Extensions Guide
            Java: Help Center
            Java: Install New JDK
            Java: Open Java Formatter Settings with Preview
            Java: Overview
            Java: Show Release Notes
            Java: Tips for Beginners
        b.使用
            Java: Create Java Project...
            -> Maven
            -> archetype-quickstart-jdk8
            -> Relaunch
    c.新建SpringBooot工程
         a.命令
            Spring Boot Dashboard: Debug ..
            Spring Boot Dashboard: Run ..
            Spring Boot Dashboard: Show All Beans
            Spring Boot Dashboard: Show All Endpoints
            Spring Boot Dashboard: Show Defined Beans
            Spring Boot Dashboard: Show Defined Endpoints
            Spring Boot Dashboard: Stop ..
            Spring Boot: Manage Live Spring Boot Process Connections
            Spring Initializr: Add Starters...
            Spring Initializr: Create a Gradle Project...
            Spring Initializr: Create a Maven Project...
            Spring: Focus on Beans View
            Spring: Focus on Endpoint Mappings View
            Spring: Focus on Spring Boot Dashboard View
        b.使用
            Java: Create Java Project...
            -> SpringBoot
            -> Maven Project
            -> SpringBoot 2.7.0
            -> Java
            -> org.myslayers
            -> Jar
            -> Java 8
            -> Selected 6 dependencies:Lombok、Spring Web、...
            -> OK
        c.编写测试
            @RestController
            @SpringBootApplication
            public class DemoApplication {

                public static void main(String[] args) {
                    SpringApplication.run(DemoApplication.class, args);
                }

                @GetMapping("/hello")
                public String hello() {
                    return "hello world" + LocalDate.now();
                }
            }

2 docker

2.1 [1]basic

01.介绍
    a.CPU架构与ABI(Application binary interface)
        a.对应关系
            CPU架构(纵)\API(横) armeabi  armeabi-v7a  arm64-v8a  x86  x86_64  mips  mips64
            ARMv5                  支持
            ARMv7                  支持        支持
            x86                    支持        支持                 支持
            x86_64                 支持        支持                       支持
            ARMv8                  支持        支持        支持
            MIPS                                                                支持
            MIPS64                                                                     支持
        b.具体介绍
            x86:平板、模拟器
            x86_64:64位平板
            armeabi:第5代、第6代的ARM处理器,早期手机较多
            armeabiv-v7a:第7代及以上的ARM处理器,2011年15月生产的Android设备
            arm64-v8a:第8代、64位ARM处理器,目前比较常见
        c.为什么叫x86为32位系统呢?
            8086微处理器,英特尔出了划时代的8086之后,后来使用该架构出了80286、80386等,
            这一系列CPU就称作x86,正式一点称作IA-32(Intel Architecture 32-bit)
            -------------------------------------------------------------------------------------------------
            x86架构的特点是cpu的寄存器是32位的,因此也叫32位cpu
            基于32位cpu开发的操作系统就叫32位操作系统,因为目前x86架构在32位cpu的知名度,32位也被称为x86系统
        d.x86_64与amd64
            由于32位系统x86架构的种种限制,包括速度,性能等方面,Intel开始向64位架构发展,那么有两个选择:
            一是,向下兼容x86;二是,完全重新设计指令集,不兼容x86
            -------------------------------------------------------------------------------------------------
            结果AMD领先,比Intel率先制造出了商用的兼容x86的CPU,AMD称之为AMD64,抢了64位PC市场,得到了用户的认同
            而Intel选择了设计一种不兼容x86的全新64为指令集,称之为IA-64,但是比amd晚了一步,
            微软把intel给忽悠了,承诺了会出安腾版windows server版,但是迟迟拿不出东西,
            后来,微软也开始支持【AMD64的指令集】,但是换了个名字,叫x86_64,表示是x86指令集的64扩展
            -------------------------------------------------------------------------------------------------
            总结1:86_64、x64、AMD64基本上是同一个东西,现在用的intel/amd的桌面级CPU基本上都是x86_64
            总结2:i386被用来作为对Intel 32位微处理器的统称,更多时候,我们公认i386为32位系统,其实就是x86
    b.Dokcer运行模式
        a.两种模式
            一是(WSL2模式的Linux容器);二是(Hyper-V模式的Linux容器还是Windows容器)
        b.资源分配
            CPU:默认情况下,Docker Desktop设置为使用主机上可用处理器数量的一半
            内存:默认情况下,Docker Desktop设置为使用2GB运行时内存,该内存是从计算机上的总可用内存中分配的
            交换:根据需要配置交换文件的大小。默认值为1 GB
            磁盘映像大小:指定磁盘映像的大小
            磁盘映像位置:指定Linux卷的容器和映像的存储位置。
        c.文件共享
            “文件共享”选项卡仅在Hyper-V模式下可用,因为在WSL 2模式和Windows容器模式下,Windows将自动共享所有文件
        d.Switch to windows containers
            Windows container 分为两大部分:windows container on windows,linux container on windows
            两种运行时不能同时使用,可以切换,切换过程中数据是不会丢失的
            你不可以在 windows container 环境下操作 linux container 的镜像与容器
            更不能在 linux container 环境 下操作 windows container 的镜像和容器,两者架构上不一致
            -------------------------------------------------------------------------------------------------
            尽管两者在技术架构上有差异,但是 docker 的基本操作都是适用的,如果你的磁盘不够大网速不够好,
            不建议直接在自己电脑上尝试 windows container,windows container 大部分是基于 windows-sever 的镜像,
            动则十几个G,下载镜像都不一定能下载成功。
        e.总结
            Docker近几年发展中,停止了一些以往内容的维护,如Docker Machine、Docker toolbox...
            默认Docker for windows版本,分为WSL2、Hyper-V两种,默认WSL2,名字为【docker-desktop】
            默认Docker分为两种容器,分为Linux、Windows两种,即【基于Linux的镜像,无法在Windows使用】
    c.镜像、容器、数据卷、仓库、核心组成模块
        a.镜像
            Linux内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像,就相当于是一个root文件系统
            -------------------------------------------------------------------------------------------------
            Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,
            还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
            镜像不包含任何动态数据,其内容在构建之后也不会被改变。
            -------------------------------------------------------------------------------------------------
            分层存储:每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
            在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,额外东西应该在该层构建结束前清理掉
            分层存储的特征还使得镜像的复用、定制变的更为容易。
            甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
        b.容器
            镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,
            镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
            -------------------------------------------------------------------------------------------------
            容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
            因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
            -------------------------------------------------------------------------------------------------
            容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。
            -------------------------------------------------------------------------------------------------
            一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,
            我们可以称这个为容器运行时读写而准备的存储层为【容器存储层】。
            -------------------------------------------------------------------------------------------------
            容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。
            因此,任何保存于容器存储层的信息都会随容器删除而丢失。
        c.数据卷
            容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。
            所有的文件写入操作,都应该使用【数据卷】或者【绑定宿主目录】,
            在这些位置的【读写会跳过容器存储层】,直接对宿主(或网络存储)发生读写,其性能和稳定性更高
            -------------------------------------------------------------------------------------------------
            数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。
            因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
        d.仓库
            一个 Docker Registry 中可以包含多个 仓库(Repository);
            每个仓库可以包含多个 标签(Tag);
            每个标签对应一个镜像
            -------------------------------------------------------------------------------------------------
            Docker Registry 公开服务:开放给用户使用、允许用户管理镜像的 Registry 服务。
            如:官方Docker Hub,Red Hat的Quay.io,Google的Google Container Registry,GitHub推出的ghcr.io
            -------------------------------------------------------------------------------------------------
            Docker Registry 私有服务:官方提供了 Docker Registry 镜像,不包含图形界面,以及镜像维护、用户管理等
            如:官方Docker Registry,Harbor,Sonatype Nexus
        e.核心组成模块
            Docker的两个主要组成模块是: Docker Daemon 和 Docker CLI
            Docker CLI:一个用来与 Docker 守护进程进行交互的 Docker 命令行客户端,也就是 Docker 命令
            Docker Daemon:一个常驻的后台进程,帮助管理和创建 Docker 镜像、容器、网络和存储卷
            Docker Engine REST API:一个应用程序用来与 Docker 守护进程进行交互的 API;通过 HTTP 客户端访问它
    d.常见术语
        a.Docker Engine
            人们说“Docker”时,通常指的是Docker Engine,由Docker守护程序组成的客户端-服务器应用程序,指定用于与
            守护程序交互的接口的REST API和与守护程序进行对话的命令行界面(CLI)客户端(通过REST API包装器)
            Docker Enginedocker从CLI接受命令,例如 docker run <image>,docker ps列出正在运行的容器等
        d.Docker Machine
            Docker Machine 是一种在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机
        c.Docker Compose
            Compose 是用于定义和运行多容器 Docker 应用程序的工具
            Compose使用的三个步骤:
            使用 Dockerfile 构建镜像的文本文件,定义应用程序的环境
            使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行
            最后,执行 docker-compose up 命令来启动并运行整个应用程序
        d.Docker Swarm
            Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机
            -------------------------------------------------------------------------------------------------
            Docker Swarm                                    独立于Docker engine
                                                            需要额外的KV存储(也可以用Docker Hub的token)
                                                            没有服务模型
                                                            与Docker machine的集成
                                                            使用Docker CLI
            Swarmkit                                        在Docker 1.12 RC之前,Docker 发布了 Swarmkit
                                                            这是一个独立的、开源的容器编排项目
                                                            使用自己的CLI(swarmd负责管理,swarmctl用于控制)
                                                            没有服务发现、负载均衡和路由功能
                                                            提供编排和调度服务
                                                            是Swarm mode的基础
            Swarm mode                                      集成到了Docker engine中(docker swarm子命令)
                                                            不需要额外的KV存储
                                                            支持服务模型(及task概念)
                                                            支持扩容缩容、服务发现、滚动升级、路由和负载均衡
                                                            加密通信
                                                            还没有和Docker machine与Docker compose集成
                                                            使用Docker CLI
                                                            Swarm mode基于Swarmkit编写
            -------------------------------------------------------------------------------------------------
            总结:忘记Docker Swarm吧,知道有个Swarmkit,要用就用Docker Swarm Mode
        e.Kubernetes
            一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
            由Google与RedHat公司共同主导的开源“容器编排”项目,它起源于Google公司的Borg系统。
            打败了Docker推出的容器编排解决方案(Compose+Swarm),从而成为了容器编排领域事实上的标准。

02.Docker for windows
    a.常用信息1
        a.默认用户和密码
            用户            密码             进入方式
            docker          tcuser          ssh
            root                            command:sudo -i (docker用户下执行)
        b.环境变量
            C:\ProgramData\DockerDesktop\version-bin
            C:\Program Files\Docker\Docker\resources\bin
        c.路径解读
            C:\Users\mysla\.docker                                           --配置+常见配置文件
            C:\Program Files\Docker                                          --安装
            C:\ProgramData\DockerDesktop\                                    --配置
            C:\Users\mysla\AppData\Roaming\Docker                            --配置
            C:\Users\mysla\AppData\Local\Docker\wsl                          --WSL发行版默认位置
            C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx           --WSL运行数据、镜像文件
            C:\Users\mysla\AppData\Local\Docker\wsl\distro\ext4.vhdx         --WSL运行数据、镜像文件
    b.常用信息2
        a.服务
            WSL进程:Vmmem.exe
            注册名称:Docker Desktop Service
            注册服务:C:\Program Files\Docker\Docker\com.docker.service
        b.版本信息
            Version                         4.10.1(82475)
            Engine                          20.10.17
            Compose                         v2.6.1
            Credential Helper               v0.6.4
            Kubernetes                      v1.24.1
            Snyk                            v1.827.0
            -------------------------------------------------------------------------------------------------
            CS Docker Engine                最版本已移除
            Docker (1.13 and earlier)       最版本已移除
            Docker Machine                  最版本已移除
            Docker Swarm (standalone)       最版本已移除
            Docker Toolbox (legacy)         最版本已移除
            Kitematic
        c.扩展
            Ambassador Telepresence         Kubernetes:支持快速本地到远程开发和测试循环的工具
            anchore                         对images的内容和安全分析
            Aqua Trivy                      对远程或本地存储的images进行无限制的漏洞扫描。
            Ddosify                         高性能、开源、简单的负载测试工具
            Disk Usage                      查看Docker使用的磁盘空间                               【安装】
            Epinio                          一键将Source端推送到Kubernetes
            Gosh                            使用 Docker 和 Git 构建分散且安全的软件供应链
            JFrog                           使用 JFrog Xray 扫描您的 Docker 映像以查找漏洞
            Lacework Scanner                用于 Docker 桌面的 Lacework Scanner 集成
            Lens                            在 Docker 桌面上运行 Lens Kubernetes
            Logs Explorer                   在 Logs 查看所有容器日志,以便您进行调试                【安装】
            Meshery                         使用可扩展的设计和操作您的云原生部署
            Okteto                          Docker Compose 的远程开发
            OpenShift                       将Docker镜像部署到OpenShift
            Portainer                       Docker图形化界面                                      【安装】
            Slim.Al                         Slim 让您能够更快地创建安全容器
            Snyk                            Snyk Container 扩展使您能够扫描远程或本地images
            Tailscale                       虚拟组网工具,基于WireGuard
            Uffizzi                         Uffizzi 让您可以从 Docker 在云中创建和管理全栈预览
            VMware Tanzu Community Edition  将Kubernetes集群部署VMware Tanzu Community Edition
    b.镜像存储位置
        a.Linux
            镜像: /var/lib/docker/image
            容器: /var/lib/docker/containers
        b.Mac
            ~/Library/Containers/com.docker.docker/Data/vms/0/~
        c.Windows
            C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx           --WSL运行数据、镜像文件
            C:\Users\mysla\AppData\Local\Docker\wsl\distro\ext4.vhdx         --WSL运行数据、镜像文件

03.Docker根目录内部结构
    a.根目录
        /var/lib/docker为根目录,储存如下内容:容器数据、卷、构建文件、网络文件和集群数据
        -----------------------------------------------------------------------------------------------------
        $ ls -la /var/lib/docker
        drwx------    2 root     root          4096 May 20  2019 builder
        drwx------    4 root     root          4096 May 20  2019 buildkit
        drwx------    3 root     root          4096 May 20  2019 containerd
        drwx------    2 root     root         12288 Feb  3 19:35 containers     --容器
        drwx------    3 root     root          4096 May 20  2019 image          --镜像
        drwxr-x---    3 root     root          4096 May 20  2019 network
        drwx------    6 root     root         77824 Feb  3 19:37 overlay2       --存储驱动
        drwx------    4 root     root          4096 May 20  2019 plugins
        drwx------    2 root     root          4096 Feb  1 13:09 runtimes
        drwx------    2 root     root          4096 May 20  2019 swarm
        drwx------    2 root     root          4096 Feb  3 19:37 tmp
        drwx------    2 root     root          4096 May 20  2019 trust
        drwx------   15 root     root         12288 Feb  3 19:35 volumes        --卷
    b.镜像(images)
        最大的文件通常是镜像。默认overlay2存储驱动,镜像会保存在/var/lib/docker/overlay2
        -----------------------------------------------------------------------------------------------------
        $ docker image pull nginx
        $ docker image inspect nginx
        [
            {
                "Id": "sha256:207...6e1",
                "RepoTags": [
                    "nginx:latest"
                ],
                "RepoDigests": [
                    "nginx@sha256:ad5...c6f"
                ],
                "Parent": "",
                "Architecture": "amd64",
                "Os": "linux",
                "Size": 126698063,
                "VirtualSize": 126698063,
                "GraphDriver": {
                    "Data": {
                        "LowerDir": "/var/lib/docker/overlay2/585...9eb/diff:      --LowerDir只读层
                                     /var/lib/docker/overlay2/585...9eb/diff",
                        "MergedDir": "/var/lib/docker/overlay2/585...9eb/merged",
                        "UpperDir": "/var/lib/docker/overlay2/585...9eb/diff",
                        "WorkDir": "/var/lib/docker/overlay2/585...9eb/work"       --MergedDir运行容器
                    },
            }
        ]
    c.卷(Volumes)
        持久化容器内的数据,容器和宿主机之间、容器和容器之间也可以通过共享卷来共享数据,即【卷=数据】
        -----------------------------------------------------------------------------------------------------
        $ docker run --name nginx_container -v /var/log nginx                      --通过-v参数,容器挂载卷
        $ docker inspect nginx_container                                           -查看挂载的卷的位置
        "Mounts": [
                    {
                        "Type": "volume",
                        "Name": "1e4...d9c",
                        "Source": "/var/lib/docker/volumes/1e4...d9c/_data",
                        "Destination": "/var/log",
                        "Driver": "local",
                        "Mode": "",
                        "RW": true,
                        "Propagation": ""
                    }
                ],

04.VMware、WSL、Hyper-V、Dokcer兼容
    a.Docker
        a.Docker for windows两种运行方式
            第一种,基于WSL2的Docker
            第二种,基于Hyper-V的Docker
            -------------------------------------------------------------------------------------------------
            C:\Users\mysla>wsl -l -v
              NAME                   STATE           VERSION
            * docker-desktop         Stopped         2                       --运行Docker引擎
              docker-desktop-data    Stopped         2                       --存储容器和图像
        b.说明
            Docker Desktop与WSL2分发版本进行了集成,无需在WSL中安装docker;
            当然,也可以选择不与Docker Desktop集成,直接在WSL中运行docker;
            默认Docker for windows使用WSL2,如果不使用WSL2,手动【打开Docker设置】中更改为【Hyper-V虚拟机】运行
            Docker -> Settings -> General -> Use the WSL 2 based engine
            Docker -> Settings -> Resources -> WSL INTEGRATION -> Enable integration with my default WSL distro
            -------------------------------------------------------------------------------------------------
            启用或关闭Windows功能 -> 适用于Linux的Windows子系统                --开启WSL
            启用或关闭Windows功能 -> Hyper-V                                  --开启Hyper-V
            启用或关闭Windows功能 -> 虚拟机平台                                --开启Hyper-V
    b.Vmware
        a.说明
            默认,VMware 15.x 与 WSL1 兼容
            默认,VMware 15.x 与 WSL2 不兼容
            默认,VMware 15.x 与 Hyper-V 不兼容
            默认,WSL1、WSL2 与 Hyper-V 不兼容
            -------------------------------------------------------------------------------------------------
            默认,VMware 16 Pro 与 Hyper-V、WSL2 共存,无需任何设置
            -------------------------------------------------------------------------------------------------
            默认,虚拟化Intel VT-x/EPT或AMD-V/RVI(V) 与 Hyper-V 不兼容
            默认,虚拟化CPU性能计数器(U) 与 Hyper-V 不兼容
            默认,虚拟化IOMMU(O内存管理单元)(I) 与 Hyper-V 不兼容
        b.解决方法
            a.方法一
                将WSL2降级成WSL1
            b.方法二
                启动哪个,输入哪个命令
                bcdedit /set hypervisorlaunchtype off                        --启用VMware
                bcdedit /set hypervisorlaunchtype auto                       --启用WSL
        c.Vmware 15.x 兼容Hyper-v+WSL2+Docker,要求环境如下:
            a.步骤1
                Windows10(版本最低必须为19041)
                下载好的 VMware Workstation Pro Tech Preview 20H1 版本(默认提供试用229天)
                Windows10在BIOS中开启VT虚拟化
                Intel Haswell or newer CPU 或者 AMD Bulldozer or newer CPU
            b.步骤2
                网站:https://docs.microsoft.com/zh-cn/windows/wsl/install-win10
                问题:为什么不直接设置成【wsl --set-default-version 2】默认安装WSL2呢?
                回答:上述造成报错【WslRegisterDistribution failed with error: 0x80370102】,必须WSL1升WSL2
                ---------------------------------------------------------------------------------------------
                PS C:\Users\enen> wsl -l -v
                  NAME                   STATE           VERSION
                * Ubuntu-18.04           Running         1
                ---------------------------------------------------------------------------------------------
                # 用管理员模式启动PowerShell然后运行
                dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
                dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
                ---------------------------------------------------------------------------------------------
                # 这两个安装完成直接 重启 !!!!!!!!!重启!!!!!!
                # 这里的<Distro>就是你安装的WSL1的名称
                wsl --set-version <Distro> 2
                wsl -l -v
            c.步骤3
                安装VMware20H1,开启Hyper-v后,创建启动一个虚拟机发现正常(Vmware 15.x 提示不兼容的)
    c.WSL1 对比 WSL2
        a.命令
            wsl -l -v                                                        --查看WSL版本
            wsl --list --online                                              --列出可用的 Linux 发行版
            wsl --list --verbose                                             --列出已安装的 Linux 发行版
            wsl --status                                                     --检查WSL状态
            wsl --update                                                     --更新WSL
            wsl -u <Username>`, `wsl --user <Username>                       --以特定用户的身份运行
            <DistributionName> config --default-user <Username>              --更改发行版的默认用户
            -------------------------------------------------------------------------------------------------
            wsl --set-default-version 2                                      --将WSL默认为【WSL2】,2代表WSL2
            wsl --set-version Debian 1                                       --将WSL切换为【Debian+WSL1】
            wsl --set-version Debian 2                                       --将WSL切换为【Debian+WSL2】
            -------------------------------------------------------------------------------------------------
            wsl --install -d Debian                                          --安装该发行版
            wsl --install -d Ubuntu-18.04                                    --安装该发行版
        b.切换
            wsl --list                                                       --查看WSL可更换默认版本
            适用于 Linux 的 Windows 子系统分发版:
            docker-desktop (默认)
            docker-desktop-data
            Debian
            -------------------------------------------------------------------------------------------------
            wsl --set-default docker-desktop                                 --切换WSL默认为docker-desktop
            wsl.exe                                                          --验证
        c.WSL1
            WSL 1用的是Windows内核模拟的各种系统接口。
            虽然可以运行大部分Linux应用,但还是有不少依赖于内核的应用是无法正常运行的—,例如Docker。
            WSL 1和Windows共用文件系统、网络,有些时候会比较头疼
            -------------------------------------------------------------------------------------------------
            WSL1没有Linux内核,不支持docker
        d.WSL2
            WSL 2/Docker本质上都是Hyper-V。WSL 2是一个轻量级的Hyper-V VM;
            Docker for Windows如果要跑Linux镜像,安装运行一台运行Linux的Hyper-V虚拟机,用Hyper-V管理工具可以看到
            -------------------------------------------------------------------------------------------------
            WSL2是有Linux内核的轻量化虚拟机,支持docker,与WSL1不同的是,WSL2采用在Hyper-V虚拟机中运行的方案
            WSL2 Docker和宿主机Win10共享network,宿主机Win10使用【localhost:端口号】来访问【Container中的服务】

05.报错汇总
    a.报错1
        报错:WSL 2 installation is incomplete.
        解决:wsl2版本过老,需要手动更新【wsl_update_x64.msi】
    b.报错2
        报错:VMware出现Device Guard不相容错误
        解决:第一步,更新版本以上,Windows10 2004 / build 19041.264、VMware Workstation 15.5.5
        解决:第二步,VMware -> 虚拟化Intel VT-x/EPT或AMD-V/RVI(V)、 虚拟化CPU性能计数器(U) -> 关闭
    c.报错3
        报错:error during connect: This error may indicate that the docker daemon is not running
        解决:cd "C:\Program Files\Docker\Docker" && DockerCli.exe -SwitchDaemon      --第1步
        解决:net stop com.docker.service                                             --第2步
        解决:net start com.docker.service                                            --第3步
        解决:Docker Desktop.exe                                                      --第4步
        解决:Expose daemon on tcp://localhost:2375 without TLS                       --第5步(开启守护进程)
    d.报错4
        报错:vmmem进程占用内存情况为15.9/16GB,死循环尝试连接 -> 失败 -> 尝试连接
        解决:wsl --shutdown

2.2 [1]install

00.Docker镜像
    a.配置
        https://docker.rainbond.cc
        https://mirror.baidubce.com
        https://hub-mirror.c.163.com
        https://almtd3fa.mirror.aliyuncs.com
    b.阿里云
        https://6juphqlo.mirror.aliyuncs.com
        -----------------------------------------------------------------------------------------------------
        当前仅支持阿里云用户使用具备公网访问能力的阿里云产品进行镜像加速,且仅限于特定范围内的容器镜像。详情请见公告
    c.2025-01-01
        https://docker.hpcloud.cloud
        https://docker.m.daocloud.io
        https://docker.unsee.tech
        https://docker.1panel.live
        http://mirrors.ustc.edu.cn
        https://docker.chenby.cn
        http://mirror.azure.cn
        https://dockerpull.org
        https://dockerhub.icu
        https://hub.rat.dev
        https://proxy.1panel.live
        https://docker.1panel.top
        https://docker.m.daocloud.io
        https://docker.1ms.run
        https://docker.ketches.cn

01.Docker安装
    a.方式一
        a.安装所需的3个工具包(memory > 2G)
            sudo yum install -y yum-utils \
            device-mapper-persistent-data \
            lvm2
        b.配置docker安装源
            sudo yum-config-manager \
            --add-repo \
            http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        c.安装Engine-Community
            sudo yum install docker-ce docker-ce-cli containerd.io
        d.启动
            systemctl start docker
        e.自启
            systemctl enable docker
    b.方式二
        yum update -y \
        && yum install docker -y \
        && systemctl start docker \
        && systemctl enable docker \
        && service docker status
    c.方式三
        curl -sSL https://get.docker.com/ | sh
        curl -fsSL https://get.docker.com -o get-docker.sh && bash get-docker.sh
        curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
    d.配置文件
        a.daemon.json
            C:\Users\mysla\.docker\daemon.json                               --打开文件
            {
              "builder": {
                "gc": {
                  "defaultKeepStorage": "20GB",
                  "enabled": true
                }
              },
              "experimental": false,
              "features": {
                "buildkit": true
              },
              "registry-mirrors": [
                "https://mirror.baidubce.com",
                "https://hub-mirror.c.163.com",
                "https://almtd3fa.mirror.aliyuncs.com"
              ]
            }
            -------------------------------------------------------------------------------------------------
            {
              "registry-mirrors": [
                "https://hub-mirror.c.163.com",
                "https://mirror.baidubce.com",
                "https://docker.rainbond.cc"
              ]
            }
            -------------------------------------------------------------------------------------------------
            vi /etc/docker/daemon.json
            {
                "data-root":"/data/docker",
                "registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"]
            }
            -------------------------------------------------------------------------------------------------
            systemctl daemon-reload                                          --重新加载daemon.json文件
            systemctl restart docker.service                                 --重启docker服务
            docker info                                                      --验证
        b.wslconfig
            C:\Users\mysla -> 新建文件(.wslconfig)                          --打开文件
            -------------------------------------------------------------------------------------------------
            [wsl2]
            processors=4
            memory=4GB
            swap=4GB
            localhostForwarding=true
            -------------------------------------------------------------------------------------------------
            wsl --shutdown                                                   --关闭当前的子系统
            Docker Desktop                                                   --重启

02.Docker使用
    a.常用命令1
        C:\Windows\system32>wsl --shutdown                                      --经测试,14.5GB -> 7.57GB
        -----------------------------------------------------------------------------------------------------
        docker login                                                            --登录DockerHub(myslayers)
        docker logout                                                           --登出DockerHub(XXXXXXXXX)
        -----------------------------------------------------------------------------------------------------
        docker search activemq                                                  --搜索镜像
        docker pull webcenter/activemq                                          --拉取镜像
        -----------------------------------------------------------------------------------------------------
        docker tag mysql:5.7.27 myslayers/mysql:dev                             --设置标签
        docker push myslayers/mysql:dev                                         --推送镜像
        -----------------------------------------------------------------------------------------------------
        docker search myslayers/mysql                                           --测试1
        docker pull myslayers/mysql:dev                                         --测试2
    b.常用命令2
        docker ps                                                               --container:运行
        docker ps -a                                                            --container:运行、未运行
        docker ps --no-trunc                                                    --container:查看command参数
        docker images                                                           --images:全部
        docker volume ls                                                        --volume:全部
        -----------------------------------------------------------------------------------------------------
        docker version                                                          --版本
        docker info                                                             --配置
        docker info | grep "Docker Root Dir"                                    --配置,Docker存放位置
        -----------------------------------------------------------------------------------------------------
        docker start 80576e5ea74a                                               --启动容器
        docker stop 80576e5ea74a                                                --停止容器
        docker restart 80576e5ea74a                                             --重启容器
        docker rm 80576e5ea74a                                                  --移除容器
        docker logs 80576e5ea74a                                                --查看日志
        docker inspect 80576e5ea74a                                             --查看构建
        docker port myslayers-mysql5                                            --查看端口
        docker exec -it myslayers-prtainer /bin/bash                            --进入容器
    c.清理空间
        docker system df                                                        --查看Docker磁盘大致情况
        docker system df -v                                                     --查看Docker磁盘详细情况
        -----------------------------------------------------------------------------------------------------
        docker container prune                                                  --清理,无用的container
        docker image prune                                                      --清理,无用的image
        docker volume prune                                                     --清理,无用的volume
        docker system prune -a                                                  --删除,无用的镜像容器缓存【慎重】
        -----------------------------------------------------------------------------------------------------
        docker ps -a
        docker rm  -f 80576e5ea74a                                              --移除容器,-f参数:强制删除
        docker images
        docker rmi -f d55229deb03e                                              --移除镜像,-f参数:强制删除
        docker volume ls
        docker volume rm -f d55229deb03e                                        --移除卷,-f参数:强制删除
        -----------------------------------------------------------------------------------------------------
        C:\Windows\system32>wsl --shutdown                                      --经测试,14.5GB -> 7.57GB
        C:\Windows\system32>diskpart
        DISKPART> select vdisk file="C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx"
        DISKPART> attach vdisk readonly                                         --连接
        DISKPART> compact vdisk                                                 --压缩
        DISKPART> detach vdisk                                                  --断开
        DISKPART> exit
        -----------------------------------------------------------------------------------------------------
        docker system df; \
        docker kill $(docker ps -aq); \
        docker rm $(docker ps -aq); \
        docker rmi $(docker images -q); \
        docker volume rm $(docker volume ls -q); \
        docker system df
    d.卸载docker
        a.查看docker版本
            yum list installed | grep docker
        b.卸载docker版本
            yum -y remove docker-ce.x86_64
            yum -y remove containerd.io.x86_64
            yum -y remove docker-ce-cli.x86_64
        c.删除存储目录
            rm -rf /etc/docker
            rm -rf /run/docker
            rm -rf /var/lib/dockershim
            rm -rf /var/lib/docker
        d.若发现删除,需要先进行umount操作
            umount /var/lib/docker/devicemapper
    e.设置容器开机自启动
        a.开启
            docker update --restart=always Portainer
        b.关闭
            docker update --restart=no Portainer

03.Docker Compose使用
    a.安装
        sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    b.版本
        [root@bigdata01 ~]# sudo chmod +x /usr/local/bin/docker-compose         --授予当前用户执行权限
        [root@bigdata01 ~]# docker-compose version                              --版本
        docker-compose version 1.25.0, build 0a186604
        docker-py version: 4.1.0
        CPython version: 3.7.4
        OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019
    c.操作
        docker search gitlab                                                    --查看gitlab镜像
        docker pull gitlab/gitlab-ce:latest                                     --拉取gitlab镜像
    d.创建文件夹
        [root@bigdata01 ~]# cd /usr/local
        [root@bigdata01 local]# mkdir docker
        [root@bigdata01 local]# cd docker/
        [root@bigdata01 docker]# mkdir gitlab_docker
        [root@bigdata01 docker]# cd gitlab_docker/
        [root@bigdata01 gitlab_docker]# pwd
        /usr/local/docker/gitlab_docker
    e.创建docker-compose.yml文件
        cd /usr/local/docker/gitlab_docker
        vi docker-compose.yml
        -----------------------------------------------------------------------------------------------------
        version: '3.1'
        services:
          gitlab:
            image: 'gitlab/gitlab-ce:latest'
            container_name: gitlab
            restart: always
            environment:
              GITLAB_OMNIBUS_CONFIG: |
                external_url 'http://192.168.2.128:8929'
                gitlab_rails['gitlab_shell_ssh_port'] = 2224
            ports:
              - '8929:8929'
              - '2224:2224'
            volumes:
              - './config:/etc/gitlab'
              - './logs:/var/log/gitlab'
              - './data:/var/opt/gitlab'
    f.启动docker-compose
        cd /usr/local/docker/gitlab_docker
        docker-compose up -d                                                    --启动
        docker-compose logs -f                                                  --日志
    g.访问
        http://192.168.2.128:8929                                               --访问
        root
        glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
    h.获取默认密码
        [root@bigdata01 gitlab_docker]# docker exec -it gitlab bash             --进入容器
        root@f48f17cf9d8a:/# cat /etc/gitlab/initial_root_password              --查看密码
        # WARNING: This value is valid only in the following conditions
        #          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
        #          2. Password hasn't been changed manually, either via UI or via command line.
        #
        #          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

        Password: glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=

        # NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
        root@f48f17cf9d8a:/#
    i.修改密码
        http://192.168.2.128:8929/-/profile/password/edit                       --修改密码
        当前密码:glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
        新密码:12345678

04.Docker数据卷
    a.数据卷
        a.介绍
            数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
            数据卷可以在容器之间共享和重用
            对数据卷的修改会立马生效
            对数据卷的更新,不会影响镜像
            数据卷默认会一直存在,即使容器被删除
            -------------------------------------------------------------------------------------------------
            数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷,
            并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。
        b.命令
            docker run -p 80:80 -v /data:/data -d nginx:latest                --创建一个数据卷:-v(volume)
                Mounts:/data/                                                --【√】,/data目录
            -------------------------------------------------------------------------------------------------
            docker inspect nginx                                              --查看数据卷信息
            -------------------------------------------------------------------------------------------------
            docker exec -it nginx mkdir /mnt/web/test                         --方式一:不进入容器,新增数据
            docker exec -it nginx /bin/bash                                   --方式二:进入容器,新增数据
            mkdir /mnt/web/test                                               --方式二:进入容器,新增数据
        c.同步性测试
            a.本机文件可以同步到容器
                在本机/tmp/data1目录中新建hello.txt文件
                touch /tmp/data1/hello.txt
                ls /tmp/data1/
                hello.txt
                ---------------------------------------------------------------------------------------------
                hello.txt文件在容器/tmp/data2/目录中可见
                docker exec test ls /tmp/data2/
                hello.txt
                ---------------------------------------------------------------------------------------------
                可知,在本机目录/tmp/data1/的修改,可以同步到容器目录/tmp/data2/中
            b.容器文件可以同步到主机
                在容器/tmp/data2目录中新建world.txt文件
                docker exec test touch /tmp/data2/world.txt
                docker exec test ls /tmp/data2/
                hello.txt
                world.txt
                ---------------------------------------------------------------------------------------------
                world.txt文件在主机/tmp/data1/目录中可见
                ls /tmp/data1/
                hello.txt  world.txt
                ---------------------------------------------------------------------------------------------
                可知,在容器目录/tmp/data2/的修改,可以同步到主机目录/tmp/data1/中
    b.数据卷容器
        a.介绍
            如果你有一些【持续更新的数据】需要在容器之间【共享】,最好创建数据卷容器。
            数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
        b.命令
            docker run -d -v /dbdata --name dbdata training/postgres          --【√】,/var/lib/docker随机目录
                Mounts:/var/lib/docker/volumes/0b0968dcb12f39/_data
            docker run -d -v workspace_data:/dbdata --name dbdata training/postgres
                Mounts:/var/lib/docker/volumes/workspace_data/_data          --【√】,/var/lib/docker指定目录
            -------------------------------------------------------------------------------------------------
            docker run -d -v /workspace_data:/dbdata --name dbdata training/postgres
                Mounts:无                                                    --【√】,/workspace_data目录
            docker run -d -v /root/test:/dbdata --name dbdata training/postgres
                Mounts:/root/test                                            --【√】,/root/test目录
            -------------------------------------------------------------------------------------------------
            docker run -d --volumes-from dbdata --name db1 training/postgres  --创建db1容器,从dbdata挂载
            docker run -d --volumes-from dbdata --name db2 training/postgres  --创建db2容器,从dbdata挂载
            docker run -d --volumes-from dbdata --name db3 training/postgres  --创建db3容器,从dbdata挂载
    c.备份、恢复
        a.备份
            docker run -itd --name nginx -v web:/mnt/web nginx                         --挂载卷web:/mnt/web
                Mounts:/var/lib/docker/volumes/web/_data
            -------------------------------------------------------------------------------------------------
            docker volume ls                                                           --查看卷web
                DRIVER    VOLUME NAME
                local     web
            -------------------------------------------------------------------------------------------------
            docker exec -it nginx /bin/bash                                            --进入容器
            root@826f13832ca6:/# ls
            bin   dev                  docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
            boot  docker-entrypoint.d  etc                   lib   media  opt  root  sbin  sys  usr
            root@826f13832ca6:/mnt/web# ls
            TODO1.txt  TODO2.txt  TODO3.txt
            -------------------------------------------------------------------------------------------------
            docker run -it \
            --volumes-from nginx \
            -v /root/test:/backup \
            nginx \
            tar cvf /backup/web.tar /mnt/web                                           --备份
                ---------------------------------------------------------------------------------------------
                nginx基础镜像新建一个临时的容器(不放入后台运行,但会【随机创建类似exciting_ride的容器】)
                数据共享容器nginx的数据卷web
                -v  指定将本机的/root/test目录挂载到临时容器的/backup目录
                tar 执行备份命令将临时容器的/mnt/web目录打包压缩到/backup目录下名为web.tar的备份文件
                ---------------------------------------------------------------------------------------------
                ①数据卷web挂载到了nginx容器的/mnt/web目录
                ②而临时容器又共享了nginx容器的数据卷web,因此直接打包容器的/mnt/web目录
                ③本机的/root/test目录挂载到了临时容器的/backup目录
                所以,直接在本机的/root/test目录中查找备份文件web.tar
                ---------------------------------------------------------------------------------------------
                映射关系:/root/test 映射 /backup
                         /backup/web.tar 备份 /mnt/web文件夹
                         /mnt/web文件夹 对应 共享数据卷web
        b.恢复
            docker run -itd --name nginxback -v webdata:/mnt/web nginx
                --用nginx基础镜像新启动一个带有【空数据卷webdata】的【容器nginxback】
            -------------------------------------------------------------------------------------------------
            docker volume ls                                                           --查看卷web
                DRIVER    VOLUME NAME
                local     web
                local     webdata(恢复卷)
            -------------------------------------------------------------------------------------------------
            docker exec -it nginxback /bin/bash                                        --进入容器
            root@826f13832ca6:/# ls
            bin   dev                  docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
            boot  docker-entrypoint.d  etc                   lib   media  opt  root  sbin  sys  usr
            root@826f13832ca6:/mnt/web# ls
            无
            -------------------------------------------------------------------------------------------------
            docker run -it \
            --volumes-from nginxback \
            -v /root/test:/backup \
            nginx \
            tar xvf /backup/web.tar                                                    --恢复
                ---------------------------------------------------------------------------------------------
                nginx基础镜像新建一个临时的容器(不放入后台运行,但会【随机创建类似exciting_ride的容器】)
                数据共享容器nginxback的数据卷webdata(作用是将web.tar文件数据恢复至数据卷webdata)
                -v  指定将本机的/root/test目录挂载到临时容器的/backup目录
                tar 将临时容器的/backup目录下名为web.tar的备份文件恢复至nginxback容器的数据卷webdata
                ---------------------------------------------------------------------------------------------
                ①数据卷web挂载到了nginx容器的/mnt/web目录
                ②而临时容器又共享了nginx容器的数据卷web,因此直接打包容器的/mnt/web目录
                ③本机的/root/test目录挂载到了临时容器的/backup目录
                所以,直接在本机的/root/test目录中查找备份文件web.tar
                ---------------------------------------------------------------------------------------------
                映射关系:/root/test 映射 /backup
                         /backup/web.tar 备份 /mnt/web文件夹
                         /mnt/web文件夹 对应 共享数据卷web
        c.验证
            a.验证nginxback是否与nginx数据卷一致
                root@debian01:~# docker exec -it nginx ls /mnt/web                     --原nginx
                TODO1.txt  TODO2.txt  TODO3.txt
                root@debian01:~# docker exec -it nginxback ls /mnt/web                 --现nginx
                TODO1.txt  TODO2.txt  TODO3.txt
            b.为了验证web数据卷备份恢复到webdata数据卷的数据,再启动一个新容器挂载webdata数据卷查看数据
                root@debian01:~# docker run -itd --name nginxtest -v webdata:/mnt/web nginx
                f7b57a0a6ce82f078bba4cf9011d000ba1bf15c7d1994b2b69588e929ecd8abc
                root@debian01:~# docker exec -it nginxtest ls /mnt/web                 --新nginx
                TODO1.txt  TODO2.txt  TODO3.txt
    d.MySQL的备份与恢复
        a.mysql容器
            docker run -itd --name myslayers-mysql8 \
            -p 3306:3306 \
            -e MYSQL_ROOT_PASSWORD=4033665 \
            -v /docker/mysql/data/:/var/lib/mysql/ \
            -v /docker/mysql/conf.d:/etc/mysql/conf.d \
            -v mysql8_data:/var/lib/mysql \
            mysql:latest
            -------------------------------------------------------------------------------------------------
            docker exec -it myslayers-mysql8 /bin/bash                              --进入容器
            mysql -u root -p                                                        --测试(用户root密码4033665)
        b.备份
            docker run -it \
            --volumes-from myslayers-mysql8 \
            -v /root/test:/backup \
            mysql \
            tar cvf /backup/test.tar /var/lib/mysql
        c.mysql_back容器
            docker run -itd \
            --name mysql_back \
            -e MYSQL_ROOT_PASSWORD=4033665 \
            -v mysql8_data_back:/var/lib/mysql \
            mysql:latest
        d.恢复
            docker run -it \
            --volumes-from mysql_back \
            -v /root/test:/backup \
            mysql \
            tar xvf /backup/test.tar -C /var/lib/mysql

05.Docker制作镜像
    a.方式一:从已经创建的容器中更新镜像,并提交这个镜像
        docker run -t -i ubuntu:15.10 /bin/bash                                         --进入容器
        -----------------------------------------------------------------------------------------------------
        docker commit -m="has update" -a="myslayers" e218edb10161 runoob/ubuntu:v2      --更新镜像
        -m: 提交的描述信息
        -a: 指定镜像作者
        e218edb10161:容器 ID
        runoob/ubuntu:v2: 指定要创建的目标镜像名
        -----------------------------------------------------------------------------------------------------
        docker images                                                                   --查看镜像
        REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
        runoob/ubuntu       v2                  70bf1840fd7c        15 seconds ago      158.5 MB
        -----------------------------------------------------------------------------------------------------
        docker tag mysql:5.7.27 myslayers/mysql:dev                                     --设置标签
        docker push myslayers/mysql:dev                                                 --推送镜像
        -----------------------------------------------------------------------------------------------------
        docker search myslayers/mysql                                                   --测试1
        docker pull myslayers/mysql:dev                                                 --测试2
    b.方式二:使用 Dockerfile 指令来创建一个新的镜像
        cat Dockerfile                                                                  --查看Dockerfile
        -----------------------------------------------------------------------------------------------------
        FROM    centos:6.7
        MAINTAINER      Fisher "[email protected]"
        RUN     /bin/echo 'root:123456' |chpasswd
        RUN     useradd runoob
        RUN     /bin/echo 'runoob:123456' |chpasswd
        RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
        EXPOSE  22
        EXPOSE  80
        CMD     /usr/sbin/sshd -D
        -----------------------------------------------------------------------------------------------------
        docker build -t runoob/centos:6.7 .                                             --build构建镜像
        -t :指定要创建的目标镜像名
        . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
        -----------------------------------------------------------------------------------------------------
        docker images                                                                   --查看镜像
        REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
        runoob/centos       6.7                 860c279d2fec        About a minute ago   190.6 MB
        -----------------------------------------------------------------------------------------------------
        docker tag mysql:5.7.27 myslayers/mysql:dev                                     --设置标签
        docker push myslayers/mysql:dev                                                 --推送镜像
        -----------------------------------------------------------------------------------------------------
        docker search myslayers/mysql                                                   --测试1
        docker pull myslayers/mysql:dev                                                 --测试2

2.3 [1]backup

01.Docker备份
    a.Windows
        a.位置
            C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx           --WSL运行数据、镜像文件
            C:\Users\mysla\AppData\Local\Docker\wsl\distro\ext4.vhdx         --WSL运行数据、镜像文件
        b.docker-desktop-data 对应 data
            # 停止docker,在任务栏中手动停止
            # data文件夹下的ext4.vhdx为1.12GB
            # 导出 docker-desktop-data
            wsl --export docker-desktop-data "D:\\docker-desktop-data.tar"
            # 注销 docker-desktop-data
            wsl --unregister docker-desktop-data
            # 导入 docker-desktop
            wsl --import docker-desktop-data "F:\\docker\\wsl\\data" "D:\\docker-desktop-data.tar" --version 2
        c.docker-desktop 对应 distro
            # 停止docker,在任务栏中手动停止
            # distro文件夹下的ext4.vhdx为127MB
            # 导出 docker-desktop
            wsl --export docker-desktop "D:\\docker-desktop.tar"
            # 注销 docker-desktop
            wsl --unregister docker-desktop
            # 导入 docker-desktop
            wsl --import docker-desktop "F:\\docker\\wsl\\distro" "D:\\docker-desktop.tar" --version 2
        d.切换WSL
            C:\Users\mysla> wsl --list                                        --查看WSL可更换默认版本
            适用于 Linux 的 Windows 子系统分发版:
            docker-desktop (默认)
            docker-desktop-data
            Debian
            -------------------------------------------------------------------------------------------------
            C:\Users\mysla> wsl --set-default docker-desktop                 --切换WSL默认为docker-desktop
            C:\Users\mysla> wsl --list                                       --验证
            wsl.exe                                                          --验证
    b.Linux
        a.总结
            a.三组命令
                sava与load
                export与import
                checkpoint与reestore
            b.文件大小不同
                export 导出的镜像文件体积小于 save 保存的镜像
            c.是否可以对镜像重命名
                docker import 可以为镜像指定新名称
                docker load 不能对载入的镜像重命名
            d.是否可以同时将多个镜像打包到一个文件中
                docker export 不支持
                docker save 支持
            e.是否包含镜像历史
                docker import 是根据容器拿到的镜像,可以【给容器数据打快照】,推荐
                docker save 直接根据镜像来进行报错,无法【给数据打快照】
                若是只想备份images,使用save、load即可
                若是在启动容器后,容器内容有变化,需要备份,则使用export、import
        b.sava-load
            a.操作1
                docker save mysql:5.7.27 > mysql_5.7.27.tar                     --save:导出镜像(单个)
                docker load < /root/mysql_5.7.27.tar                            --load:导入镜像(单个)
            b.操作2
                docker save mysql:5.7.27 mysql:latest > mysql_5.7.27_latest.tar --save:导出镜像(多个合并为单个)
                docker save -o mysql_5.7.27_latest.tar mysql:5.7.27 mysql:latest--save:导出镜像(多个合并为单个)
                docker load < /root/mysql:5.7.27_latest.tar                     --load:导入镜像(多个合并为单个)
            c.运行image为container
                末尾无需跟参数:【docker ps --no-trunc -> COMMAND】
                docker run -itd --name myslayers-mysql5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=4033665 mysql:5.7.25
        c.export-import
            a.操作
                docker export myslayers-mysql5 > mysql_5.7.27.tar               --export:容器导出镜像(仅单个)
                docker import - mysql:5.7.27 < mysql_5.7.27.tar                 --import:导入镜像(仅单个)
            b.运行image为container
                末尾必须跟参数:【docker ps --no-trunc -> COMMAND】
                docker run -itd --name myslayers-mysql5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=4033665 mysql:5.7.27 docker-entrypoint.sh mysqld
        d.批量脚本
            a.镜像的批量导出
                #!/bin/bash
                # 获取到 "image:tag" 格式的镜像名
                IMG_NAME=`docker images | grep -v TAG | awk '{print $1":"$2}'`
                # 定义镜像存放目录
                DIR="/data/docker/image_tar"
                if [ ! -d "$DIR" ]; then
                  echo -e "\033[34m${DIR}\033[0m 不存在"
                  mkdir -p "$DIR"
                  echo -e "\033[34m${DIR}\033[0m 已创建"
                else
                  echo -e "\033[34m${DIR}\033[0m 已存在"
                fi
                echo ""
                for IMAGE in $IMG_NAME
                do
                  echo -e "正在保存 \033[33m${IMAGE}\033[0m"
                  SAVE_NAME=`echo $IMAGE | awk -F: '{print $1"_"$2}' | sed 's/\//_/g'`
                  docker save $IMAGE -o ${DIR}/${SAVE_NAME}.tar
                  echo -e "已保存到 \033[34m${DIR}/\033[31m${SAVE_NAME}.tar\033[0m"
                  echo ""
                done
            b.镜像的批量导入
                for i in `ls /data/docker/image_tar/*`;do docker load <$i;done

02.Docker释放
    a.查看Docker大小
        $ cd /var/lib/docker
        $ du -h --max-depth=1 *                                          --当前目录下各文件、文件夹的大小
        $ du -h --max-depth=0 *                                          --子目录文件及文件夹大小统计
        $ du –sh                                                         --查看指定目录的总大小
        -----------------------------------------------------------------------------------------------------
        docker system df                                                 --查看Docker磁盘使用情况
        docker system df -v                                              --查看Docker磁盘详细情况
        -----------------------------------------------------------------------------------------------------
        TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
        Images          1         1         376.1MB   0B (0%)
        Containers      1         1         63B       0B (0%)
        Local Volumes   1         1         43.39MB   0B (0%)
        Build Cache     0         0         0B        0B
    b.清理Docker空间
        docker system df                                                 --查看Docker磁盘使用情况
        docker container prune                                           --清理,无用的container
        docker image prune                                               --清理,无用的image
        docker volume prune                                              --清理,无用的volume
        docker system prune -a                                           --删除,无用的镜像容器缓存【慎重】
        -----------------------------------------------------------------------------------------------------
        docker system df                                                 --查看Docker磁盘使用情况
        docker ps -a
        docker ps --no-trunc
        docker rm  -f 80576e5ea74a                                       --移除容器,-f参数:强制删除
        docker images
        docker rmi -f d55229deb03e                                       --移除镜像,-f参数:强制删除
        docker volume ls
        docker volume rm -f d55229deb03e                                 --移除卷,-f参数:强制删除
        -----------------------------------------------------------------------------------------------------
        docker system df                                                 --查看Docker磁盘使用情况
        docker kill $(docker ps -aq)                                     --清除全部文件,包括正在运行
        docker rm $(docker ps -aq)
        docker rmi $(docker images -q)
        docker volume rm $(docker volume ls -q)
        -----------------------------------------------------------------------------------------------------
        docker system df                                                 --查看Docker磁盘使用情况
        docker rm $(docker ps -aq)                                       --保留正在运行的XXX,其他全部清除
        docker rmi $(docker images -q)
        docker volume rm $(docker volume ls -q)
    c.清理WSL空间
        a.说明
            WSL2使用虚拟硬盘(VHD)存储linux下的文件,最大限制256G
            但是,在Linux中减少文件占用,WSL却没有相应的减少硬盘空间的占用,需要手动释放这部分空间
        b.操作
            C:\Windows\system32>wsl --shutdown                            --经测试,14.5GB -> 7.57GB
            C:\Windows\system32>diskpart
            DISKPART> select vdisk file="C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx"
            DISKPART> attach vdisk readonly                               --连接
            DISKPART> compact vdisk                                       --压缩
            DISKPART> detach vdisk                                        --断开
            DISKPART> exit
    d.卸载docker
        a.查看docker版本
            yum list installed | grep docker
        b.卸载docker版本
            yum -y remove docker-ce.x86_64
            yum -y remove containerd.io.x86_64
            yum -y remove docker-ce-cli.x86_64
        c.删除存储目录
            rm -rf /etc/docker
            rm -rf /run/docker
            rm -rf /var/lib/dockershim
            rm -rf /var/lib/docker
        d.若发现删除,需要先进行umount操作
            umount /var/lib/docker/devicemapper

03.Docker扩容
    a.方式一:软链接
        a.说明
            挂载新的分区到该目录,在原有系统空间不变的情况下,采用【软链接:修改镜像和容器的存放路径】的方式
        b.操作
            systemctl stop docker                            --停掉Docker服务
            mv /var/lib/docker /data/docker                  --移动
            ln -sf /data/docker /var/lib/docker              --软链接(显示/var/lib/docker,实际/data/docker)
    b.方式二:docker.service
        a.修改
            vi /etc/default/docker                           --配置文件(Ubuntu 18)
            vi /usr/lib/systemd/system/docker.service        --配置文件(CentOS 7)
            配置如下:
            ExecStart=/usr/bin/dockerd --graph="/data/docker"--说明 --graph 指定镜像和容器存放路径
        b.修改daemon.json
            vi /etc/docker/daemon.json
            {
                "registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
                "graph": "/data/docker"
            }
        c.重启
            systemctl daemon-reload                          --重新加载daemon.json文件
            systemctl restart docker.service                 --重启docker服务
            docker info | grep "Docker Root Dir"             --配置,Docker存放位置
    c.方式三:docker.service.d 文件夹下的 docker.conf
        a.修改
            mkdir /etc/systemd/system/docker.service.d/      --默认 docker.service.d 文件夹不存在
            配置如下:
            $ sudo vi /etc/systemd/system/docker.service.d/docker.conf
            [Service]
            ExecStart=/usr/bin/dockerd --graph="/data/docker" --storage-driver=devicemapper  --参数覆盖
        b.修改daemon.json
            vi /etc/docker/daemon.json
            {
                "registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
                "graph": "/data/docker"
            }
        c.重启
            systemctl daemon-reload                          --重新加载daemon.json文件
            systemctl restart docker.service                 --重启docker服务
            docker info | grep "Docker Root Dir"             --配置,Docker存放位置

2.4 [1]network

01.介绍
    a.回送地址
        默认:192.168.65.0/28
        说明:127.0.0.1也称为回送地址,因为它连接到本地系统而不是远程系统上。
              IP地址范围127.0.0.1/8已完全注册用于回送,这意味着在127.0.0.1 – 127.0.1.255之间注册了环回接口
    b.Docker端口映射
        端口映射可使用-p、-P来实现:
        -p指定要映射的端口,一个指定端口上只可以绑定一个容器
        -P将容器内部开放的网络端口随机映射到宿主机的一个端口上
        -----------------------------------------------------------------------------------------------------
        默认情况下 -p 和 -P 绑定的都是 tcp 协议端口
        如果要绑定 udp 协议端口,只能使用 -p 参数,且在最后添加 /udp 字符串
        如:docker run -d -p 127.0.0.1:5553:5000/udp jcdemo/flaskapp
        -----------------------------------------------------------------------------------------------------
        多次使用 -p 参数可以映射多个端口
        如:docker run -d -p 5552:5000  -p 5551:5001 jcdemo/flaskapp

        端口映射支持的格式:
        ip:hostport:containerport #指定ip、指定宿主机port、指定容器port
        ip::containerport #指定ip、未指定宿主机port(随机)、指定容器port
        hostport:containerport #未指定ip、指定宿主机port、指定容器port
        -----------------------------------------------------------------------------------------------------
        端口的映射有以下五种方法:
        方法一:将容器暴露的所有端口,都随机映射到宿主机上(不推荐使用)
                docker run -P -it ubuntu /bin/bash
        方法二:将容器指定端口随机映射到宿主机一个端口上
                docker run -P 80 -it ubuntu /bin/bash
        方法三:将容器指定端口指定映射到宿主机的一个端口上
                docker run -p 8000:80 -it ubuntu /bin/bash           --将容器的80端口映射到宿主机的8000端口
        方法四:将容器ip和端口,随机映射到宿主机上
                docker run -P 192.168.0.100::80 -it ubuntu /bin/bash
        方法五:将容器ip和端口,指定映射到宿主机上
                docker run -p 192.168.0.100:8000:80 -it ubuntu /bin/bash

02.设置固定ip地址
    a.说明
        a.默认
            说明:使用默认bridge网络进行固定IP地址创建时会报错,只有在自定义halavah网络下才可设置固定IP
            示例:docker run -itd --net bridge --ip 172.17.0.10 nginx:latest /bin/bash
            报错:user specified IP address is supported on user defined networks only.
            -------------------------------------------------------------------------------------------------
            说明:只允许一个“主机”网络实例
            报错:only one instance of "host" network is allowed
        b.分类
            a.bridge:桥接网络
                默认情况下启动的Docker容器,都是使用bridge,Docker安装时创建的桥接网络,
                每次Docker容器重启时,会按照顺序获取对应的IP地址,这个就导致重启下,Docker的IP地址就变了
            b.none:无指定网络
                使用--network=none,容器就不会分配局域网的IP
            c.host:主机网络
                使用--network=host,Docker容器的网络会附属在主机上,两者是互通的
                例如,在容器中运行一个Web服务,监听8080端口,则主机的8080端口就会自动映射到容器中
    b.系统进程
        a.Windows
            ipconfig                                                            --查看IPV4
            netstat -ano                                                        --查看全部端口
            netstat -aon|findstr 135                                            --查看某个端口
            taskkill -f -pid 135                                                --删除某个端口
            tasklist|findstr 12088                                              --根据pid查看应用程序
        b.Centos
            ip a / ip addr / ip address                                         --查看IPV4
            hostname -I                                                         --查看IPV4
            install net-tools && ifconfig -a                                    --查看IPV4
            -------------------------------------------------------------------------------------------------
            ps                                                                  --查看全部进程
            pkill -9 python                                                     --结束name为python的全部进程
            -------------------------------------------------------------------------------------------------
            netstat -nap                                                        --查看正常使用的端口以及关联的进程
            netstat -ntulp | grep 8080                                          --查看8080端口
            lsof -i 8080                                                        --查看8080端口
            ps [pid]                                                            --查看8080端口对应的pid进程
            kill -9 [pid]                                                       --关闭8080端口对应的pid进程
    c.操作
        a.汇总
            docker network connect                                              --将容器连接到网络
            docker network create                                               --创建一个网络
            docker network disconnect                                           --断开容器的网络
            docker network inspect                                              --显示一个或多个网络的详细信息
            docker network ls                                                   --列出网络
            docker network prune                                                --删除所有未使用的网络
            docker network rm                                                   --删除一个或多个网络
            -------------------------------------------------------------------------------------------------
            --driver host                                                       --driver指定类型
            --subnet=192.168.3.0/16                                             --subnet指定ip段
            --gateway=192.168.3.1                                               --gateway指定网关
            --network halavah --ip 172.17.0.10                                  --network指定网络类型
        b.查看
            $ docker network ls
        c.增加+创建绑定
            docker network create \
            --subnet=192.168.3.0/16 \
            --gateway=192.168.3.1 \
            halavah                                                             --创建halavah网络
            -------------------------------------------------------------------------------------------------
            docker network inspect halavah                                      --查看halavah网络
            -------------------------------------------------------------------------------------------------
            docker run -itd \
            --name nginx01 \
            --network halavah \
            --ip 192.168.3.128 \
            nginx                                                               --绑定nginx01容器
            docker inspect nginx01 | grep -i “network”                          --查看nginx01网络
            -------------------------------------------------------------------------------------------------
            docker run -itd \
            --name nginx02 \
            --network halavah \
            --ip 192.168.3.129 \
            nginx                                                               --绑定nginx02容器
            docker inspect nginx02 | grep -i “network”                          --查看nginx02网络
        d.删除
            $ docker network rm halavah
        e.更改
            docker network disconnect halavah nginx01                           --解除容器(nginx01)绑定网络
            docker network rm halavah                                           --删除原先的网络
            -------------------------------------------------------------------------------------------------
            docker network create --subnet=192.168.3.0/16 myslayers             --重新创建容器网络
            docker network connect myslayer test01                              --为容器重新指定网络
            docker container restart test01                                     --重新启动容器

03.容器访问
    a.外部访问容器
        a.端口映射基础
            基本语法:
            docker run -p 宿主机端口:容器端口 镜像名                              --映射指定端口
            docker run -P 镜像名                                                 --随机映射所有暴露端口
            -------------------------------------------------------------------------------------------------
            示例1:映射单个端口
            docker run -d -p 8080:80 nginx                                       --宿主机8080映射到容器80
            -------------------------------------------------------------------------------------------------
            示例2:指定IP绑定
            docker run -d -p 127.0.0.1:8080:80 nginx                             --只允许本机访问
            docker run -d -p 192.168.1.10:8080:80 nginx                          --指定IP访问
            -------------------------------------------------------------------------------------------------
            查看端口映射:
            docker port 容器名/ID                                                 --查看容器端口映射
            docker ps                                                            --查看所有容器端口映射
        b.多端口映射
            映射多个端口:
            docker run -d \
              -p 8080:80 \
              -p 8443:443 \
              nginx                                                              --同时映射80和443端口
            -------------------------------------------------------------------------------------------------
            映射端口范围:
            docker run -d -p 8000-8010:8000-8010 myapp                           --映射端口段
        c.指定协议
            TCP协议(默认):
            docker run -d -p 8080:80/tcp nginx                                   --TCP协议
            -------------------------------------------------------------------------------------------------
            UDP协议:
            docker run -d -p 5353:53/udp bind9                                   --UDP协议
            -------------------------------------------------------------------------------------------------
            同时映射TCP和UDP:
            docker run -d \
              -p 8080:80/tcp \
              -p 5353:53/udp \
              myapp
        d.动态端口映射
            使用-P参数自动映射:
            docker run -d -P nginx                                               --自动映射所有EXPOSE端口
            -------------------------------------------------------------------------------------------------
            查看映射的端口:
            docker port 容器ID                                                    --查看具体映射
            -------------------------------------------------------------------------------------------------
            示例输出:
            80/tcp -> 0.0.0.0:32768
            443/tcp -> 0.0.0.0:32769
        e.访问测试
            本机访问:
            curl http://localhost:8080                                           --访问映射的端口
            -------------------------------------------------------------------------------------------------
            远程访问:
            curl http://服务器IP:8080                                            --从其他机器访问
            -------------------------------------------------------------------------------------------------
            检查端口监听:
            netstat -tlnp | grep 8080                                            --查看端口监听状态
            ss -tlnp | grep 8080                                                 --使用ss命令查看
    b.容器互联
        a.默认bridge网络
            同一网络下的容器可以互相通信:
            docker run -d --name web1 nginx                                      --创建容器1
            docker run -d --name web2 nginx                                      --创建容器2
            -------------------------------------------------------------------------------------------------
            容器间通信:
            docker exec web1 ping web2                                           --通过容器名ping(需要自定义网络)
            docker exec web1 ping 172.17.0.3                                     --通过IP ping
        b.自定义网络互联
            创建自定义网络:
            docker network create mynet                                          --创建网络
            docker network create --subnet=172.20.0.0/16 mynet                   --指定子网
            -------------------------------------------------------------------------------------------------
            使用自定义网络:
            docker run -d --name web1 --network mynet nginx                      --加入mynet网络
            docker run -d --name web2 --network mynet nginx                      --加入mynet网络
            -------------------------------------------------------------------------------------------------
            容器间通信:
            docker exec web1 ping web2                                           --直接通过容器名通信
            docker exec web1 curl http://web2                                    --HTTP访问
        c.网络别名
            为容器设置别名:
            docker run -d --name web1 --network mynet --network-alias webapp nginx
            -------------------------------------------------------------------------------------------------
            通过别名访问:
            docker exec web2 ping webapp                                         --使用别名访问
        d.连接多个网络
            将容器连接到多个网络:
            docker network create net1                                           --创建网络1
            docker network create net2                                           --创建网络2
            -------------------------------------------------------------------------------------------------
            docker run -d --name web1 --network net1 nginx                       --容器加入net1
            docker network connect net2 web1                                     --同时连接到net2
            -------------------------------------------------------------------------------------------------
            查看容器网络:
            docker inspect web1 | grep -i network                                --查看网络配置
        e.容器link(已废弃)
            传统link方式(不推荐):
            docker run -d --name db mysql                                        --创建数据库容器
            docker run -d --name web --link db:database nginx                   --link到db容器
            -------------------------------------------------------------------------------------------------
            环境变量传递:
            docker exec web env | grep DATABASE                                  --查看注入的环境变量
            -------------------------------------------------------------------------------------------------
            推荐使用:建议使用自定义网络替代link
        f.跨主机容器通信
            使用overlay网络(Docker Swarm):
            docker network create --driver overlay myoverlay                     --创建overlay网络
            docker service create --name web --network myoverlay nginx           --创建服务
            -------------------------------------------------------------------------------------------------
            使用macvlan网络:
            docker network create -d macvlan \
              --subnet=192.168.1.0/24 \
              --gateway=192.168.1.1 \
              -o parent=eth0 macvlan_net                                         --创建macvlan网络

04.数据管理
    a.数据卷(Volume)
        a.创建和使用数据卷
            创建数据卷:
            docker volume create mydata                                          --创建名为mydata的卷
            -------------------------------------------------------------------------------------------------
            挂载数据卷:
            docker run -d --name web -v mydata:/usr/share/nginx/html nginx      --挂载到容器
            -------------------------------------------------------------------------------------------------
            匿名卷:
            docker run -d -v /usr/share/nginx/html nginx                         --自动创建匿名卷
        b.查看数据卷信息
            docker volume ls                                                     --列出所有卷
            docker volume inspect mydata                                         --查看卷详细信息
            -------------------------------------------------------------------------------------------------
            输出示例:
            [
                {
                    "CreatedAt": "2023-12-16T10:00:00Z",
                    "Driver": "local",
                    "Mountpoint": "/var/lib/docker/volumes/mydata/_data",
                    "Name": "mydata"
                }
            ]
        c.删除数据卷
            docker volume rm mydata                                              --删除指定卷
            docker volume prune                                                  --删除所有未使用的卷
            -------------------------------------------------------------------------------------------------
            强制删除:
            docker volume rm -f mydata                                           --强制删除
        d.数据卷容器
            创建数据卷容器:
            docker run -d --name datastore -v /data busybox                      --创建数据容器
            -------------------------------------------------------------------------------------------------
            其他容器使用:
            docker run -d --name web1 --volumes-from datastore nginx             --共享数据卷
            docker run -d --name web2 --volumes-from datastore nginx             --共享数据卷
            -------------------------------------------------------------------------------------------------
            多个容器共享同一数据卷
    b.绑定挂载(Bind Mount)
        a.挂载主机目录
            基本挂载:
            docker run -d -v /host/path:/container/path nginx                    --挂载主机目录
            -------------------------------------------------------------------------------------------------
            实例:
            docker run -d -v /data/nginx:/usr/share/nginx/html nginx            --挂载网站目录
            docker run -d -v /var/logs:/var/log/nginx nginx                     --挂载日志目录
        b.挂载单个文件
            docker run -d -v /host/nginx.conf:/etc/nginx/nginx.conf:ro nginx    --挂载配置文件
            -------------------------------------------------------------------------------------------------
            注意:挂载文件时建议使用绝对路径
        c.只读挂载
            docker run -d -v /data:/data:ro nginx                                --只读挂载
            docker run -d -v /data:/data:rw nginx                                --读写挂载(默认)
        d.挂载权限问题
            设置权限:
            chmod 755 /host/path                                                 --修改主机目录权限
            chown -R 1000:1000 /host/path                                        --修改所有者
            -------------------------------------------------------------------------------------------------
            容器内指定用户:
            docker run -d --user 1000:1000 -v /data:/data nginx                  --指定运行用户
    c.tmpfs挂载
        a.tmpfs基本使用
            docker run -d --tmpfs /tmp nginx                                     --创建tmpfs挂载
            docker run -d --tmpfs /tmp:rw,size=100m nginx                        --指定大小和权限
        b.tmpfs应用场景
            存储临时文件
            存储敏感信息(重启后自动清除)
            需要高速读写的场景
    d.数据备份和恢复
        a.备份数据卷
            docker run --rm -v mydata:/data -v $(pwd):/backup busybox \
              tar czf /backup/mydata-backup.tar.gz /data                         --备份数据卷
        b.恢复数据卷
            docker run --rm -v mydata:/data -v $(pwd):/backup busybox \
              tar xzf /backup/mydata-backup.tar.gz -C /                          --恢复数据卷
        c.容器间数据迁移
            导出数据:
            docker run --rm -v olddata:/from -v newdata:/to busybox \
              cp -av /from/. /to                                                 --复制数据到新卷

2.5 [2]terminal

00.汇总
    a.镜像
        Linux内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像,就相当于是一个root文件系统
        -------------------------------------------------------------------------------------------------
        Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,
        还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
        镜像不包含任何动态数据,其内容在构建之后也不会被改变。
        -------------------------------------------------------------------------------------------------
        分层存储:每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
        在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,额外东西应该在该层构建结束前清理掉
        分层存储的特征还使得镜像的复用、定制变的更为容易。
        甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
    b.容器
        镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,
        镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
        -------------------------------------------------------------------------------------------------
        容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
        因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
        -------------------------------------------------------------------------------------------------
        容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。
        -------------------------------------------------------------------------------------------------
        一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,
        我们可以称这个为容器运行时读写而准备的存储层为【容器存储层】。
        -------------------------------------------------------------------------------------------------
        容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。
        因此,任何保存于容器存储层的信息都会随容器删除而丢失。
    c.数据卷
        容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。
        所有的文件写入操作,都应该使用【数据卷】或者【绑定宿主目录】,
        在这些位置的【读写会跳过容器存储层】,直接对宿主(或网络存储)发生读写,其性能和稳定性更高
        -------------------------------------------------------------------------------------------------
        数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。
        因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
    d.仓库
        一个 Docker Registry 中可以包含多个 仓库(Repository);
        每个仓库可以包含多个 标签(Tag);
        每个标签对应一个镜像
        -------------------------------------------------------------------------------------------------
        Docker Registry 公开服务:开放给用户使用、允许用户管理镜像的 Registry 服务。
        如:官方Docker Hub,Red Hat的Quay.io,Google的Google Container Registry,GitHub推出的ghcr.io
        -------------------------------------------------------------------------------------------------
        Docker Registry 私有服务:官方提供了 Docker Registry 镜像,不包含图形界面,以及镜像维护、用户管理等
        如:官方Docker Registry,Harbor,Sonatype Nexus
    e.核心组成模块
        Docker的两个主要组成模块是: Docker Daemon 和 Docker CLI
        Docker CLI:一个用来与 Docker 守护进程进行交互的 Docker 命令行客户端,也就是 Docker 命令
        Docker Daemon:一个常驻的后台进程,帮助管理和创建 Docker 镜像、容器、网络和存储卷
        Docker Engine REST API:一个应用程序用来与 Docker 守护进程进行交互的 API;通过 HTTP 客户端访问它

01.常用信息1
    a.常用命令1
        C:\Windows\system32>wsl --shutdown                                      --经测试,14.5GB -> 7.57GB
        -----------------------------------------------------------------------------------------------------
        docker login                                                            --登录DockerHub(myslayers)
        docker logout                                                           --登出DockerHub(XXXXXXXXX)
        -----------------------------------------------------------------------------------------------------
        docker search activemq                                                  --搜索镜像
        docker pull webcenter/activemq                                          --拉取镜像
        -----------------------------------------------------------------------------------------------------
        docker tag mysql:5.7.27 myslayers/mysql:dev                             --设置标签
        docker push myslayers/mysql:dev                                         --推送镜像
        -----------------------------------------------------------------------------------------------------
        docker search myslayers/mysql                                           --测试1
        docker pull myslayers/mysql:dev                                         --测试2
    b.常用命令2
        docker ps                                                               --container:运行
        docker ps -a                                                            --container:运行、未运行
        docker ps --no-trunc                                                    --container:查看command参数
        docker images                                                           --images:全部
        docker volume ls                                                        --volume:全部
        -----------------------------------------------------------------------------------------------------
        docker version                                                          --版本
        docker info                                                             --配置
        docker info | grep "Docker Root Dir"                                    --配置,Docker存放位置
        -----------------------------------------------------------------------------------------------------
        docker start 80576e5ea74a                                               --启动容器
        docker stop 80576e5ea74a                                                --停止容器
        docker restart 80576e5ea74a                                             --重启容器
        docker rm 80576e5ea74a                                                  --移除容器
        docker logs 80576e5ea74a                                                --查看日志
        docker inspect 80576e5ea74a                                             --查看构建
        docker port myslayers-mysql5                                            --查看端口
        docker exec -it myslayers-prtainer /bin/bash                            --进入容器
    c.清理空间
        docker system df                                                        --查看Docker磁盘大致情况
        docker system df -v                                                     --查看Docker磁盘详细情况
        -----------------------------------------------------------------------------------------------------
        docker container prune                                                  --清理,无用的container
        docker image prune                                                      --清理,无用的image
        docker volume prune                                                     --清理,无用的volume
        docker system prune -a                                                  --删除,无用的镜像容器缓存【慎重】
        -----------------------------------------------------------------------------------------------------
        docker ps -a
        docker rm  -f 80576e5ea74a                                              --移除容器,-f参数:强制删除
        docker images
        docker rmi -f d55229deb03e                                              --移除镜像,-f参数:强制删除
        docker volume ls
        docker volume rm -f d55229deb03e                                        --移除卷,-f参数:强制删除
        -----------------------------------------------------------------------------------------------------
        C:\Windows\system32>wsl --shutdown                                      --经测试,14.5GB -> 7.57GB
        C:\Windows\system32>diskpart
        DISKPART> select vdisk file="C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx"
        DISKPART> attach vdisk readonly                                         --连接
        DISKPART> compact vdisk                                                 --压缩
        DISKPART> detach vdisk                                                  --断开
        DISKPART> exit
        -----------------------------------------------------------------------------------------------------
        docker system df; \
        docker kill $(docker ps -aq); \
        docker rm $(docker ps -aq); \
        docker rmi $(docker images -q); \
        docker volume rm $(docker volume ls -q); \
        docker system df

02.常用信息2
    a.卸载docker
        a.查看docker版本
            yum list installed | grep docker
        b.卸载docker版本
            yum -y remove docker-ce.x86_64
            yum -y remove containerd.io.x86_64
            yum -y remove docker-ce-cli.x86_64
        c.删除存储目录
            rm -rf /etc/docker
            rm -rf /run/docker
            rm -rf /var/lib/dockershim
            rm -rf /var/lib/docker
        d.若发现删除,需要先进行umount操作
            umount /var/lib/docker/devicemapper
    b.设置容器开机自启动
        a.开启
            docker update --restart=always Portainer
        b.关闭
            docker update --restart=no Portainer

2.6 [2]compose

00.图示
    特性          Dockerfile                 Docker Compose
    用途          构建单个容器               镜像编排多容器应用
    文件格式      文本文件,包含指令          YAML文件,定义服务、网络和卷
    使用场景      创建自定义镜像              管理多容器应用(如Web+DB+Cache)
    核心命令      docker build               docker-compose up
    依赖关系      无                         可以定义服务之间的依赖关系
    典型使用      构建镜像                   启动、停止和管理多容器应用

01.简单说明
    a.定义
        Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具
        它通过一个 YAML 文件(通常是 docker-compose.yml)来配置多个服务、网络和存储卷,从而实现一键启动整个应用
    b.核心作用
        a.编排多容器应用
            在实际项目中,一个应用往往由多个服务组成,比如 Web 服务器、数据库、缓存服务等
            Docker Compose 可以轻松管理这些服务之间的依赖关系
        b.简化开发环境
            通过一个命令(docker-compose up),你可以启动整个应用栈,而不需要手动启动每个容器
        c.环境一致性
            Docker Compose 确保开发、测试和生产环境的一致性,避免了“在我机器上能运行”的问题
    c.配置
        version:指定 Docker Compose 文件的版本
        services:定义各个服务(容器)
        build:指定 Dockerfile 路径来构建镜像
        image:使用现成的镜像
        ports:映射主机端口到容器端口
        volumes:挂载数据卷
        depends_on:定义服务之间的依赖关系
    d.示例
        version: '3'
        services:
          web:
            build: .
            ports:
              - "5000:5000"
          redis:
            image: "redis:alpine"
        -----------------------------------------------------------------------------------------------------
        web:使用当前目录下的 Dockerfile 构建镜像,并将主机的 5000 端口映射到容器的 5000 端口
        redis:直接使用官方的 Redis 镜像。
    e.启动
        docker-compose up --build -d

02.基本步骤
    a.顶层关键字
        version: "3.8"                                                          --(可选)指定 Compose 文件格式版本
        services:                                                               --定义所有服务(容器)的根键
        networks:                                                               --定义自定义网络的根键
        volumes:                                                                --定义命名卷的根键
    b.services 服务内常用配置
        image: myapp:latest                                                     --使用指定的镜像
        build: .                                                                --使用当前目录的 Dockerfile 构建镜像
        container_name: my-webapp                                               --指定容器名称
        command: "bundle exec thin -p 3000"                                     --覆盖镜像的默认 CMD
        entrypoint: ["/docker-entrypoint.sh"]                                   --覆盖镜像的默认 ENTRYPOINT
        ports:                                                                  --端口映射 "主机端口:容器端口"
          - "8080:80"
        volumes:                                                                --卷挂载 "主机路径:容器路径" 或 "命名卷:容器路径"
          - ./data:/app/data
          - db-data:/var/lib/mysql
        environment:                                                            --设置环境变量
          - RACK_ENV=development
        env_file:                                                               --从文件加载环境变量
          - .env
        depends_on:                                                             --定义服务依赖关系(控制启动顺序)
          - redis
        restart: always                                                         --重启策略: no | always | on-failure | unless-stopped
        networks:                                                               --将服务连接到指定网络
          - my-net
        healthcheck:                                                            --定义服务健康检查
          test: ["CMD", "curl", "-f", "http://localhost"]
    c.docker-compose CLI 常用命令
        docker-compose up                                                       --创建并启动所有服务
        docker-compose up -d                                                    --在后台创建并启动所有服务
        docker-compose up --build                                               --在启动前强制重新构建镜像
        docker-compose down                                                     --停止并移除所有服务、网络
        docker-compose down -v                                                  --同时移除定义的命名卷【慎重】
        -----------------------------------------------------------------------------------------------------
        docker-compose ps                                                       --查看所有服务的状态
        docker-compose logs                                                     --查看所有服务的日志
        docker-compose logs -f                                                  --持续跟踪(follow)日志输出
        docker-compose config                                                   --验证并查看最终的配置信息
        -----------------------------------------------------------------------------------------------------
        docker-compose start                                                    --启动已存在的服务
        docker-compose stop                                                     --停止正在运行的服务
        docker-compose restart                                                  --重启服务
        docker-compose rm                                                       --删除已停止的服务容器
        -----------------------------------------------------------------------------------------------------
        docker-compose build                                                    --构建或重新构建所有服务的镜像
        docker-compose pull                                                     --拉取所有服务所需的镜像
        docker-compose exec <service_name> /bin/bash                            --进入指定服务容器并执行命令
        docker-compose run --rm <service_name> /bin/ls                          --在指定服务上运行一个一次性命令

03.SpringBoot3与Docker-Compose整合
    a.说明
        SpringBoot3整合Docker-Compose的主要优势在于约定大于配置。
        使用Docker-Compose时,配置可以被SpringBoot3自动发现,从而减少手动配置。
        例如,常见的MySQL、Redis等服务的配置可以省略,SpringBoot3会自动处理。
    b.添加依赖
        a.SpringBoot3依赖
            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>3.3.4</version>
                <relativePath/> <!-- lookup parent from repository -->
            </parent>
        b.Docker-Compose依赖
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-docker-compose</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
        c.MySQL依赖
            <dependency>
                <groupId>com.mysql</groupId>
                <artifactId>mysql-connector-j</artifactId>
                <scope>runtime</scope>
            </dependency>
        d.Redis依赖
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    c.Compose推荐配置
        a.配置说明
            在使用Docker-Compose时,注意skip需要在start_only模式下才能正常执行。
            在start_and_stop模式下,应用启动后会启动容器,然后关闭容器,skip参数将无效。
        b.示例配置
            spring:
              docker:
                compose:
                  profiles:
                    active: dev # 指定当前运行环境
                  enabled: true # 开启compose
                  start:
                    skip: if_running  # 如果容器在运行就不再去再启动了
                  lifecycle-management: start_only # 这个参数不会在停机后关闭容器
            services:
              mysql:
                image: 'mysql:latest'
                restart: always
                environment:
                  - MYSQL_DATABASE=root
                  - MYSQL_ROOT_PASSWORD=123456
                ports:
                  - '3306:3306'
                profiles:
                  - dev
                labels:
                  org.springframework.boot.jdbc.parameters: useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8&useSSL=false
              redis:
                image: 'redis:latest'
                restart: always
                environment:
                  - 'REDIS_PASSWORD=redis'
                ports:
                  - '6379:6379'
                profiles:
                  - dev

04.Docker-Compose生命周期管理
    a.管理器介绍
        org.springframework.boot.docker.compose.lifecycle.DockerComposeLifecycleManager
        负责整合后的Compose生命周期管理,包括容器创建、启动、停止,以及配置自动发现
    b.配置自动发现
        在容器启动完成后,会发布DockerComposeServicesReadyEvent事件。
        DockerComposeServiceConnectionsApplicationListener监听到该事件后开始注册配置。
        -----------------------------------------------------------------------------------------------------
        private void registerConnectionDetails(BeanDefinitionRegistry registry, List<RunningService> runningServices) {
            for (RunningService runningService : runningServices) {
                DockerComposeConnectionSource source = new DockerComposeConnectionSource(runningService);
                this.factories.getConnectionDetails(source, false).forEach((connectionDetailsType, connectionDetails) -> {
                    register(registry, runningService, connectionDetailsType, connectionDetails);
                    this.factories.getConnectionDetails(connectionDetails, false)
                        .forEach((adaptedType, adaptedDetails) -> register(registry, runningService, adaptedType,
                                adaptedDetails));
                });
            }
        }
    c.注意事项
        skip需要搭配lifecycle-management使用。
        常规的environment参数由SpringBoot自动发现,一些特殊参数(如MySQL连接参数)可以放到labels下,
        格式类似于org.springframework.boot.jdbc.parameters。

2.7 [2]dockerfile

00.图示
    特性          Dockerfile                 Docker Compose
    用途          构建单个容器               镜像编排多容器应用
    文件格式      文本文件,包含指令          YAML文件,定义服务、网络和卷
    使用场景      创建自定义镜像              管理多容器应用(如Web+DB+Cache)
    核心命令      docker build               docker-compose up
    依赖关系      无                         可以定义服务之间的依赖关系
    典型使用      构建镜像                   启动、停止和管理多容器应用

01.简单说明
    a.定义
        Dockerfile 是一个文本文件,包含了一系列指令,用于定义如何构建一个 Docker 镜像
        你可以把它想象成一个“菜谱”,告诉 Docker 如何从零开始制作一个容器镜像
        比如,选择基础镜像、安装依赖、复制文件、设置环境变量等
    b.作用
        a.构建镜像
            Dockerfile 是构建 Docker 镜像的基础
            通过 docker build 命令,Docker 会按照 Dockerfile 中的指令一步步生成镜像
        b.定制化环境
            你可以基于官方镜像(如 Ubuntu、Python、Node.js)进行扩展
            添加自己的应用代码和配置,从而创建一个完全符合需求的镜像
    c.指令
        FROM:指定基础镜像
        RUN:执行命令,比如安装软件包
        COPY:将本地文件复制到镜像中
        WORKDIR:设置工作目录
        EXPOSE:声明容器运行时监听的端口
        CMD:指定容器启动时运行的命令
    d.示例
        # 使用官方 Python 镜像作为基础
        FROM python:3.8-slim

        # 设置工作目录
        WORKDIR /app

        # 复制依赖文件
        COPY requirements.txt .

        # 安装依赖
        RUN pip install -r requirements.txt

        # 复制应用代码
        COPY . .

        # 暴露端口
        EXPOSE 5000

        # 运行应用
        CMD ["python", "app.py"]

02.基本步骤
    a.第一步:编写 Dockerfile
        # 使用官方的 Node.js 18 轻量级镜像作为基础
        FROM node:18-alpine
        # 在镜像内创建 /app 目录作为工作区
        WORKDIR /app
        # 复制 package.json 等依赖描述文件,并安装依赖
        # 这样做可以利用 Docker 缓存,如果依赖没变,无需重复安装
        COPY package*.json ./
        RUN npm install
        # 将项目所有文件复制到工作区
        COPY . .
        # 声明容器将暴露 3000 端口
        EXPOSE 3000
        # 定义容器启动时执行的默认命令
        CMD [ "node", "server.js" ]
        -----------------------------------------------------------------------------------------------------
        基础与元数据
        FROM ubuntu:20.04                                                       --指定基础镜像
        LABEL maintainer="Your Name <[email protected]>"                    --为镜像添加元数据(作者、描述等)
        -----------------------------------------------------------------------------------------------------
        文件与工作目录
        WORKDIR /app                                                            --指定后续命令的工作目录
        COPY . .                                                                --将构建上下文中的文件/目录复制到镜像中(推荐)
        ADD package.tar.gz /tmp                                                 --复制文件,可自动解压压缩包或下载URL文件
        -----------------------------------------------------------------------------------------------------
        构建时执行命令
        RUN apt-get update && apt-get install -y vim                            --构建镜像时执行命令,如安装软件
        RUN ["/bin/bash", "-c", "echo hello"]                                   --RUN指令的Exec格式
        -----------------------------------------------------------------------------------------------------
        容器运行时配置
        CMD ["node", "app.js"]                                                  --容器启动时默认执行的命令(可被覆盖)
        ENTRYPOINT ["java", "-jar", "app.jar"]                                  --容器启动时执行的命令(不会被覆盖,而是追加参数)
        EXPOSE 8080                                                             --声明容器计划暴露的端口(文档作用)
        ENV APP_VERSION=1.0                                                     --设置环境变量
        ARG BUILD_VERSION=1.0                                                   --设置构建时变量(仅build时有效)
        VOLUME ["/data"]                                                        --创建一个匿名卷挂载点,用于持久化数据
        USER node                                                               --指定运行后续命令和容器的用户
        HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/    --定义容器健康检查
        ONBUILD COPY . /app/src                                                 --当此镜像作为基础镜像时,在其下游镜像构建时执行
    b.第二步:构建镜像
        # 在 Dockerfile 所在目录执行
        docker build -t my-nodejs-app:1.0 .
        -----------------------------------------------------------------------------------------------------
        build: 构建命令。
        -t my-nodejs-app:1.0: 为镜像打上一个易于识别的标签(名称:版本)。
        .: 指示 Docker 使用当前目录作为构建上下文(包括 Dockerfile 和应用代码)。
    c.第三步:运行容器
        docker run -d -p 8080:3000 --name my-app-instance my-nodejs-app:1.0
        -----------------------------------------------------------------------------------------------------
        run: 运行命令。
        -d: 在后台(detached)模式下运行容器。
        -p 8080:3000: 将主机的 8080 端口映射到容器的 3000 端口。
        --name my-app-instance: 为这个运行的容器起一个名字。
        my-nodejs-app:1.0: 指定要使用的镜像。

03.发布流程
    a.构建Docker镜像
        a.编写Dockerfile
            # 使用官方的OpenJDK 8基础镜像
            FROM openjdk:8-jdk
            # 设置工作目录
            WORKDIR /app
            # 将当前目录的内容复制到容器的/app目录
            COPY . /app
            # 暴露应用程序运行的端口(如果需要)
            # EXPOSE 8080
            # 设置默认命令(如果需要)
            # CMD ["java", "-jar", "your-application.jar"]
        b.构建
            docker build -t your-repo/your-image-name:your-tag .
            --your-repo/your-image-name:your-tag 是你为镜像指定的名称和标签
            --. 表示Dockerfile所在的当前目录
    b.推送镜像到Docker私有仓库
        a.登录到私有仓库
            docker login your-private-registry.com
        b.给镜像打标签以匹配私有仓库
            docker tag your-repo/your-image-name:your-tag your-private-registry.com/your-repo/your-image-name:your-tag
        c.推送镜像到私有仓库
            docker push your-private-registry.com/your-repo/your-image-name:your-tag
    c.启动自定义镜像
        a.拉取镜像
            docker pull your-private-registry.com/your-repo/your-image-name:your-tag
        b.启动容器
            docker run -d --name your-container-name your-private-registry.com/your-repo/your-image-name:your-tag

2.8 [3]dockge

01.官方
    a.地址
        https://github.com/louislam/dockge
        https://github.com/TWO-ICE/Awesome-NAS-Docker
    b.要求
        Docker版本>=20或使用Podman
        支持的操作系统包括:Ubuntu/Debian/Raspbian/CentOS/Fedora/ArchLinux
        支持的架构包括:armv7, arm64, amd64
    c.安装
        # Create directories that store your stacks and stores Dockge's stack
        mkdir /opt/homebrew/Cellar/dockge
        mkdir /opt/homebrew/Cellar/dockge/data
        mkdir /opt/homebrew/Cellar/dockge/stacks
        cd /opt/homebrew/Cellar/dockge

        # Download the compose.yaml
        curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml

        # Start the server
        docker compose up -d
    d.compose.yaml
        services:
          dockge:
            image: louislam/dockge:1
            restart: unless-stopped
            ports:
              # Host Port : Container Port
              - 5001:5001
            volumes:
              - /var/run/docker.sock:/var/run/docker.sock
              - ./data:/app/data

              # If you want to use private registries, you need to share the auth file with Dockge:
              # - /root/.docker/:/root/.docker

              # Stacks Directory
              # ⚠️ READ IT CAREFULLY. If you did it wrong, your data could end up writing into a WRONG PATH.
              # ⚠️ 1. FULL path only. No relative path (MUST)
              # ⚠️ 2. Left Stacks Path === Right Stacks Path (MUST)
              - /opt/homebrew/Cellar/dockge/stacks:/opt/stacks
            environment:
              # Tell Dockge where is your stacks directory
              - DOCKGE_STACKS_DIR=/opt/homebrew/Cellar/dockge/stacks
    e.访问
        http://127.0.0.1:5001
        admin
        dljxxxxxxx

02.部署
    a.地址
        https://github.com/SillyTavern/SillyTavern
    b.操作
        打开Dockge面板 -> 创建堆栈 -> 设置堆栈名称 -> 粘贴compose代码 -> 30秒启动成功!
    c.compose
        version: "3"
        services:
          sillytavern:
            image: ghcr.io/sillytavern/sillytavern:latest
            container_name: sillytavern
            restart: unless-stopped
            ports:
              - "8730:8000"
            volumes:
              - "./config:/home/node/app/config"
              - "./data:/home/node/app/data"
              - "./plugins:/home/node/app/plugins"
              - "./extensions:/home/node/app/public/scripts/extensions/third-party"
    d.访问
        http://127.0.0.1:8730

2.9 [3]portainer

01.官方
    a.镜像
        docker search portainer
        docker pull portainer/portainer
    b.本机模式
        docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock --restart=always --name prtainer portainer/portainer
    c.远程模式
        docker run -d -p 9000:9000 --restart=always --name prtainer portainer/portainer
    d.运行
        docker start 80576e5ea74a                                               --启动容器
        docker stop 80576e5ea74a                                                --停止容器
        docker restart 80576e5ea74a                                             --重启容器
        docker rm 80576e5ea74a                                                  --移除容器
        docker logs 80576e5ea74a                                                --查看日志
        docker exec -it portainer /bin/bash                                     --进入容器
        http://127.0.0.1:9000                                                   --测试(admin,12345678)

02.汉化
    a.镜像
        docker search portainer
        docker pull 6053537/portainer-ce
    b.x86一键安装
        docker run -d --restart=always --name="portainer" -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data 6053537/portainer-ce
    c.x86一键更新
        sh -c "$(curl -kfsSl https://gitee.com/expin/public/raw/master/onex86.sh)"
    d.运行
        docker start 80576e5ea74a                                               --启动容器
        docker stop 80576e5ea74a                                                --停止容器
        docker restart 80576e5ea74a                                             --重启容器
        docker rm 80576e5ea74a                                                  --移除容器
        docker logs 80576e5ea74a                                                --查看日志
        docker exec -it portainer /bin/bash                                     --进入容器
        http://127.0.0.1:9000                                                   --测试(admin,12345678)
    e.设置容器开机自启动
        a.开启
            docker update --restart=always portainer
        b.关闭
            docker update --restart=no portainer

3 kubernetes

3.1 [1]basic

01.介绍
    a.什么是Kubernetes
        a.定义
            Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序
            名字来源于希腊语,意为"舵手"或"领航员",K8s中的8代表中间的8个字母ubernete
            由Google于2014年开源,基于其内部使用15年以上的Borg系统经验开发
            现由Cloud Native Computing Foundation(CNCF)维护
        b.核心功能
            服务发现和负载均衡:K8s可以使用DNS名称或IP地址暴露容器,并在流量较高时进行负载均衡
            存储编排:自动挂载存储系统,包括本地存储、公共云提供商等
            自动部署和回滚:描述已部署容器的所需状态,K8s会以受控速率更改实际状态
            自动装箱:提供一个节点集群运行容器化任务,告诉K8s每个容器需要多少CPU和内存
            自我修复:重新启动失败的容器、替换容器、杀死不响应健康检查的容器
            密钥和配置管理:存储和管理敏感信息,无需重新构建镜像即可部署和更新密钥
    b.为什么需要Kubernetes
        a.容器编排的必要性
            单机Docker:适合开发测试,生产环境需要多主机管理
            容器数量激增:微服务架构下,一个应用可能包含数十个容器
            高可用需求:容器故障后需要自动重启和迁移
            弹性伸缩:根据负载自动调整容器数量
            服务发现:容器IP动态变化,需要统一的服务发现机制
        b.K8s与Docker对比
            Docker:解决了"如何打包和运行应用"的问题
            K8s:解决了"如何管理大规模容器集群"的问题
            关系:K8s使用Docker(或containerd、CRI-O等)作为容器运行时
        c.K8s与其他编排工具对比
            Docker Swarm                                简单易用,但功能相对简单
                                                        适合小规模集群
                                                        与Docker原生集成
            Kubernetes                                  功能强大,生态丰富
                                                        适合大规模生产环境
                                                        社区活跃,已成为事实标准
            Apache Mesos                                通用资源调度框架
                                                        支持容器和非容器工作负载
                                                        学习曲线陡峭
    c.Kubernetes架构
        a.集群架构
            Kubernetes集群由Master节点(控制平面)和Worker节点(工作节点)组成
            Master节点负责管理整个集群,Worker节点负责运行实际的应用容器
            -------------------------------------------------------------------------------------------------
            Master节点组件:
                API Server:集群的统一入口,提供RESTful API
                etcd:分布式键值存储,保存集群所有数据
                Scheduler:负责资源调度,将Pod分配到合适的节点
                Controller Manager:运行控制器进程,如节点控制器、副本控制器等
                Cloud Controller Manager:与云提供商交互的控制器
            -------------------------------------------------------------------------------------------------
            Worker节点组件:
                kubelet:运行在每个节点上的代理,负责维护容器的生命周期
                kube-proxy:维护节点上的网络规则,实现服务的负载均衡
                Container Runtime:容器运行时(Docker、containerd、CRI-O等)
        b.工作流程
            用户通过kubectl或API提交应用部署请求
            API Server接收请求并存储到etcd
            Scheduler监听API Server,发现未调度的Pod,选择合适的节点
            kubelet监听API Server,发现调度到本节点的Pod,调用容器运行时创建容器
            kube-proxy配置网络规则,实现服务的负载均衡
            Controller Manager持续监控集群状态,确保实际状态与期望状态一致
        c.架构图示
            +---------------------+
            |    kubectl/API      |
            +----------+----------+
                       |
            +----------v----------+
            |    API Server       |
            +----------+----------+
                       |
            +----------v----------+
            |       etcd          |
            +---------------------+

            +---------------------+     +---------------------+
            |    Scheduler        |     | Controller Manager  |
            +---------------------+     +---------------------+

            +--------------------------------------------------+
            |              Worker Node 1                       |
            |  +----------+  +----------+  +----------+        |
            |  | kubelet  |  |kube-proxy|  |Container |        |
            |  +----------+  +----------+  | Runtime  |        |
            |                              +----------+        |
            |  +--------------------------------------+        |
            |  |           Pods                       |        |
            |  +--------------------------------------+        |
            +--------------------------------------------------+

02.核心概念
    a.Pod
        a.定义
            Pod是K8s中最小的部署单元,不是容器本身
            一个Pod可以包含一个或多个容器,这些容器共享网络和存储
            Pod中的容器共享同一个IP地址和端口空间
            同一Pod中的容器可以通过localhost互相访问
        b.为什么需要Pod
            原因1:容器之间需要紧密协作(如应用容器+日志收集容器)
            原因2:容器之间需要共享数据(通过Volume)
            原因3:容器之间需要共享网络(通过Pod IP)
        c.Pod的生命周期
            Pending:Pod已被K8s接受,但容器镜像尚未创建
            Running:Pod已绑定到节点,所有容器都已创建,至少一个容器正在运行
            Succeeded:Pod中所有容器都成功终止,不会重启
            Failed:Pod中所有容器都已终止,至少一个容器失败
            Unknown:无法获取Pod状态,通常是节点通信问题
        d.示例
            apiVersion: v1
            kind: Pod
            metadata:
              name: nginx-pod
              labels:
                app: nginx
            spec:
              containers:
              - name: nginx
                image: nginx:1.21
                ports:
                - containerPort: 80
    b.Deployment
        a.定义
            Deployment为Pod和ReplicaSet提供声明式更新
            用于管理无状态应用,是最常用的工作负载资源
            提供滚动更新、回滚、扩缩容等功能
        b.核心功能
            副本管理:确保指定数量的Pod副本始终运行
            滚动更新:逐步替换旧版本Pod,实现零停机更新
            版本回滚:记录更新历史,支持快速回滚到之前版本
            扩缩容:手动或自动调整Pod副本数量
        c.工作原理
            Deployment创建ReplicaSet
            ReplicaSet创建和管理Pod
            更新Deployment时,创建新的ReplicaSet,逐步扩容新RS,缩容旧RS
        d.示例
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment
            spec:
              replicas: 3                                                    --副本数量
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.21
                    ports:
                    - containerPort: 80
    c.Service
        a.定义
            Service是一种抽象,定义了一组Pod的访问策略
            为动态变化的Pod提供稳定的网络访问入口
            通过Label Selector选择后端Pod
        b.为什么需要Service
            问题1:Pod IP会动态变化(Pod重启后IP改变)
            问题2:多个Pod副本需要负载均衡
            问题3:需要统一的服务发现机制
            解决:Service提供固定的ClusterIP,自动负载均衡到后端Pod
        c.Service类型
            ClusterIP(默认)                          分配集群内部IP,仅集群内部可访问
                                                        用于集群内部服务间通信
            NodePort                                    在每个节点上开放端口,集群外部可通过<NodeIP>:<NodePort>访问
                                                        端口范围:30000-32767
            LoadBalancer                                创建外部负载均衡器(需要云提供商支持)
                                                        自动分配外部IP
            ExternalName                                将服务映射到外部DNS名称
                                                        返回CNAME记录
        d.示例
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-service
            spec:
              type: ClusterIP                                                --服务类型
              selector:
                app: nginx                                                   --选择标签为app=nginx的Pod
              ports:
              - protocol: TCP
                port: 80                                                     --Service端口
                targetPort: 80                                               --Pod端口
    d.Namespace
        a.定义
            Namespace是K8s中的虚拟集群,用于资源隔离
            一个物理集群可以划分为多个虚拟集群(Namespace)
            不同Namespace中的资源名称可以相同
        b.默认Namespace
            default                                     默认命名空间,未指定Namespace的资源创建在此
            kube-system                                 K8s系统组件使用的命名空间
            kube-public                                 所有用户可读的命名空间,通常用于集群信息
            kube-node-lease                             节点心跳信息的命名空间(K8s 1.13+)
        c.使用场景
            场景1:多租户隔离(开发、测试、生产环境)
            场景2:资源配额管理(限制每个团队的资源使用)
            场景3:访问控制(不同团队有不同权限)
        d.示例
            apiVersion: v1
            kind: Namespace
            metadata:
              name: dev
            -------------------------------------------------------------------------------------------------
            kubectl create namespace dev                                     --创建Namespace
            kubectl get namespaces                                           --查看Namespace
            kubectl get pods -n dev                                          --查看指定Namespace的Pod
    e.Volume(数据卷)
        a.定义
            Volume是Pod中能够被多个容器访问的共享目录
            解决容器数据持久化和容器间数据共享问题
            Volume的生命周期与Pod相同
        b.Volume类型
            emptyDir                                    临时目录,Pod删除时数据也删除
                                                        用于临时存储,如缓���、临时文件
            hostPath                                    挂载主机目录到Pod
                                                        用于访问宿主机文件系统
            nfs                                         挂载NFS网络文件系统
                                                        用于跨节点共享数据
            persistentVolumeClaim                       使用PVC挂载PV
                                                        用于持久化存储
            configMap                                   挂载ConfigMap作为文件
                                                        用于配置文件注入
            secret                                      挂载Secret作为文件
                                                        用于敏感信息注入
        c.示例(emptyDir)
            apiVersion: v1
            kind: Pod
            metadata:
              name: test-pod
            spec:
              containers:
              - name: app
                image: nginx
                volumeMounts:
                - name: cache-volume
                  mountPath: /cache
              volumes:
              - name: cache-volume
                emptyDir: {}                                                 --临时卷
        d.示例(hostPath)
            apiVersion: v1
            kind: Pod
            metadata:
              name: test-pod
            spec:
              containers:
              - name: app
                image: nginx
                volumeMounts:
                - name: host-volume
                  mountPath: /data
              volumes:
              - name: host-volume
                hostPath:
                  path: /opt/data                                            --宿主机路径
                  type: DirectoryOrCreate

03.核心组件详解
    a.API Server
        a.功能
            提供RESTful API,是集群的统一入口
            处理所有对集群资源的CRUD操作
            认证、授权、准入控制
            与etcd交互,实现资源的持久化
        b.工作流程
            客户端发送请求(kubectl、客户端库等)
            认证:验证用户身份(证书、Token、ServiceAccount等)
            授权:检查用户是否有权限执行操作(RBAC、ABAC等)
            准入控制:执行准入控制器(Mutating、Validating)
            数据持久化:将资源存储到etcd
            返回响应
        c.访问方式
            kubectl                                     命令行工具,最常用
            REST API                                    直接调用HTTP API
            客户端库                                     各语言SDK(Go、Python、Java等)
            kubectl proxy                               本地代理,简化API访问
    b.etcd
        a.功能
            分布式键值存储,保存集群所有配置和状态数据
            使用Raft协议保证数据一致性
            支持Watch机制,实时监听数据变化
        b.存储内容
            所有K8s资源对象:Pod、Service、ConfigMap等
            集群配置信息
            集群状态信息
        c.高可用
            建议部署奇数个节点(3、5、7)
            超过半数节点存活即可提供服务
            定期备份etcd数据
        d.常用命令
            etcdctl member list                                              --查看集群成员
            etcdctl endpoint status                                          --查看状态
            etcdctl snapshot save snapshot.db                                --备份
            etcdctl snapshot restore snapshot.db                             --恢复
    c.Scheduler
        a.功能
            监听API Server,发现未调度的Pod
            根据调度算法为Pod选择最合适的节点
            将调度结果写回API Server
        b.调度过程
            预选(Filtering):过滤掉不满足条件的节点
                资源是否充足(CPU、内存)
                节点是否就绪
                Pod亲和性/反亲和性
                污点和容忍度
            优选(Scoring):对预选节点打分,选择最优节点
                资源平衡
                亲和性优先
                最少请求数优先
        c.调度策略
            nodeSelector                                通过标签选择节点
            nodeAffinity                                节点亲和性,支持硬性/软性要求
            podAffinity                                 Pod亲和性,Pod倾向于调度在一起
            podAntiAffinity                             Pod反亲和性,Pod倾向于分散调度
            taints and tolerations                      污点和容忍度,防止Pod调度到特定节点
    d.Controller Manager
        a.功能
            运行各种控制器,确保集群实际状态与期望状态一致
            每个控制器是一个独立的进程,但为了降低复杂性,编译到同一个二进制文件
            通过API Server监听资源变化,执行相应操作
        b.常见控制器
            Node Controller                             监控节点状态,处理节点故障
            Replication Controller                      维护指定数量的Pod副本
            Endpoints Controller                        维护Service和Pod的对应关系
            ServiceAccount Controller                   为Namespace创建默认ServiceAccount
            Deployment Controller                       管理Deployment和ReplicaSet
            StatefulSet Controller                      管理有状态应用
            DaemonSet Controller                        确保每个节点运行指定Pod
            Job Controller                              管理一次性任务
            CronJob Controller                          管理定时任务
        c.工作机制
            控制器通过List-Watch机制监听资源变化
            发现实际状态与期望状态不一致时,执行调谐操作
            调谐是持续进行的,确保集群始终处于期望状态
    e.kubelet
        a.功能
            运行在每个Worker节点上的代理
            负责维护容器的生命周期
            接收PodSpec,确保容器按照PodSpec运行
            定期向API Server报告节点和Pod状态
        b.主要职责
            Pod管理:创建、启动、停止、删除容器
            容器健康检查:执行Liveness、Readiness、Startup探针
            资源监控:监控节点和容器资源使用情况
            Volume管理:挂载和卸载Volume
            镜像管理:拉取容器镜像
        c.工作流程
            监听API Server,获取调度到本节点的Pod
            调用容器运行时(CRI)创建容器
            执行健康检查,不健康时重启容器
            定期上报节点和Pod状态
    f.kube-proxy
        a.功能
            运行在每个节点上,维护网络规则
            实现Service的负载均衡
            支持三种代理模式:userspace、iptables、ipvs
        b.代理模式
            userspace模式                               K8s早期版本,性能较差,已废弃
                                                        kube-proxy在用户空间监听端口,转发流量
            iptables模式                                默认模式,性能较好
                                                        使用iptables规则实现负载均衡
                                                        随机选择后端Pod
            ipvs模式                                    高性能模式,支持更多负载均衡算法
                                                        支持rr、lc、dh、sh、sed、nq等算法
                                                        需要加载ipvs内核模块
        c.工作原理
            监听API Server,获取Service和Endpoints变化
            根据Service配置,创建或更新iptables/ipvs规则
            客户端访问Service时,通过规则转发到后端Pod

04.常见术语
    a.Label(标签)
        a.定义
            Label是附加到K8s资源对象上的键值对
            用于标识和选择资源对象
            一个对象可以有多个Label
        b.使用场景
            环境标识:env=prod、env=dev
            版本标识:version=v1.0、version=v2.0
            应用标识:app=nginx、app=redis
            团队标识:team=frontend、team=backend
        c.Label Selector
            等式选择器:env=prod(选择env为prod的资源)
            集合选择器:env in (prod,dev)(选择env为prod或dev的资源)
        d.示例
            metadata:
              labels:
                app: nginx
                env: prod
                version: v1.0
    b.Annotation(注解)
        a.定义
            Annotation也是键值对,但不用于标识和选择资源
            用于存储非标识性的元数据
            可以存储更长的、非结构化的数据
        b.使用场景
            构建信息:build_id、git_commit
            负责人信息:maintainer、contact
            工具信息:ingress配置、监控配置
        c.示例
            metadata:
              annotations:
                kubernetes.io/change-cause: "Update to version 1.21"
                maintainer: "[email protected]"
    c.ConfigMap
        a.定义
            ConfigMap用于存储非敏感的配置数据
            以键值对形式存储
            可以作为环境变量、命令行参数或配置文件使用
        b.使用方式
            环境变量注入
            命令行参数注入
            Volume挂载为文件
        c.示例
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: app-config
            data:
              app.properties: |
                server.port=8080
                log.level=INFO
              database.url: "mysql://localhost:3306/mydb"
    d.Secret
        a.定义
            Secret用于存储敏感信息,如密码、Token、密钥
            数据以Base64编码存储(不是加密)
            使用方式与ConfigMap类似
        b.Secret类型
            Opaque                                      默认类型,用于存储任意数据
            kubernetes.io/service-account-token         ServiceAccount Token
            kubernetes.io/dockerconfigjson              Docker镜像仓库认证信息
            kubernetes.io/tls                           TLS证书和密钥
        c.示例
            apiVersion: v1
            kind: Secret
            metadata:
              name: db-secret
            type: Opaque
            data:
              username: YWRtaW4=                                              --admin的Base64编码
              password: MWYyZDFlMmU2N2Rm                                      --密码的Base64编码
    e.Ingress
        a.定义
            Ingress是集群外部访问集群内部服务的HTTP/HTTPS路由规则
            提供负载均衡、SSL终止、基于名称的虚拟主机
            需要Ingress Controller才能工作(如Nginx Ingress、Traefik等)
        b.功能
            域名路由:不同域名路由到不同Service
            路径路由:同一域名不同路径路由到不同Service
            TLS/SSL:配置HTTPS证书
            负载均衡:多个Pod间负载均衡
        c.示例
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: example-ingress
            spec:
              rules:
              - host: example.com
                http:
                  paths:
                  - path: /app1
                    pathType: Prefix
                    backend:
                      service:
                        name: app1-service
                        port:
                          number: 80
                  - path: /app2
                    pathType: Prefix
                    backend:
                      service:
                        name: app2-service
                        port:
                          number: 80
    f.Helm
        a.定义
            Helm是K8s的包管理工具,类似于yum、apt
            简化K8s应用的部署和管理
            使用Chart打包K8s资源
        b.核心概念
            Chart                                       Helm包,包含运行应用所需的所有资源定义
            Release                                     Chart的运行实例
            Repository                                  存储和分享Chart的仓库
        c.基本命令
            helm search                                 搜索Chart
            helm install                                安装Chart
            helm upgrade                                升级Release
            helm rollback                               回滚Release
            helm uninstall                              卸载Release

3.2 [1]install

01.环境准备
    a.系统要求
        a.操作系统
            Ubuntu 20.04/22.04 LTS
            CentOS 7.9+/8.x
            Debian 10/11
            RHEL 7.9+/8.x
        b.硬件要求
            Master节点                                  最低:2核CPU、2GB内存、20GB硬盘
                                                        推荐:4核CPU、8GB内存、50GB硬盘
            Worker节点                                  最低:2核CPU、2GB内存、30GB硬盘
                                                        推荐:4核CPU、16GB内存、100GB硬盘
        c.网络要求
            所有节点网络互通
            所有节点能访问外网(拉取镜像)
            关闭防火墙或开放必要端口
            确保MAC地址和product_uuid唯一
    b.版本选择
        a.K8s版本
            稳定版                                      选择最新的稳定版本(如1.28.x)
            LTS版本                                     长期支持版本(如1.27.x)
            测试版                                      不推荐生产环境使用
        b.容器运行时
            containerd                                  推荐,CNCF项目,性能好
            CRI-O                                       RedHat维护,OCI标准
            Docker(通过cri-dockerd)                   需要额外适配器,不推荐
        c.版本兼容性
            K8s 1.24+版本移除了对dockershim的支持
            如果使用Docker,需要安装cri-dockerd
            建议直接使用containerd或CRI-O
    c.端口要求
        a.Master节点端口
            6443                                        Kubernetes API Server
            2379-2380                                   etcd server client API
            10250                                       Kubelet API
            10259                                       kube-scheduler
            10257                                       kube-controller-manager
        b.Worker节点端口
            10250                                       Kubelet API
            30000-32767                                 NodePort Services

02.kubeadm安装(推荐)
    a.准备工作(所有节点)
        a.关闭swap
            swapoff -a                                                           --临时关闭
            sed -ri 's/.*swap.*/#&/' /etc/fstab                                  --永久关闭
            free -h                                                              --验证
        b.关闭防火墙
            systemctl stop firewalld                                             --CentOS/RHEL
            systemctl disable firewalld
            -------------------------------------------------------------------------------------------------
            ufw disable                                                          --Ubuntu/Debian
        c.关闭SELinux
            setenforce 0                                                         --临时关闭
            sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config --永久关闭
        d.配置内核参数
            cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
            overlay
            br_netfilter
            EOF
            -------------------------------------------------------------------------------------------------
            modprobe overlay                                                     --加载模块
            modprobe br_netfilter
            -------------------------------------------------------------------------------------------------
            cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
            net.bridge.bridge-nf-call-iptables  = 1
            net.bridge.bridge-nf-call-ip6tables = 1
            net.ipv4.ip_forward                 = 1
            EOF
            -------------------------------------------------------------------------------------------------
            sysctl --system                                                      --应用配置
        e.配置主机名和hosts
            hostnamectl set-hostname k8s-master                                  --设置主机名
            -------------------------------------------------------------------------------------------------
            cat >> /etc/hosts << EOF
            192.168.1.10 k8s-master
            192.168.1.11 k8s-node1
            192.168.1.12 k8s-node2
            EOF
    b.安装容器运行时(containerd)
        a.安装containerd(Ubuntu/Debian)
            apt-get update
            apt-get install -y containerd
            -------------------------------------------------------------------------------------------------
            mkdir -p /etc/containerd
            containerd config default | tee /etc/containerd/config.toml
            -------------------------------------------------------------------------------------------------
            sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
            sed -i 's#registry.k8s.io/pause:3.6#registry.aliyuncs.com/google_containers/pause:3.9#' /etc/containerd/config.toml
            -------------------------------------------------------------------------------------------------
            systemctl restart containerd
            systemctl enable containerd
            systemctl status containerd                                          --验证
        b.安装containerd(CentOS/RHEL)
            yum install -y yum-utils
            yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
            yum install -y containerd.io
            -------------------------------------------------------------------------------------------------
            mkdir -p /etc/containerd
            containerd config default | tee /etc/containerd/config.toml
            -------------------------------------------------------------------------------------------------
            sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
            sed -i 's#registry.k8s.io/pause:3.6#registry.aliyuncs.com/google_containers/pause:3.9#' /etc/containerd/config.toml
            -------------------------------------------------------------------------------------------------
            systemctl restart containerd
            systemctl enable containerd
            systemctl status containerd                                          --验证
        c.配置镜像加速
            vim /etc/containerd/config.toml
            -------------------------------------------------------------------------------------------------
            [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
              endpoint = ["https://docker.mirrors.ustc.edu.cn"]
            [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
              endpoint = ["https://registry.aliyuncs.com/google_containers"]
            -------------------------------------------------------------------------------------------------
            systemctl restart containerd
    c.安装kubeadm、kubelet、kubectl
        a.Ubuntu/Debian
            apt-get update
            apt-get install -y apt-transport-https ca-certificates curl
            -------------------------------------------------------------------------------------------------
            curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
            -------------------------------------------------------------------------------------------------
            cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
            deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
            EOF
            -------------------------------------------------------------------------------------------------
            apt-get update
            apt-get install -y kubelet kubeadm kubectl
            apt-mark hold kubelet kubeadm kubectl                                --锁定版本
            -------------------------------------------------------------------------------------------------
            systemctl enable kubelet
            systemctl start kubelet
        b.CentOS/RHEL
            cat <<EOF > /etc/yum.repos.d/kubernetes.repo
            [kubernetes]
            name=Kubernetes
            baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
            enabled=1
            gpgcheck=1
            repo_gpgcheck=1
            gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
            EOF
            -------------------------------------------------------------------------------------------------
            yum install -y kubelet kubeadm kubectl
            systemctl enable kubelet
            systemctl start kubelet
        c.验证安装
            kubeadm version                                                      --查看kubeadm版本
            kubelet --version                                                    --查看kubelet版本
            kubectl version --client                                             --查看kubectl版本
    d.初始化Master节点
        a.生成初始化配置
            kubeadm config print init-defaults > kubeadm-init.yaml
            -------------------------------------------------------------------------------------------------
            vim kubeadm-init.yaml
            修改以下内容:
            advertiseAddress: 192.168.1.10                                       --改为Master节点IP
            imageRepository: registry.aliyuncs.com/google_containers             --改为阿里云镜像
            kubernetesVersion: v1.28.0                                           --指定K8s版本
            networking:
              podSubnet: 10.244.0.0/16                                           --Pod网络CIDR
              serviceSubnet: 10.96.0.0/12                                        --Service网络CIDR
        b.预拉取镜像
            kubeadm config images pull --config kubeadm-init.yaml                --提前拉取镜像
            -------------------------------------------------------------------------------------------------
            或使用阿里云镜像:
            kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
        c.初始化集群
            kubeadm init \
              --apiserver-advertise-address=192.168.1.10 \
              --image-repository registry.aliyuncs.com/google_containers \
              --kubernetes-version v1.28.0 \
              --service-cidr=10.96.0.0/12 \
              --pod-network-cidr=10.244.0.0/16
            -------------------------------------------------------------------------------------------------
            初始化成功后,会输出类似信息:
            Your Kubernetes control-plane has initialized successfully!

            To start using your cluster, you need to run the following as a regular user:

              mkdir -p $HOME/.kube
              sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
              sudo chown $(id -u):$(id -g) $HOME/.kube/config

            Then you can join any number of worker nodes by running the following on each as root:

            kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef \
                --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        d.配置kubectl
            mkdir -p $HOME/.kube
            sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
            sudo chown $(id -u):$(id -g) $HOME/.kube/config
            -------------------------------------------------------------------------------------------------
            kubectl get nodes                                                    --验证
            NAME         STATUS     ROLES           AGE   VERSION
            k8s-master   NotReady   control-plane   1m    v1.28.0
            -------------------------------------------------------------------------------------------------
            注意:状态为NotReady是正常的,因为还未安装网络插件
    e.安装网络插件(Master节点)
        a.Flannel(推荐新手)
            kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
            -------------------------------------------------------------------------------------------------
            或使用国内镜像:
            wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
            sed -i 's#docker.io#docker.mirrors.ustc.edu.cn#g' kube-flannel.yml
            kubectl apply -f kube-flannel.yml
            -------------------------------------------------------------------------------------------------
            kubectl get pods -n kube-flannel                                     --验证
            kubectl get nodes                                                    --节点状态变为Ready
        b.Calico(推荐生产环境)
            kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
            -------------------------------------------------------------------------------------------------
            kubectl get pods -n kube-system | grep calico                        --验证
        c.Weave Net
            kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
            -------------------------------------------------------------------------------------------------
            kubectl get pods -n kube-system | grep weave                         --验证
    f.加入Worker节点
        a.获取join命令
            在Master节点执行:
            kubeadm token create --print-join-command                            --生成join命令
            -------------------------------------------------------------------------------------------------
            输出示例:
            kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef \
                --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        b.Worker节点加入
            在Worker节点执行上述join命令:
            kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef \
                --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
            -------------------------------------------------------------------------------------------------
            加入成功后,在Master节点验证:
            kubectl get nodes
            NAME         STATUS   ROLES           AGE     VERSION
            k8s-master   Ready    control-plane   10m     v1.28.0
            k8s-node1    Ready    <none>          2m      v1.28.0
            k8s-node2    Ready    <none>          1m      v1.28.0
        c.Token过期处理
            Token默认24小时过期,如果过期需要重新生成:
            kubeadm token create                                                 --创建新Token
            kubeadm token list                                                   --查看Token
            -------------------------------------------------------------------------------------------------
            获取CA证书哈希:
            openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
            openssl rsa -pubin -outform der 2>/dev/null | \
            openssl dgst -sha256 -hex | sed 's/^.* //'
            -------------------------------------------------------------------------------------------------
            手动拼接join命令:
            kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

03.���进制安装(高级)
    a.准备工作
        a.下载二进制文件
            访问:https://github.com/kubernetes/kubernetes/releases
            下载对应版本的二进制文件(kubernetes-server-linux-amd64.tar.gz)
        b.解压
            tar -xzf kubernetes-server-linux-amd64.tar.gz
            cd kubernetes/server/bin
            -------------------------------------------------------------------------------------------------
            cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
            cp kubelet kube-proxy /usr/local/bin/
    b.生成证书
        a.安装cfssl
            wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
            wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
            wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
            -------------------------------------------------------------------------------------------------
            chmod +x cfssl*
            mv cfssl_linux-amd64 /usr/local/bin/cfssl
            mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
            mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
        b.生成CA证书
            cat > ca-config.json << EOF
            {
              "signing": {
                "default": {
                  "expiry": "87600h"
                },
                "profiles": {
                  "kubernetes": {
                    "usages": [
                      "signing",
                      "key encipherment",
                      "server auth",
                      "client auth"
                    ],
                    "expiry": "87600h"
                  }
                }
              }
            }
            EOF
            -------------------------------------------------------------------------------------------------
            cat > ca-csr.json << EOF
            {
              "CN": "kubernetes",
              "key": {
                "algo": "rsa",
                "size": 2048
              },
              "names": [
                {
                  "C": "CN",
                  "ST": "Beijing",
                  "L": "Beijing",
                  "O": "k8s",
                  "OU": "System"
                }
              ]
            }
            EOF
            -------------------------------------------------------------------------------------------------
            cfssl gencert -initca ca-csr.json | cfssljson -bare ca
        c.生成API Server证书
            cat > server-csr.json << EOF
            {
              "CN": "kubernetes",
              "hosts": [
                "10.0.0.1",
                "127.0.0.1",
                "192.168.1.10",
                "kubernetes",
                "kubernetes.default",
                "kubernetes.default.svc",
                "kubernetes.default.svc.cluster",
                "kubernetes.default.svc.cluster.local"
              ],
              "key": {
                "algo": "rsa",
                "size": 2048
              },
              "names": [
                {
                  "C": "CN",
                  "ST": "Beijing",
                  "L": "Beijing",
                  "O": "k8s",
                  "OU": "System"
                }
              ]
            }
            EOF
            -------------------------------------------------------------------------------------------------
            cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
    c.配置etcd
        a.下载etcd
            wget https://github.com/etcd-io/etcd/releases/download/v3.5.9/etcd-v3.5.9-linux-amd64.tar.gz
            tar -xzf etcd-v3.5.9-linux-amd64.tar.gz
            cp etcd-v3.5.9-linux-amd64/etcd* /usr/local/bin/
        b.创建systemd服务
            cat > /usr/lib/systemd/system/etcd.service << EOF
            [Unit]
            Description=Etcd Server
            After=network.target
            After=network-online.target
            Wants=network-online.target

            [Service]
            Type=notify
            WorkingDirectory=/var/lib/etcd/
            ExecStart=/usr/local/bin/etcd \\
              --name=etcd01 \\
              --data-dir=/var/lib/etcd \\
              --listen-client-urls=https://192.168.1.10:2379,http://127.0.0.1:2379 \\
              --advertise-client-urls=https://192.168.1.10:2379 \\
              --listen-peer-urls=https://192.168.1.10:2380 \\
              --initial-advertise-peer-urls=https://192.168.1.10:2380 \\
              --initial-cluster=etcd01=https://192.168.1.10:2380 \\
              --initial-cluster-token=etcd-cluster-token \\
              --initial-cluster-state=new
            Restart=on-failure
            RestartSec=5
            LimitNOFILE=65536

            [Install]
            WantedBy=multi-user.target
            EOF
            -------------------------------------------------------------------------------------------------
            systemctl daemon-reload
            systemctl enable etcd
            systemctl start etcd
            systemctl status etcd                                                --验证
    d.配置API Server
        略(二进制安装较复杂,生产环境建议使用kubeadm)

04.Minikube安装(本地开发)
    a.安装Minikube(macOS)
        brew install minikube                                                    --使用Homebrew安装
        -------------------------------------------------------------------------------------------------
        或手动安装:
        curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64
        sudo install minikube-darwin-amd64 /usr/local/bin/minikube
    b.安装Minikube(Linux)
        curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
        sudo install minikube-linux-amd64 /usr/local/bin/minikube
    c.安装Minikube(Windows)
        下载安装包:https://github.com/kubernetes/minikube/releases/latest
        或使用Chocolatey:
        choco install minikube
    d.启动Minikube
        minikube start                                                           --使用默认驱动(Docker)
        minikube start --driver=virtualbox                                       --使用VirtualBox驱动
        minikube start --driver=hyperv                                           --使用Hyper-V驱动
        minikube start --cpus=4 --memory=8192                                    --指定资源
        -------------------------------------------------------------------------------------------------
        minikube status                                                          --查看状态
        kubectl get nodes                                                        --验证
    e.常用命令
        minikube stop                                                            --停止集群
        minikube delete                                                          --删除集群
        minikube pause                                                           --暂停集群
        minikube unpause                                                         --恢复集群
        minikube dashboard                                                       --打开Dashboard
        minikube ssh                                                             --SSH到节点
        minikube addons list                                                     --查看插件列表
        minikube addons enable ingress                                           --启用Ingress插件

05.Kind安装(本地开发)
    a.安装Kind(macOS/Linux)
        curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
        chmod +x ./kind
        sudo mv ./kind /usr/local/bin/kind
        -------------------------------------------------------------------------------------------------
        或使用包管理器:
        brew install kind                                                        --macOS
        go install sigs.k8s.io/[email protected]                                      --Go安装
    b.创建集群
        kind create cluster                                                      --创建单节点集群
        kind create cluster --name my-cluster                                    --指定集群名称
        -------------------------------------------------------------------------------------------------
        使用配置文件创建多节点集群:
        cat > kind-config.yaml << EOF
        kind: Cluster
        apiVersion: kind.x-k8s.io/v1alpha4
        nodes:
        - role: control-plane
        - role: worker
        - role: worker
        EOF
        -------------------------------------------------------------------------------------------------
        kind create cluster --config kind-config.yaml
    c.常用命令
        kind get clusters                                                        --查看集群列表
        kind delete cluster                                                      --删除默认集群
        kind delete cluster --name my-cluster                                    --删除指定集群
        kind load docker-image my-image:latest                                   --加载镜像到集群
        kubectl cluster-info --context kind-my-cluster                           --查看集群信息

06.K3s安装(轻量级)
    a.安装K3s
        curl -sfL https://get.k3s.io | sh -                                      --一键安装
        -------------------------------------------------------------------------------------------------
        指定版本:
        curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.28.0+k3s1 sh -
        -------------------------------------------------------------------------------------------------
        验证:
        systemctl status k3s                                                     --查看服务状态
        kubectl get nodes                                                        --查看节点
    b.配置kubectl
        mkdir -p $HOME/.kube
        sudo cp /etc/rancher/k3s/k3s.yaml $HOME/.kube/config
        sudo chown $(id -u):$(id -g) $HOME/.kube/config
    c.添加Worker节点
        在Master节点获取Token:
        cat /var/lib/rancher/k3s/server/node-token
        -------------------------------------------------------------------------------------------------
        在Worker节点执行:
        curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.10:6443 K3S_TOKEN=<token> sh -
    d.卸载K3s
        /usr/local/bin/k3s-uninstall.sh                                          --Master节点
        /usr/local/bin/k3s-agent-uninstall.sh                                    --Worker节点

07.常见问题
    a.镜像拉取失败
        问题:国内无法访问gcr.io、k8s.gcr.io等镜像仓库
        解决:使用阿里云镜像:registry.aliyuncs.com/google_containers
    b.节点NotReady
        问题:节点状态一直是NotReady
        解决:检查网络插件是否正常运行(kubectl get pods -n kube-system)
    c.coredns CrashLoopBackOff
        问题:coredns容器一直重启
        解决:检查/etc/resolv.conf,确保DNS配置正确
    d.端口被占用
        问题:6443端口已被占用
        解决:lsof -i:6443 查看占用进程,kill掉或更换端口
    e.kubelet启动失败
        问题:kubelet服务无法启动
        解决:查看日志 journalctl -xeu kubelet,根据错误信息排查

3.3 [1]backup

01.etcd备份
    a.备份方式
        a.快照备份
            etcd的数据以快照形式保存
            使用etcdctl snapshot save命令备份
            备份文件包含完整的集群状态数据
        b.定时备份
            使用cron定时任务自动备份
            建议每天至少备份一次
            保留最近7天的备份文件
        c.备份位置
            本地备份                                      存储在Master节点本地磁盘
            远程备份                                      存储在NAS、对象存储(如S3、OSS)
            多地备份                                      同时存储在多个位置,提高可靠性
    b.备份命令
        a.查看etcd信息
            kubectl get pods -n kube-system | grep etcd                          --查看etcd Pod
            -------------------------------------------------------------------------------------------------
            etcd Pod名称通常为:etcd-<master-hostname>
            etcd数据目录:/var/lib/etcd
        b.使用etcdctl备份(kubeadm安装)
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              snapshot save /backup/etcd-snapshot-$(date +%Y%m%d-%H%M%S).db
            -------------------------------------------------------------------------------------------------
            验证备份文件:
            ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot-20231216-100000.db
        c.使用kubectl exec备份
            kubectl exec -n kube-system etcd-k8s-master -- sh -c \
              "ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              snapshot save /tmp/etcd-snapshot.db"
            -------------------------------------------------------------------------------------------------
            kubectl cp kube-system/etcd-k8s-master:/tmp/etcd-snapshot.db ./etcd-snapshot.db
        d.检查备份文件
            ls -lh /backup/etcd-snapshot-*.db                                    --查看备份文件大小
            -------------------------------------------------------------------------------------------------
            ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot-20231216-100000.db --write-out=table
            输出示例:
            +----------+----------+------------+------------+
            |   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
            +----------+----------+------------+------------+
            | 12345678 |    10000 |       1234 |     5.2 MB |
            +----------+----------+------------+------------+
    c.自动化备份脚本
        a.创建备份脚本
            cat > /usr/local/bin/etcd-backup.sh << 'EOF'
            #!/bin/bash
            # etcd自动备份脚本

            # 配置变量
            BACKUP_DIR="/backup/etcd"
            ETCD_ENDPOINTS="https://127.0.0.1:2379"
            ETCD_CACERT="/etc/kubernetes/pki/etcd/ca.crt"
            ETCD_CERT="/etc/kubernetes/pki/etcd/server.crt"
            ETCD_KEY="/etc/kubernetes/pki/etcd/server.key"
            RETENTION_DAYS=7
            DATE=$(date +%Y%m%d-%H%M%S)
            BACKUP_FILE="${BACKUP_DIR}/etcd-snapshot-${DATE}.db"

            # 创建备份目录
            mkdir -p ${BACKUP_DIR}

            # 执行备份
            echo "开始备份 etcd..."
            ETCDCTL_API=3 etcdctl \
              --endpoints=${ETCD_ENDPOINTS} \
              --cacert=${ETCD_CACERT} \
              --cert=${ETCD_CERT} \
              --key=${ETCD_KEY} \
              snapshot save ${BACKUP_FILE}

            # 检查备份是否成功
            if [ $? -eq 0 ]; then
              echo "备份成功: ${BACKUP_FILE}"
              # 验证备份文件
              ETCDCTL_API=3 etcdctl snapshot status ${BACKUP_FILE}
            else
              echo "备份失败!"
              exit 1
            fi

            # 清理过期备份(保留最近7天)
            echo "清理 ${RETENTION_DAYS} 天前的备份..."
            find ${BACKUP_DIR} -name "etcd-snapshot-*.db" -mtime +${RETENTION_DAYS} -delete

            # 显示当前备份文件
            echo "当前备份文件:"
            ls -lh ${BACKUP_DIR}/etcd-snapshot-*.db

            echo "备份完成!"
            EOF
            -------------------------------------------------------------------------------------------------
            chmod +x /usr/local/bin/etcd-backup.sh
        b.测试备份脚本
            /usr/local/bin/etcd-backup.sh                                        --手动执行测试
        c.配置定时任务
            crontab -e
            -------------------------------------------------------------------------------------------------
            添加以下内容(每天凌晨2点执行备份):
            0 2 * * * /usr/local/bin/etcd-backup.sh >> /var/log/etcd-backup.log 2>&1
            -------------------------------------------------------------------------------------------------
            查看定时任务:
            crontab -l
        d.远程备份脚本(上传到对象存储)
            cat > /usr/local/bin/etcd-backup-s3.sh << 'EOF'
            #!/bin/bash
            # etcd备份并上传到S3

            BACKUP_DIR="/backup/etcd"
            DATE=$(date +%Y%m%d-%H%M%S)
            BACKUP_FILE="${BACKUP_DIR}/etcd-snapshot-${DATE}.db"
            S3_BUCKET="s3://my-k8s-backup"

            # 执行备份
            /usr/local/bin/etcd-backup.sh

            # 上传到S3
            if [ -f ${BACKUP_FILE} ]; then
              echo "上传备份到 S3..."
              aws s3 cp ${BACKUP_FILE} ${S3_BUCKET}/etcd/
              if [ $? -eq 0 ]; then
                echo "上传成功!"
              else
                echo "上传失败!"
                exit 1
              fi
            fi
            EOF
            -------------------------------------------------------------------------------------------------
            chmod +x /usr/local/bin/etcd-backup-s3.sh

02.etcd恢复
    a.恢复流程
        a.恢复前准备
            停止所有Master节点的K8s组件
            备份当前etcd数据(防止恢复失败)
            确保有可用的etcd备份文件
        b.恢复步骤
            第一步:停止etcd服务
            第二步:清理旧数据目录
            第三步:使用快照恢复数据
            第四步:修改etcd配置(如果需要)
            第五步:启动etcd服务
            第六步:启动K8s组件
            第七步:验证恢复结果
        c.注意事项
            恢复操作会覆盖现有数据,务必谨慎
            建议在测试环境先演练恢复流程
            恢复后需要重启所有K8s组件
    b.恢复命令
        a.停止K8s组件(kubeadm安装)
            systemctl stop kubelet                                               --停止kubelet
            -------------------------------------------------------------------------------------------------
            或使用静态Pod方式停止:
            mv /etc/kubernetes/manifests /etc/kubernetes/manifests.bak          --移走静态Pod配置
            -------------------------------------------------------------------------------------------------
            等待所有组件停止:
            docker ps | grep k8s                                                 --确认容器已停止
        b.备份当前数据
            mv /var/lib/etcd /var/lib/etcd.bak                                   --备份当前etcd数据
        c.恢复快照
            ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot-20231216-100000.db \
              --name=etcd-0 \
              --initial-cluster=etcd-0=https://192.168.1.10:2380 \
              --initial-cluster-token=etcd-cluster \
              --initial-advertise-peer-urls=https://192.168.1.10:2380 \
              --data-dir=/var/lib/etcd
            -------------------------------------------------------------------------------------------------
            参数说明:
            --name                                                               etcd成员名称
            --initial-cluster                                                    初始集群配置
            --initial-cluster-token                                              集群令牌
            --initial-advertise-peer-urls                                        成员间通信地址
            --data-dir                                                           数据目录
        d.修改权限
            chown -R etcd:etcd /var/lib/etcd                                     --如果使用etcd用户
            -------------------------------------------------------------------------------------------------
            或:
            chmod 700 /var/lib/etcd
        e.启动K8s组件
            mv /etc/kubernetes/manifests.bak /etc/kubernetes/manifests          --恢复静态Pod配置
            systemctl start kubelet                                              --启动kubelet
        f.多节点恢复
            # 在所有Master节点执行恢复操作
            # 节点1:
            ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
              --name=etcd-0 \
              --initial-cluster=etcd-0=https://192.168.1.10:2380,etcd-1=https://192.168.1.11:2380,etcd-2=https://192.168.1.12:2380 \
              --initial-cluster-token=etcd-cluster \
              --initial-advertise-peer-urls=https://192.168.1.10:2380 \
              --data-dir=/var/lib/etcd
            -------------------------------------------------------------------------------------------------
            # 节点2:
            ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
              --name=etcd-1 \
              --initial-cluster=etcd-0=https://192.168.1.10:2380,etcd-1=https://192.168.1.11:2380,etcd-2=https://192.168.1.12:2380 \
              --initial-cluster-token=etcd-cluster \
              --initial-advertise-peer-urls=https://192.168.1.11:2380 \
              --data-dir=/var/lib/etcd
            -------------------------------------------------------------------------------------------------
            # 节点3:
            ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
              --name=etcd-2 \
              --initial-cluster=etcd-0=https://192.168.1.10:2380,etcd-1=https://192.168.1.11:2380,etcd-2=https://192.168.1.12:2380 \
              --initial-cluster-token=etcd-cluster \
              --initial-advertise-peer-urls=https://192.168.1.12:2380 \
              --data-dir=/var/lib/etcd
    c.验证恢复
        a.检查etcd状态
            kubectl get pods -n kube-system | grep etcd                          --查看etcd Pod状态
            -------------------------------------------------------------------------------------------------
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              member list
            -------------------------------------------------------------------------------------------------
            输出示例:
            8e9e05c52164694d, started, etcd-0, https://192.168.1.10:2380, https://192.168.1.10:2379, false
        b.检查集群状态
            kubectl get nodes                                                    --查看节点状态
            kubectl get pods -A                                                  --查看所有Pod状态
            kubectl get deployments -A                                           --查看Deployment状态
        c.检查数据完整性
            kubectl get namespaces                                               --查看命名空间
            kubectl get configmaps -A                                            --查看ConfigMap
            kubectl get secrets -A                                               --查看Secret
            -------------------------------------------------------------------------------------------------
            验证关键应用是否正常:
            kubectl get pods -n <namespace>                                      --检查业务Pod

03.资源备份
    a.使用kubectl导出
        a.导出单个资源
            kubectl get deployment nginx -n default -o yaml > nginx-deployment.yaml      --导出Deployment
            kubectl get service nginx -n default -o yaml > nginx-service.yaml            --导出Service
            kubectl get configmap nginx-config -n default -o yaml > nginx-configmap.yaml --导出ConfigMap
        b.导出命名空间所有资源
            kubectl get all -n default -o yaml > default-namespace.yaml                  --导出所有资源
            -------------------------------------------------------------------------------------------------
            注意:get all不包括ConfigMap、Secret、PVC等资源
        c.导出特定类型的所有资源
            kubectl get deployments -A -o yaml > all-deployments.yaml                    --所有Deployment
            kubectl get services -A -o yaml > all-services.yaml                          --所有Service
            kubectl get configmaps -A -o yaml > all-configmaps.yaml                      --所有ConfigMap
            kubectl get secrets -A -o yaml > all-secrets.yaml                            --所有Secret
            kubectl get pvc -A -o yaml > all-pvc.yaml                                    --所有PVC
        d.批量导出脚本
            cat > /usr/local/bin/k8s-export-resources.sh << 'EOF'
            #!/bin/bash
            # K8s资源导出脚本

            BACKUP_DIR="/backup/k8s-resources"
            DATE=$(date +%Y%m%d-%H%M%S)
            EXPORT_DIR="${BACKUP_DIR}/${DATE}"

            mkdir -p ${EXPORT_DIR}

            # 导出各类资源
            echo "导出Namespace..."
            kubectl get namespaces -o yaml > ${EXPORT_DIR}/namespaces.yaml

            echo "导出Deployments..."
            kubectl get deployments -A -o yaml > ${EXPORT_DIR}/deployments.yaml

            echo "导出StatefulSets..."
            kubectl get statefulsets -A -o yaml > ${EXPORT_DIR}/statefulsets.yaml

            echo "导出DaemonSets..."
            kubectl get daemonsets -A -o yaml > ${EXPORT_DIR}/daemonsets.yaml

            echo "导出Services..."
            kubectl get services -A -o yaml > ${EXPORT_DIR}/services.yaml

            echo "导出ConfigMaps..."
            kubectl get configmaps -A -o yaml > ${EXPORT_DIR}/configmaps.yaml

            echo "导出Secrets..."
            kubectl get secrets -A -o yaml > ${EXPORT_DIR}/secrets.yaml

            echo "导出PV..."
            kubectl get pv -o yaml > ${EXPORT_DIR}/pv.yaml

            echo "导出PVC..."
            kubectl get pvc -A -o yaml > ${EXPORT_DIR}/pvc.yaml

            echo "导出Ingress..."
            kubectl get ingress -A -o yaml > ${EXPORT_DIR}/ingress.yaml

            echo "导出完成! 文件保存在: ${EXPORT_DIR}"
            ls -lh ${EXPORT_DIR}
            EOF
            -------------------------------------------------------------------------------------------------
            chmod +x /usr/local/bin/k8s-export-resources.sh
    b.使用Velero备份
        a.安装Velero CLI
            # macOS
            brew install velero
            -------------------------------------------------------------------------------------------------
            # Linux
            wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz
            tar -xzf velero-v1.12.0-linux-amd64.tar.gz
            sudo mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/
        b.安装Velero服务端(使用Minio)
            # 安装Minio作为对象存储
            kubectl apply -f https://raw.githubusercontent.com/vmware-tanzu/velero/main/examples/minio/00-minio-deployment.yaml
            -------------------------------------------------------------------------------------------------
            # 创建凭证文件
            cat > credentials-velero << EOF
            [default]
            aws_access_key_id = minio
            aws_secret_access_key = minio123
            EOF
            -------------------------------------------------------------------------------------------------
            # 安装Velero
            velero install \
              --provider aws \
              --plugins velero/velero-plugin-for-aws:v1.8.0 \
              --bucket velero \
              --secret-file ./credentials-velero \
              --use-volume-snapshots=false \
              --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000
        c.创建备份
            velero backup create my-backup                                               --备份所有资源
            velero backup create my-backup --include-namespaces default                  --备份指定命名空间
            velero backup create my-backup --selector app=nginx                          --备份指定标签的资源
            -------------------------------------------------------------------------------------------------
            查看备份:
            velero backup get                                                            --查看所有备份
            velero backup describe my-backup                                             --查看备份详情
            velero backup logs my-backup                                                 --查看备份日志
        d.定时备份
            velero schedule create daily-backup --schedule="0 2 * * *"                   --每天凌晨2点备份
            velero schedule create weekly-backup --schedule="0 2 * * 0"                  --每周日凌晨2点备份
            -------------------------------------------------------------------------------------------------
            查看定时任务:
            velero schedule get
        e.恢复备份
            velero restore create --from-backup my-backup                                --从备份恢复
            velero restore create --from-backup my-backup --include-namespaces default   --恢复指定命名空间
            -------------------------------------------------------------------------------------------------
            查看恢复状态:
            velero restore get
            velero restore describe <restore-name>
    c.GitOps备份
        a.使用Git存储配置
            将所有K8s YAML配置存储在Git仓库
            通过CI/CD自动应用配置
            配置变更历史可追溯
        b.目录结构示例
            k8s-configs/
            ├── base/
            │   ├── deployments/
            │   │   ├── app1.yaml
            │   │   └── app2.yaml
            │   ├── services/
            │   │   ├── app1-svc.yaml
            │   │   └── app2-svc.yaml
            │   └── configmaps/
            │       └── app-config.yaml
            ├── overlays/
            │   ├── dev/
            │   ├── staging/
            │   └── prod/
            └── README.md
        c.使用ArgoCD
            kubectl create namespace argocd
            kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
            -------------------------------------------------------------------------------------------------
            创建应用:
            kubectl apply -f - <<EOF
            apiVersion: argoproj.io/v1alpha1
            kind: Application
            metadata:
              name: my-app
              namespace: argocd
            spec:
              project: default
              source:
                repoURL: https://github.com/myorg/k8s-configs
                targetRevision: HEAD
                path: base
              destination:
                server: https://kubernetes.default.svc
                namespace: default
              syncPolicy:
                automated:
                  prune: true
                  selfHeal: true
            EOF
        d.使用Flux
            flux bootstrap github \
              --owner=myorg \
              --repository=k8s-configs \
              --branch=main \
              --path=./clusters/my-cluster \
              --personal

04.灾难恢复
    a.完全恢复流程
        a.场景说明
            整个集群损坏需要重建
            从备份恢复所有数据和配置
        b.恢复步骤
            第一步:重新部署K8s集群(使用kubeadm init)
            第二步:恢复etcd数据(从快照恢复)
            第三步:验证集群基础功能
            第四步:恢复网络插件配置
            第五步:恢复应用资源(使用kubectl apply或Velero)
            第六步:验证应用功能
            第七步:恢复持久化数据(如果有)
        c.完整恢复脚本
            cat > /usr/local/bin/k8s-disaster-recovery.sh << 'EOF'
            #!/bin/bash
            # K8s灾难恢复脚本

            ETCD_BACKUP="/backup/etcd/etcd-snapshot-latest.db"
            RESOURCE_BACKUP="/backup/k8s-resources/latest"

            echo "=== 步骤1: 恢复etcd ==="
            systemctl stop kubelet
            mv /etc/kubernetes/manifests /etc/kubernetes/manifests.bak

            ETCDCTL_API=3 etcdctl snapshot restore ${ETCD_BACKUP} \
              --name=etcd-0 \
              --initial-cluster=etcd-0=https://192.168.1.10:2380 \
              --initial-cluster-token=etcd-cluster \
              --initial-advertise-peer-urls=https://192.168.1.10:2380 \
              --data-dir=/var/lib/etcd

            mv /etc/kubernetes/manifests.bak /etc/kubernetes/manifests
            systemctl start kubelet

            echo "等待集群就绪..."
            sleep 30

            echo "=== 步骤2: 恢复网络插件 ==="
            kubectl apply -f /etc/kubernetes/network-plugin.yaml

            echo "等待网络就绪..."
            sleep 30

            echo "=== 步骤3: 恢复应用资源 ==="
            kubectl apply -f ${RESOURCE_BACKUP}/namespaces.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/configmaps.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/secrets.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/pv.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/pvc.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/deployments.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/statefulsets.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/daemonsets.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/services.yaml
            kubectl apply -f ${RESOURCE_BACKUP}/ingress.yaml

            echo "=== 恢复完成! ==="
            echo "请执行以下命令验证:"
            echo "  kubectl get nodes"
            echo "  kubectl get pods -A"
            EOF
            -------------------------------------------------------------------------------------------------
            chmod +x /usr/local/bin/k8s-disaster-recovery.sh
    b.部分恢复流程
        a.恢复单个命名空间
            kubectl apply -f backup/namespace/my-namespace.yaml                          --恢复命名空间定义
            kubectl apply -f backup/namespace/my-namespace/                              --恢复该命名空间下所有资源
        b.恢复单个应用
            kubectl apply -f backup/apps/nginx/                                          --恢复nginx应用
        c.使用Velero部分恢复
            velero restore create --from-backup my-backup --include-namespaces default   --只恢复default命名空间
            velero restore create --from-backup my-backup --selector app=nginx           --只恢复特定标签的资源
    c.跨集群迁移
        a.导出源集群资源
            # 在源集群执行
            /usr/local/bin/k8s-export-resources.sh
            -------------------------------------------------------------------------------------------------
            # 打包备份文件
            tar -czf k8s-backup.tar.gz /backup/k8s-resources/20231216-100000/
        b.导入目标集群
            # 将备份文件传输到目标集群
            scp k8s-backup.tar.gz user@target-cluster:/tmp/
            -------------------------------------------------------------------------------------------------
            # 在目标集群解压
            tar -xzf /tmp/k8s-backup.tar.gz -C /tmp/
            -------------------------------------------------------------------------------------------------
            # 应用资源
            kubectl apply -f /tmp/backup/k8s-resources/20231216-100000/
        c.使用Velero跨集群迁移
            # 源集群创建备份
            velero backup create migration-backup
            -------------------------------------------------------------------------------------------------
            # 配置目标集群使用相同的对象存储
            velero install \
              --provider aws \
              --plugins velero/velero-plugin-for-aws:v1.8.0 \
              --bucket velero \
              --secret-file ./credentials-velero \
              --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000
            -------------------------------------------------------------------------------------------------
            # 目标集群恢复
            velero restore create --from-backup migration-backup
        d.注意事项
            修改资源中的集群特定配置(如节点选择器、存储类)
            更新DNS、负载均衡器等外部依赖
            验证持久化数据是否正确迁移
            测试应用功能是否正常

3.4 [1]network

01.网络模型
    a.Pod网络
        a.网络模型基础
            每个Pod都有独立的IP地址
            Pod内所有容器共享网络命名空间
            Pod之间可以直接通信,无需NAT
            节点和Pod之间可以直接通信
        b.网络要求
            所有Pod可以在不使用NAT的情况下与其他Pod通信
            所有节点可以在不使用NAT的情况下与所有Pod通信
            Pod看到的自己的IP地址与其他Pod看到的地址相同
        c.Pod内容器通信
            同一个Pod内的容器通过localhost通信
            共享网络命名空间和端口空间
            -------------------------------------------------------------------------------------------------
            示例:
            容器A监听8080端口
            容器B通过localhost:8080访问容器A
        d.Pod之间通信
            通过PodIP直接通信
            依赖CNI插件实现网络互通
            跨节点通信通过overlay网络或路由实现
    b.Service网络
        a.ClusterIP网络
            虚拟IP地址,只在集群内部可访问
            通过kube-proxy实现负载均衡
            默认的Service类型
        b.Service网段
            在kubeadm init时通过--service-cidr指定
            默认为10.96.0.0/12
            与Pod网段不能重叠
        c.Service到Pod的映射
            通过Endpoints对象关联
            kube-proxy监听Service和Endpoints变化
            更新iptables或IPVS规则
        d.DNS解析
            每个Service自动创建DNS记录
            格式:<service-name>.<namespace>.svc.cluster.local
            Pod内可以直接使用Service名称访问
    c.CNI插件对比
        a.Flannel
            简单易用,适合入门
            支持多种后端(VXLAN、host-gw、UDP)
            不支持网络策略
            性能中等
            -------------------------------------------------------------------------------------------------
            使用场景:开发测试环境、小型集群
        b.Calico
            功能强大,支持网络策略
            支持BGP路由和IPIP模式
            性能好,适合大规模集群
            配置复杂度中等
            -------------------------------------------------------------------------------------------------
            使用场景:生产环境、需要网络隔离的场景
        c.Weave Net
            自动发现,配置简单
            支持加密通信
            支持网络策略
            性能较好
            -------------------------------------------------------------------------------------------------
            使用场景:需要加密的场景
        d.Cilium
            基于eBPF技术,性能极好
            支持高级网络策略
            支持Service Mesh集成
            需要较新的内核版本(4.9+)
            -------------------------------------------------------------------------------------------------
            使用场景:高性能要求、Service Mesh场景
        e.性能对比
            插件           吞吐量    延迟    CPU占用    内存占用    网络策略
            Flannel        中等      低      低         低          不支持
            Calico         高        低      中         中          支持
            Weave Net      中等      中      中         中          支持
            Cilium         极高      极低    低         中          支持

02.Service详解
    a.ClusterIP
        a.基本概念
            默认的Service类型
            只能在集群内部访问
            提供一个稳定的虚拟IP
        b.创建ClusterIP Service
            kubectl expose deployment nginx --port=80 --target-port=80         --命令行创建
            -------------------------------------------------------------------------------------------------
            YAML示例:
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-service
              namespace: default
            spec:
              type: ClusterIP
              selector:
                app: nginx
              ports:
              - protocol: TCP
                port: 80              # Service端口
                targetPort: 80        # Pod端口
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-service.yaml
        c.访问ClusterIP Service
            kubectl get svc nginx-service                                      --查看Service
            -------------------------------------------------------------------------------------------------
            在集群内访问:
            curl http://nginx-service.default.svc.cluster.local
            curl http://nginx-service                                          --同命名空间下可省略后缀
            curl http://<ClusterIP>:80
        d.查看Endpoints
            kubectl get endpoints nginx-service                                --查看后端Pod
            -------------------------------------------------------------------------------------------------
            输出示例:
            NAME            ENDPOINTS                           AGE
            nginx-service   10.244.1.5:80,10.244.2.6:80        1m
    b.NodePort
        a.基本概念
            在所有节点上开放一个端口
            外部可以通过<NodeIP>:<NodePort>访问
            端口范围:30000-32767(默认)
        b.创建NodePort Service
            kubectl expose deployment nginx --type=NodePort --port=80          --命令行创建
            -------------------------------------------------------------------------------------------------
            YAML示例:
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-nodeport
            spec:
              type: NodePort
              selector:
                app: nginx
              ports:
              - protocol: TCP
                port: 80              # Service端口
                targetPort: 80        # Pod端口
                nodePort: 30080       # 节点端口(可选,不指定则自动分配)
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-nodeport.yaml
        c.访问NodePort Service
            kubectl get svc nginx-nodeport                                     --查看Service
            -------------------------------------------------------------------------------------------------
            外部访问:
            curl http://<任意NodeIP>:30080
            -------------------------------------------------------------------------------------------------
            内部访问:
            curl http://nginx-nodeport                                         --通过ClusterIP访问
        d.自定义端口范围
            修改API Server配置:
            vim /etc/kubernetes/manifests/kube-apiserver.yaml
            -------------------------------------------------------------------------------------------------
            添加参数:
            --service-node-port-range=20000-40000
            -------------------------------------------------------------------------------------------------
            重启生效
    c.LoadBalancer
        a.基本概念
            云平台提供的负载均衡器
            自动创建外部负载均衡器
            需要云平台支持(AWS、GCP、Azure等)
        b.创建LoadBalancer Service
            YAML示例:
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-lb
            spec:
              type: LoadBalancer
              selector:
                app: nginx
              ports:
              - protocol: TCP
                port: 80
                targetPort: 80
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-lb.yaml
        c.查看LoadBalancer
            kubectl get svc nginx-lb                                           --查看Service
            -------------------------------------------------------------------------------------------------
            输出示例:
            NAME       TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
            nginx-lb   LoadBalancer   10.96.100.10    203.0.113.10     80:31234/TCP   1m
            -------------------------------------------------------------------------------------------------
            外部访问:
            curl http://203.0.113.10
        d.本地测试LoadBalancer(使用MetalLB)
            kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.0/config/manifests/metallb-native.yaml
            -------------------------------------------------------------------------------------------------
            配置IP地址池:
            apiVersion: metallb.io/v1beta1
            kind: IPAddressPool
            metadata:
              name: first-pool
              namespace: metallb-system
            spec:
              addresses:
              - 192.168.1.240-192.168.1.250
            ---
            apiVersion: metallb.io/v1beta1
            kind: L2Advertisement
            metadata:
              name: example
              namespace: metallb-system
            -------------------------------------------------------------------------------------------------
            kubectl apply -f metallb-config.yaml
    d.ExternalName
        a.基本概念
            将Service映射到外部DNS名称
            不创建ClusterIP
            通过DNS CNAME记录实现
        b.创建ExternalName Service
            YAML示例:
            apiVersion: v1
            kind: Service
            metadata:
              name: external-db
            spec:
              type: ExternalName
              externalName: mysql.example.com
            -------------------------------------------------------------------------------------------------
            kubectl apply -f external-db.yaml
        c.访问ExternalName Service
            在Pod内访问:
            mysql -h external-db -u user -p
            -------------------------------------------------------------------------------------------------
            自动解析为:mysql.example.com
        d.使用场景
            访问外部数据库
            访问外部API服务
            集群迁移时的过渡方案

03.Ingress详解
    a.Nginx Ingress
        a.安装Nginx Ingress Controller
            kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.0/deploy/static/provider/cloud/deploy.yaml
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get pods -n ingress-nginx                                  --查看Ingress Controller Pod
            kubectl get svc -n ingress-nginx                                   --查看Ingress Service
        b.创建基本Ingress
            YAML示例:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: nginx-ingress
              namespace: default
              annotations:
                nginx.ingress.kubernetes.io/rewrite-target: /
            spec:
              ingressClassName: nginx
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: nginx-service
                        port:
                          number: 80
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-ingress.yaml
        c.配置多域名
            YAML示例:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: multi-domain-ingress
            spec:
              ingressClassName: nginx
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: frontend-service
                        port:
                          number: 80
              - host: api.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: backend-service
                        port:
                          number: 8080
        d.配置TLS/SSL
            创建证书Secret:
            kubectl create secret tls example-tls \
              --cert=path/to/tls.crt \
              --key=path/to/tls.key
            -------------------------------------------------------------------------------------------------
            配置HTTPS Ingress:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: tls-ingress
            spec:
              ingressClassName: nginx
              tls:
              - hosts:
                - www.example.com
                secretName: example-tls
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: nginx-service
                        port:
                          number: 80
        e.常用注解
            nginx.ingress.kubernetes.io/rewrite-target: /                      --URL重写
            nginx.ingress.kubernetes.io/ssl-redirect: "true"                   --强制HTTPS
            nginx.ingress.kubernetes.io/proxy-body-size: "100m"                --上传文件大小限制
            nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"           --连接超时
            nginx.ingress.kubernetes.io/proxy-send-timeout: "600"              --发送超时
            nginx.ingress.kubernetes.io/proxy-read-timeout: "600"              --读取超时
            nginx.ingress.kubernetes.io/rate-limit: "100"                      --限流
    b.Traefik
        a.安装Traefik
            使用Helm安装:
            helm repo add traefik https://helm.traefik.io/traefik
            helm repo update
            helm install traefik traefik/traefik -n kube-system
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get pods -n kube-system | grep traefik
            kubectl get svc -n kube-system | grep traefik
        b.创建Traefik Ingress
            YAML示例:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: traefik-ingress
              annotations:
                traefik.ingress.kubernetes.io/router.entrypoints: web
            spec:
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: nginx-service
                        port:
                          number: 80
        c.配置中间件
            YAML示例:
            apiVersion: traefik.containo.us/v1alpha1
            kind: Middleware
            metadata:
              name: auth-middleware
            spec:
              basicAuth:
                secret: authsecret
            ---
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: traefik-auth-ingress
              annotations:
                traefik.ingress.kubernetes.io/router.middlewares: default-auth-middleware@kubernetescrd
            spec:
              rules:
              - host: secure.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: secure-service
                        port:
                          number: 80
        d.Dashboard访问
            kubectl port-forward -n kube-system $(kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik -o name) 9000:9000
            -------------------------------------------------------------------------------------------------
            访问:http://localhost:9000/dashboard/
    c.配置示例
        a.基于路径的路由
            YAML示例:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: path-based-ingress
            spec:
              ingressClassName: nginx
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /api
                    pathType: Prefix
                    backend:
                      service:
                        name: api-service
                        port:
                          number: 8080
                  - path: /web
                    pathType: Prefix
                    backend:
                      service:
                        name: web-service
                        port:
                          number: 80
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: default-service
                        port:
                          number: 80
        b.配置基本认证
            创建认证文件:
            htpasswd -c auth myuser                                            --创建密码文件
            -------------------------------------------------------------------------------------------------
            创建Secret:
            kubectl create secret generic basic-auth --from-file=auth
            -------------------------------------------------------------------------------------------------
            配置Ingress:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: auth-ingress
              annotations:
                nginx.ingress.kubernetes.io/auth-type: basic
                nginx.ingress.kubernetes.io/auth-secret: basic-auth
                nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
            spec:
              ingressClassName: nginx
              rules:
              - host: secure.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: secure-service
                        port:
                          number: 80
        c.配置白名单
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: whitelist-ingress
              annotations:
                nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.1.0/24,10.0.0.0/8"
            spec:
              ingressClassName: nginx
              rules:
              - host: internal.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: internal-service
                        port:
                          number: 80
        d.配置跨域(CORS)
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: cors-ingress
              annotations:
                nginx.ingress.kubernetes.io/enable-cors: "true"
                nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
                nginx.ingress.kubernetes.io/cors-allow-origin: "*"
                nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
            spec:
              ingressClassName: nginx
              rules:
              - host: api.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: api-service
                        port:
                          number: 8080

04.网络策略
    a.NetworkPolicy
        a.基本概念
            默认情况下所有Pod之间可以互相通信
            NetworkPolicy用于限制Pod之间的网络流量
            需要CNI插件支持(如Calico、Weave Net)
            Flannel不支持NetworkPolicy
        b.策略类型
            Ingress                                                            入站流量控制
            Egress                                                             出站流量控制
        c.选择器
            podSelector                                                        选择应用策略的Pod
            namespaceSelector                                                  选择允许通信的命名空间
            ipBlock                                                            选择允许的IP地址段
    b.入站规则
        a.默认拒绝所有入站流量
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: deny-all-ingress
              namespace: default
            spec:
              podSelector: {}                                                  --选择所有Pod
              policyTypes:
              - Ingress
            -------------------------------------------------------------------------------------------------
            kubectl apply -f deny-all-ingress.yaml
        b.允许特定Pod访问
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: allow-from-frontend
              namespace: default
            spec:
              podSelector:
                matchLabels:
                  app: backend                                                 --应用到backend Pod
              policyTypes:
              - Ingress
              ingress:
              - from:
                - podSelector:
                    matchLabels:
                      app: frontend                                            --只允许frontend Pod访问
                ports:
                - protocol: TCP
                  port: 8080
        c.允许特定命名空间访问
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: allow-from-namespace
              namespace: production
            spec:
              podSelector:
                matchLabels:
                  app: api
              policyTypes:
              - Ingress
              ingress:
              - from:
                - namespaceSelector:
                    matchLabels:
                      env: production                                          --只允许production命名空间访问
                ports:
                - protocol: TCP
                  port: 80
        d.允许特定IP段访问
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: allow-from-external
              namespace: default
            spec:
              podSelector:
                matchLabels:
                  app: web
              policyTypes:
              - Ingress
              ingress:
              - from:
                - ipBlock:
                    cidr: 192.168.1.0/24                                       --允许的IP段
                    except:
                    - 192.168.1.100/32                                         --排除的IP
                ports:
                - protocol: TCP
                  port: 80
    c.出站规则
        a.默认拒绝所有出站流量
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: deny-all-egress
              namespace: default
            spec:
              podSelector: {}
              policyTypes:
              - Egress
        b.允许访问特定服务
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: allow-to-database
              namespace: default
            spec:
              podSelector:
                matchLabels:
                  app: backend
              policyTypes:
              - Egress
              egress:
              - to:
                - podSelector:
                    matchLabels:
                      app: mysql                                               --只允许访问mysql Pod
                ports:
                - protocol: TCP
                  port: 3306
        c.允许DNS查询
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: allow-dns
              namespace: default
            spec:
              podSelector: {}
              policyTypes:
              - Egress
              egress:
              - to:
                - namespaceSelector:
                    matchLabels:
                      name: kube-system
                  podSelector:
                    matchLabels:
                      k8s-app: kube-dns
                ports:
                - protocol: UDP
                  port: 53
        d.组合入站和出站规则
            apiVersion: networking.k8s.io/v1
            kind: NetworkPolicy
            metadata:
              name: api-network-policy
              namespace: default
            spec:
              podSelector:
                matchLabels:
                  app: api
              policyTypes:
              - Ingress
              - Egress
              ingress:
              - from:
                - podSelector:
                    matchLabels:
                      app: frontend
                ports:
                - protocol: TCP
                  port: 8080
              egress:
              - to:
                - podSelector:
                    matchLabels:
                      app: database
                ports:
                - protocol: TCP
                  port: 5432
              - to:                                                            --允许DNS查询
                - namespaceSelector: {}
                  podSelector:
                    matchLabels:
                      k8s-app: kube-dns
                ports:
                - protocol: UDP
                  port: 53

05.DNS服务
    a.CoreDNS配置
        a.CoreDNS介绍
            Kubernetes默认的DNS服务
            替代了之前的kube-dns
            基于插件架构,功能强大
        b.查看CoreDNS配置
            kubectl get configmap coredns -n kube-system -o yaml              --查看配置
            -------------------------------------------------------------------------------------------------
            配置示例:
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: coredns
              namespace: kube-system
            data:
              Corefile: |
                .:53 {
                    errors
                    health {
                       lameduck 5s
                    }
                    ready
                    kubernetes cluster.local in-addr.arpa ip6.arpa {
                       pods insecure
                       fallthrough in-addr.arpa ip6.arpa
                       ttl 30
                    }
                    prometheus :9153
                    forward . /etc/resolv.conf {
                       max_concurrent 1000
                    }
                    cache 30
                    loop
                    reload
                    loadbalance
                }
        c.自定义DNS解析
            编辑CoreDNS ConfigMap:
            kubectl edit configmap coredns -n kube-system
            -------------------------------------------------------------------------------------------------
            添加自定义域名解析:
            data:
              Corefile: |
                .:53 {
                    errors
                    health
                    ready
                    kubernetes cluster.local in-addr.arpa ip6.arpa {
                       pods insecure
                       fallthrough in-addr.arpa ip6.arpa
                    }
                    hosts {                                                    --添加自定义hosts
                       192.168.1.100 custom.example.com
                       fallthrough
                    }
                    prometheus :9153
                    forward . /etc/resolv.conf
                    cache 30
                    loop
                    reload
                    loadbalance
                }
            -------------------------------------------------------------------------------------------------
            重启CoreDNS:
            kubectl rollout restart deployment coredns -n kube-system
        d.配置上游DNS
            修改forward配置:
            forward . 8.8.8.8 8.8.4.4                                          --使用Google DNS
            forward . 114.114.114.114                                          --使用国内DNS
    b.服务发现
        a.Service DNS记录
            格式:<service-name>.<namespace>.svc.cluster.local
            -------------------------------------------------------------------------------------------------
            示例:
            nginx-service.default.svc.cluster.local
            mysql-service.database.svc.cluster.local
        b.Pod DNS记录
            格式:<pod-ip-with-dashes>.<namespace>.pod.cluster.local
            -------------------------------------------------------------------------------------------------
            示例:
            10-244-1-5.default.pod.cluster.local
        c.DNS搜索域
            Pod内默认DNS搜索域:
            <namespace>.svc.cluster.local
            svc.cluster.local
            cluster.local
            -------------------------------------------------------------------------------------------------
            简化访问:
            同命名空间:curl http://nginx-service
            跨命名空间:curl http://nginx-service.default
            完整域名:curl http://nginx-service.default.svc.cluster.local
        d.Headless Service
            ClusterIP设置为None
            返回所有Pod的IP地址
            用于StatefulSet
            -------------------------------------------------------------------------------------------------
            示例:
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-headless
            spec:
              clusterIP: None
              selector:
                app: nginx
              ports:
              - port: 80
            -------------------------------------------------------------------------------------------------
            DNS查询返回所有Pod IP:
            nslookup nginx-headless.default.svc.cluster.local
    c.DNS调试
        a.测试DNS解析
            创建测试Pod:
            kubectl run dnsutils --image=tutum/dnsutils --command -- sleep infinity
            -------------------------------------------------------------------------------------------------
            进入Pod测试:
            kubectl exec -it dnsutils -- /bin/bash
            -------------------------------------------------------------------------------------------------
            测试解析:
            nslookup kubernetes.default.svc.cluster.local                      --解析Service
            nslookup nginx-service                                             --简短名称
            dig kubernetes.default.svc.cluster.local                           --使用dig命令
        b.查看DNS配置
            kubectl exec -it dnsutils -- cat /etc/resolv.conf
            -------------------------------------------------------------------------------------------------
            输出示例:
            nameserver 10.96.0.10                                              --CoreDNS Service IP
            search default.svc.cluster.local svc.cluster.local cluster.local
            options ndots:5
        c.常见DNS问题
            问题1:无法解析Service名称
            解决:检查CoreDNS Pod是否正常运行
                  kubectl get pods -n kube-system | grep coredns
            -------------------------------------------------------------------------------------------------
            问题2:解析慢
            解决:调整ndots参数,减少不必要的DNS查询
                  在Pod spec中设置:
                  dnsConfig:
                    options:
                    - name: ndots
                      value: "1"
            -------------------------------------------------------------------------------------------------
            问题3:CoreDNS CrashLoopBackOff
            解决:检查/etc/resolv.conf配置
                  确保没有环路引用
        d.性能优化
            增加CoreDNS副本数:
            kubectl scale deployment coredns -n kube-system --replicas=3
            -------------------------------------------------------------------------------------------------
            调整缓存时间:
            cache 300                                                          --缓存5分钟
            -------------------------------------------------------------------------------------------------
            启用自动伸缩:
            kubectl autoscale deployment coredns -n kube-system --min=2 --max=10 --cpu-percent=80

3.5 [2]terminal

00.汇总
    a.组件
        Pod
        Container(容器)
        Label(label)(标签)
        Replication Controller(复制控制器)
        Service(enter image description here)(服务)
        Node(节点)
        Kubernetes Master(Kubernetes主节点)
    b.容器
        RunC
        Docker
        podman
        Containerted

01.kubectl基础
    a.配置管理
        a.kubeconfig文件
            默认位置:~/.kube/config
            包含集群信息、用户凭证、上下文配置
            -------------------------------------------------------------------------------------------------
            查看当前配置:
            kubectl config view                                                      --查看完整配置
            kubectl config view --minify                                             --查看当前上下文配置
        b.集群配置
            kubectl config get-clusters                                              --查看所有集群
            -------------------------------------------------------------------------------------------------
            添加集群:
            kubectl config set-cluster my-cluster \
              --server=https://192.168.1.10:6443 \
              --certificate-authority=/path/to/ca.crt
            -------------------------------------------------------------------------------------------------
            删除集群:
            kubectl config delete-cluster my-cluster
        c.用户配置
            kubectl config get-users                                                 --查看所有用户
            -------------------------------------------------------------------------------------------------
            添加用户:
            kubectl config set-credentials my-user \
              --client-certificate=/path/to/client.crt \
              --client-key=/path/to/client.key
            -------------------------------------------------------------------------------------------------
            使用Token认证:
            kubectl config set-credentials my-user --token=<token>
        d.合并配置文件
            export KUBECONFIG=~/.kube/config:~/.kube/config2                         --临时合并
            -------------------------------------------------------------------------------------------------
            永久合并:
            KUBECONFIG=~/.kube/config:~/.kube/config2 kubectl config view --flatten > ~/.kube/merged-config
            mv ~/.kube/merged-config ~/.kube/config
    b.上下文切换
        a.查看上下文
            kubectl config get-contexts                                              --查看所有上下文
            kubectl config current-context                                           --查看当前上下文
        b.创建上下文
            kubectl config set-context my-context \
              --cluster=my-cluster \
              --user=my-user \
              --namespace=default
        c.切换上下文
            kubectl config use-context my-context                                    --切换到指定上下文
            -------------------------------------------------------------------------------------------------
            临时使用不同上下文:
            kubectl get pods --context=other-context
        d.修改当前命名空间
            kubectl config set-context --current --namespace=my-namespace            --修改当前上下文的命名空间
        e.重命名上下文
            kubectl config rename-context old-name new-name
        f.删除上下文
            kubectl config delete-context my-context
    c.命令补全
        a.Bash补全
            安装bash-completion:
            apt-get install bash-completion                                          --Ubuntu/Debian
            yum install bash-completion                                              --CentOS/RHEL
            -------------------------------------------------------------------------------------------------
            启用kubectl补全:
            echo 'source <(kubectl completion bash)' >>~/.bashrc
            source ~/.bashrc
            -------------------------------------------------------------------------------------------------
            设置别名补全:
            echo 'alias k=kubectl' >>~/.bashrc
            echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
        b.Zsh补全
            echo 'source <(kubectl completion zsh)' >>~/.zshrc
            source ~/.zshrc
            -------------------------------------------------------------------------------------------------
            如果遇到问题,可能需要:
            echo 'autoload -Uz compinit' >>~/.zshrc
            echo 'compinit' >>~/.zshrc
        c.Fish补全
            kubectl completion fish | source
            -------------------------------------------------------------------------------------------------
            永久启用:
            kubectl completion fish > ~/.config/fish/completions/kubectl.fish
        d.常用别名
            alias k='kubectl'
            alias kg='kubectl get'
            alias kd='kubectl describe'
            alias kdel='kubectl delete'
            alias kl='kubectl logs'
            alias ke='kubectl edit'
            alias kx='kubectl exec -it'
            alias ka='kubectl apply -f'

02.资源查看
    a.get命令
        a.查看Pod
            kubectl get pods                                                         --当前命名空间的Pod
            kubectl get pods -A                                                      --所有命名空间的Pod
            kubectl get pods -n kube-system                                          --指定命名空间
            kubectl get pods -o wide                                                 --详细信息(节点、IP等)
            kubectl get pods -o json                                                 --JSON格式输出
            kubectl get pods -o yaml                                                 --YAML格式输出
            kubectl get pods --show-labels                                           --显示标签
            kubectl get pods -l app=nginx                                            --按标签过滤
            kubectl get pods --field-selector status.phase=Running                   --按字段过滤
            kubectl get pods --sort-by=.metadata.creationTimestamp                   --按创建时间排序
        b.查看Deployment
            kubectl get deployments                                                  --查看Deployment
            kubectl get deploy                                                       --缩写形式
            kubectl get deploy -o wide                                               --详细信息
            kubectl get deploy nginx -o yaml                                         --查看YAML配置
        c.查看Service
            kubectl get services                                                     --查看Service
            kubectl get svc                                                          --缩写形式
            kubectl get svc -o wide                                                  --显示Endpoints
        d.查看所有资源
            kubectl get all                                                          --当前命名空间所有资源
            kubectl get all -A                                                       --所有命名空间
            -------------------------------------------------------------------------------------------------
            注意:get all不包括ConfigMap、Secret、PVC等资源
        e.自定义输出
            kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName
            -------------------------------------------------------------------------------------------------
            输出示例:
            NAME                     STATUS    NODE
            nginx-7c5ddbdf54-abc12   Running   node1
            nginx-7c5ddbdf54-def34   Running   node2
        f.监听资源变化
            kubectl get pods -w                                                      --实时监听Pod变化
            kubectl get pods -w -o wide                                              --监听并显示详细信息
    b.describe命令
        a.查看Pod详情
            kubectl describe pod nginx-7c5ddbdf54-abc12                              --查看Pod详细信息
            -------------------------------------------------------------------------------------------------
            输出包含:
            基本信息:名称、命名空间、标签、状态
            容器信息:镜像、端口、资源限制
            条件:初始化状态、就绪状态
            事件:创建、调度、拉取镜像等事件
        b.查看Deployment详情
            kubectl describe deployment nginx                                        --查看Deployment详情
            -------------------------------------------------------------------------------------------------
            输出包含:
            副本信息:期望副本、当前副本、可用副本
            策略配置:更新策略、滚动更新参数
            Pod模板:容器配置、卷挂载
            事件:扩缩容、滚动更新事件
        c.查看Service详情
            kubectl describe service nginx                                           --查看Service详情
            -------------------------------------------------------------------------------------------------
            输出包含:
            类型:ClusterIP、NodePort、LoadBalancer
            IP地址:ClusterIP、ExternalIP
            端口映射:Port、TargetPort、NodePort
            Endpoints:后端Pod列表
        d.查看Node详情
            kubectl describe node node1                                              --查看节点详情
            -------------------------------------------------------------------------------------------------
            输出包含:
            节点信息:操作系统、内核版本、容器运行时
            资源容量:CPU、内存、Pod数量
            资源分配:已分配资源、可用资源
            条件:Ready、MemoryPressure、DiskPressure
            运行的Pod列表
        e.查看事件
            kubectl describe pod nginx | grep -A 10 Events                           --只查看事件部分
    c.logs命令
        a.查看Pod日志
            kubectl logs nginx-7c5ddbdf54-abc12                                      --查看Pod日志
            kubectl logs nginx-7c5ddbdf54-abc12 -f                                   --实时跟踪日志
            kubectl logs nginx-7c5ddbdf54-abc12 --tail=100                           --最后100行
            kubectl logs nginx-7c5ddbdf54-abc12 --since=1h                           --最近1小时的日志
            kubectl logs nginx-7c5ddbdf54-abc12 --since-time=2023-12-16T10:00:00Z   --指定时间之后的日志
        b.多容器Pod日志
            kubectl logs nginx-7c5ddbdf54-abc12 -c nginx                             --指定容器
            kubectl logs nginx-7c5ddbdf54-abc12 --all-containers=true                --所有容器日志
        c.查看之前容器的日志
            kubectl logs nginx-7c5ddbdf54-abc12 --previous                           --查看崩溃前的日志
        d.按标签查看日志
            kubectl logs -l app=nginx                                                --查看所有匹配标签的Pod日志
            kubectl logs -l app=nginx -f                                             --实时跟踪
        e.导出日志
            kubectl logs nginx-7c5ddbdf54-abc12 > nginx.log                          --导出到文件
            kubectl logs nginx-7c5ddbdf54-abc12 --since=1h > nginx-recent.log        --导出最近日志

03.资源操作
    a.create/apply
        a.create命令
            kubectl create -f nginx.yaml                                             --从文件创建资源
            kubectl create -f ./manifests/                                           --从目录创建资源
            kubectl create -f https://example.com/nginx.yaml                         --从URL创建
            -------------------------------------------------------------------------------------------------
            快速创建资源:
            kubectl create deployment nginx --image=nginx:1.21                       --创建Deployment
            kubectl create service clusterip nginx --tcp=80:80                       --创建Service
            kubectl create configmap my-config --from-literal=key1=value1            --创建ConfigMap
            kubectl create secret generic my-secret --from-literal=password=123456   --创建Secret
            kubectl create namespace dev                                             --创建命名空间
            -------------------------------------------------------------------------------------------------
            生成YAML模板:
            kubectl create deployment nginx --image=nginx:1.21 --dry-run=client -o yaml > nginx-deploy.yaml
        b.apply命令
            kubectl apply -f nginx.yaml                                              --应用配置(创建或更新)
            kubectl apply -f ./manifests/                                            --应用目录中所有配置
            kubectl apply -R -f ./manifests/                                         --递归应用子目录
            -------------------------------------------------------------------------------------------------
            声明式管理:
            kubectl apply -f nginx.yaml                                              --第一次创建
            vim nginx.yaml                                                           --修改配置
            kubectl apply -f nginx.yaml                                              --第二次更新
        c.create vs apply
            create                                                                   命令式创建,资源必须不存在
                                                                                     重复执行会报错
            apply                                                                    声明式管理,可重复执行
                                                                                     推荐使用,支持增量更新
        d.从标准输入创建
            cat <<EOF | kubectl apply -f -
            apiVersion: v1
            kind: Pod
            metadata:
              name: nginx
            spec:
              containers:
              - name: nginx
                image: nginx:1.21
            EOF
    b.edit/patch
        a.edit命令
            kubectl edit deployment nginx                                            --使用默认编辑器编辑
            kubectl edit deployment nginx -o yaml                                    --强制使用YAML格式
            -------------------------------------------------------------------------------------------------
            设置默认编辑器:
            export KUBE_EDITOR="vim"                                                 --使用vim
            export KUBE_EDITOR="nano"                                                --使用nano
            -------------------------------------------------------------------------------------------------
            编辑后自动应用,保存即生效
        b.patch命令(JSON Patch)
            kubectl patch deployment nginx -p '{"spec":{"replicas":3}}'              --修改副本数
            -------------------------------------------------------------------------------------------------
            修改镜像:
            kubectl patch deployment nginx -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.22"}]}}}}'
        c.patch命令(Merge Patch)
            kubectl patch deployment nginx --type merge -p '
            spec:
              replicas: 5
            '
        d.patch命令(Strategic Merge Patch)
            kubectl patch deployment nginx --type strategic -p '
            spec:
              template:
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.22
            '
        e.实用patch示例
            修改副本数:
            kubectl patch deployment nginx -p '{"spec":{"replicas":5}}'
            -------------------------------------------------------------------------------------------------
            添加标签:
            kubectl patch deployment nginx -p '{"metadata":{"labels":{"env":"prod"}}}'
            -------------------------------------------------------------------------------------------------
            修改资源限制:
            kubectl patch deployment nginx -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","resources":{"limits":{"cpu":"200m"}}}]}}}}'
    c.delete命令
        a.删除资源
            kubectl delete pod nginx                                                 --删除Pod
            kubectl delete deployment nginx                                          --删除Deployment
            kubectl delete service nginx                                             --删除Service
            kubectl delete -f nginx.yaml                                             --根据文件删除
            kubectl delete -f ./manifests/                                           --删除目录中所有资源
        b.按标签删除
            kubectl delete pods -l app=nginx                                         --删除匹配标签的Pod
            kubectl delete all -l app=nginx                                          --删除所有匹配资源
        c.删除所有资源
            kubectl delete pods --all                                                --删除当前命名空间所有Pod
            kubectl delete all --all                                                 --删除当前命名空间所有资源
            kubectl delete namespace dev                                             --删除命名空间及其所有资源
        d.强制删除
            kubectl delete pod nginx --force --grace-period=0                        --立即删除,不等待优雅终止
            -------------------------------------------------------------------------------------------------
            注意:强制删除可能导致数据丢失,谨慎使用
        e.删除卡住的资源
            kubectl delete pod nginx --grace-period=0 --force                        --强制删除
            -------------------------------------------------------------------------------------------------
            如果仍然无法删除,移除finalizer:
            kubectl patch pod nginx -p '{"metadata":{"finalizers":null}}'

04.调试命令
    a.exec进入容器
        a.基本用法
            kubectl exec -it nginx-7c5ddbdf54-abc12 -- /bin/bash                     --进入容器bash
            kubectl exec -it nginx-7c5ddbdf54-abc12 -- sh                            --进入容器sh
        b.多容器Pod
            kubectl exec -it nginx-7c5ddbdf54-abc12 -c nginx -- /bin/bash            --指定容器
        c.执行单条命令
            kubectl exec nginx-7c5ddbdf54-abc12 -- ls -la /etc                       --查看目录
            kubectl exec nginx-7c5ddbdf54-abc12 -- cat /etc/nginx/nginx.conf         --查看文件
            kubectl exec nginx-7c5ddbdf54-abc12 -- env                               --查看环境变量
            kubectl exec nginx-7c5ddbdf54-abc12 -- ps aux                            --查看进程
        d.常用调试命令
            kubectl exec nginx-7c5ddbdf54-abc12 -- curl localhost:80                 --测试HTTP
            kubectl exec nginx-7c5ddbdf54-abc12 -- netstat -tlnp                     --查看端口
            kubectl exec nginx-7c5ddbdf54-abc12 -- df -h                             --查看磁盘
            kubectl exec nginx-7c5ddbdf54-abc12 -- free -h                           --查看内存
    b.port-forward端口转发
        a.转发Pod端口
            kubectl port-forward pod/nginx-7c5ddbdf54-abc12 8080:80                  --本地8080映射到Pod的80
            -------------------------------------------------------------------------------------------------
            访问:http://localhost:8080
        b.转发Service端口
            kubectl port-forward service/nginx 8080:80                               --转发Service端口
        c.转发Deployment端口
            kubectl port-forward deployment/nginx 8080:80                            --转发Deployment端口
        d.指定监听地址
            kubectl port-forward --address 0.0.0.0 pod/nginx 8080:80                 --允许外部访问
            kubectl port-forward --address 192.168.1.10 pod/nginx 8080:80            --指定监听IP
        e.后台运行
            kubectl port-forward pod/nginx 8080:80 &                                 --后台运行
            -------------------------------------------------------------------------------------------------
            查看后台任务:
            jobs
            -------------------------------------------------------------------------------------------------
            停止转发:
            kill %1                                                                  --结束后台任务
    c.cp文件复制
        a.从Pod复制到本地
            kubectl cp nginx-7c5ddbdf54-abc12:/etc/nginx/nginx.conf ./nginx.conf    --复制文件
            kubectl cp nginx-7c5ddbdf54-abc12:/var/log/nginx/ ./logs/               --复制目录
        b.从本地复制到Pod
            kubectl cp ./nginx.conf nginx-7c5ddbdf54-abc12:/etc/nginx/nginx.conf    --上传文件
            kubectl cp ./html/ nginx-7c5ddbdf54-abc12:/usr/share/nginx/html/        --上传目录
        c.多容器Pod
            kubectl cp nginx-7c5ddbdf54-abc12:/app/config.yaml ./config.yaml -c nginx  --指定容器
        d.跨命名空间
            kubectl cp -n production nginx:/app/config.yaml ./config.yaml            --指定命名空间
        e.注意事项
            cp命令依赖tar命令,容器内必须有tar
            不支持通配符
            大文件传输可能较慢

05.高级命令
    a.top资源监控
        a.查看节点资源
            kubectl top nodes                                                        --查看节点CPU和内存使用
            kubectl top nodes --sort-by=cpu                                          --按CPU排序
            kubectl top nodes --sort-by=memory                                       --按内存排序
            -------------------------------------------------------------------------------------------------
            输出示例:
            NAME    CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
            node1   250m         12%    2048Mi          25%
            node2   180m         9%     1536Mi          19%
        b.查看Pod资源
            kubectl top pods                                                         --查看Pod资源使用
            kubectl top pods -A                                                      --所有命名空间
            kubectl top pods --containers                                            --显示容器级别
            kubectl top pods -l app=nginx                                            --按标签过滤
            kubectl top pods --sort-by=cpu                                           --按CPU排序
            kubectl top pods --sort-by=memory                                        --按内存排序
        c.要求
            需要安装Metrics Server:
            kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get deployment metrics-server -n kube-system
    b.rollout滚动更新
        a.更新镜像
            kubectl set image deployment/nginx nginx=nginx:1.22                      --更新镜像
            -------------------------------------------------------------------------------------------------
            或使用rollout:
            kubectl rollout restart deployment/nginx                                 --重启Deployment
        b.查看更新状态
            kubectl rollout status deployment/nginx                                  --查看滚动更新状态
            -------------------------------------------------------------------------------------------------
            输出示例:
            Waiting for deployment "nginx" rollout to finish: 1 out of 3 new replicas have been updated...
            deployment "nginx" successfully rolled out
        c.查看历史版本
            kubectl rollout history deployment/nginx                                 --查看历史版本
            kubectl rollout history deployment/nginx --revision=2                    --查看指定版本详情
        d.回滚
            kubectl rollout undo deployment/nginx                                    --回滚到上一版本
            kubectl rollout undo deployment/nginx --to-revision=2                    --回滚到指定版本
        e.暂停和恢复
            kubectl rollout pause deployment/nginx                                   --暂停更新
            kubectl set image deployment/nginx nginx=nginx:1.22                      --修改配置(不会触发更新)
            kubectl rollout resume deployment/nginx                                  --恢复更新
    c.scale扩缩容
        a.手动扩缩容
            kubectl scale deployment nginx --replicas=5                              --扩展到5个副本
            kubectl scale deployment nginx --replicas=1                              --缩减到1个副本
        b.按条件扩缩容
            kubectl scale deployment nginx --replicas=3 --current-replicas=2         --只在当前为2个副本时执行
        c.扩缩多个资源
            kubectl scale deployment/nginx deployment/apache --replicas=3            --同时扩展多个
        d.自动扩缩容(HPA)
            kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80     --创建HPA
            -------------------------------------------------------------------------------------------------
            查看HPA:
            kubectl get hpa
            -------------------------------------------------------------------------------------------------
            输出示例:
            NAME    REFERENCE          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
            nginx   Deployment/nginx   45%/80%   2         10        3          5m
        e.删除HPA
            kubectl delete hpa nginx

06.常用命令汇总
    a.快速查看
        kubectl get pods -o wide                                                     --查看Pod详情
        kubectl get nodes                                                            --查看节点
        kubectl get svc                                                              --查看Service
        kubectl get deploy                                                           --查看Deployment
        kubectl get all -A                                                           --查看所有资源
    b.快速调试
        kubectl describe pod <pod-name>                                              --查看Pod详情
        kubectl logs <pod-name> -f                                                   --实时查看日志
        kubectl exec -it <pod-name> -- /bin/bash                                     --进入容器
        kubectl port-forward <pod-name> 8080:80                                      --端口转发
    c.快速操作
        kubectl apply -f <file.yaml>                                                 --应用配置
        kubectl delete -f <file.yaml>                                                --删除资源
        kubectl scale deployment <name> --replicas=3                                 --扩缩容
        kubectl rollout restart deployment/<name>                                    --重启
        kubectl rollout undo deployment/<name>                                       --回滚
    d.常用组合
        查看Pod并进入:
        kubectl get pods
        kubectl exec -it <pod-name> -- /bin/bash
        -------------------------------------------------------------------------------------------------
        查看日志并跟踪:
        kubectl logs <pod-name> -f --tail=100
        -------------------------------------------------------------------------------------------------
        删除异常Pod:
        kubectl get pods | grep Error
        kubectl delete pod <pod-name> --force --grace-period=0
        -------------------------------------------------------------------------------------------------
        批量操作:
        kubectl get pods -l app=nginx -o name | xargs kubectl delete

3.6 [2]resource

01.工作负载资源
    a.Pod详解
        a.Pod基本概念
            Kubernetes中最小的调度单位
            一个Pod可以包含一个或多个容器
            Pod内容器共享网络命名空间和存储卷
            Pod是临时性的,不会自我修复
        b.创建Pod
            YAML示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: nginx-pod
              namespace: default
              labels:
                app: nginx
                env: prod
            spec:
              containers:
              - name: nginx
                image: nginx:1.21
                ports:
                - containerPort: 80
                resources:
                  requests:
                    memory: "64Mi"
                    cpu: "250m"
                  limits:
                    memory: "128Mi"
                    cpu: "500m"
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-pod.yaml                                     --创建Pod
        c.多容器Pod
            YAML示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: multi-container-pod
            spec:
              containers:
              - name: nginx
                image: nginx:1.21
                ports:
                - containerPort: 80
              - name: busybox
                image: busybox
                command: ['sh', '-c', 'while true; do echo $(date) >> /var/log/date.log; sleep 10; done']
                volumeMounts:
                - name: log-volume
                  mountPath: /var/log
              volumes:
              - name: log-volume
                emptyDir: {}
        d.Init容器
            YAML示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: init-pod
            spec:
              initContainers:
              - name: init-service
                image: busybox
                command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done']
              containers:
              - name: main-app
                image: nginx:1.21
            -------------------------------------------------------------------------------------------------
            Init容器特点:
            在主容器启动前运行
            按顺序依次执行
            必须全部成功才会启动主容器
            适合初始化任务、等待依赖服务等场景
        e.Pod生命周期
            阶段说明:
            Pending                                                              Pod已创建,等待调度或拉取镜像
            Running                                                              至少有一个容器正在运行
            Succeeded                                                            所有容器成功终止
            Failed                                                               至少有一个容器失败终止
            Unknown                                                              无法获取Pod状态
            -------------------------------------------------------------------------------------------------
            查看Pod状态:
            kubectl get pods                                                     --查看Pod状态
            kubectl describe pod <pod-name>                                      --查看详细信息
        f.容器探针
            LivenessProbe示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: liveness-pod
            spec:
              containers:
              - name: nginx
                image: nginx:1.21
                livenessProbe:
                  httpGet:
                    path: /healthz
                    port: 80
                  initialDelaySeconds: 3
                  periodSeconds: 3
            -------------------------------------------------------------------------------------------------
            ReadinessProbe示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: readiness-pod
            spec:
              containers:
              - name: nginx
                image: nginx:1.21
                readinessProbe:
                  httpGet:
                    path: /ready
                    port: 80
                  initialDelaySeconds: 5
                  periodSeconds: 5
            -------------------------------------------------------------------------------------------------
            StartupProbe示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: startup-pod
            spec:
              containers:
              - name: slow-app
                image: myapp:latest
                startupProbe:
                  httpGet:
                    path: /startup
                    port: 8080
                  failureThreshold: 30
                  periodSeconds: 10
            -------------------------------------------------------------------------------------------------
            探针类型对比:
            LivenessProbe                                                        检测容器是否存活,失败则重启容器
            ReadinessProbe                                                       检测容器是否就绪,失败则从Service移除
            StartupProbe                                                         检测容器是否启动完成,适合慢启动应用
        g.资源限制
            requests和limits示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: resource-pod
            spec:
              containers:
              - name: app
                image: myapp:latest
                resources:
                  requests:                                                      --最小资源请求
                    memory: "128Mi"
                    cpu: "250m"
                  limits:                                                        --最大资源限制
                    memory: "256Mi"
                    cpu: "500m"
            -------------------------------------------------------------------------------------------------
            QoS等级:
            Guaranteed                                                           requests == limits,最高优先级
            Burstable                                                            requests < limits,中等优先级
            BestEffort                                                           未设置requests/limits,最低优先级
    b.Deployment详解
        a.基本概念
            用于管理无状态应用
            支持滚动更新和回滚
            自动维护指定数量的Pod副本
            通过ReplicaSet管理Pod
        b.创建Deployment
            YAML示例:
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment
              namespace: default
              labels:
                app: nginx
            spec:
              replicas: 3                                                        --副本数量
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.21
                    ports:
                    - containerPort: 80
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-deployment.yaml                               --创建Deployment
            kubectl get deployments                                              --查看Deployment
            kubectl get rs                                                       --查看ReplicaSet
            kubectl get pods                                                     --查看Pod
        c.更新策略
            滚动更新(RollingUpdate):
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment
            spec:
              replicas: 3
              strategy:
                type: RollingUpdate
                rollingUpdate:
                  maxSurge: 1                                                    --最多超出副本数1个
                  maxUnavailable: 1                                              --最多不可用副本数1个
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.22
            -------------------------------------------------------------------------------------------------
            重建更新(Recreate):
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment
            spec:
              replicas: 3
              strategy:
                type: Recreate                                                   --先删除所有旧Pod,再创建新Pod
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.22
        d.滚动更新操作
            kubectl set image deployment/nginx-deployment nginx=nginx:1.22       --更新镜像
            kubectl rollout status deployment/nginx-deployment                   --查看更新状态
            kubectl rollout history deployment/nginx-deployment                  --查看历史版本
            kubectl rollout undo deployment/nginx-deployment                     --回滚到上一版本
            kubectl rollout undo deployment/nginx-deployment --to-revision=2     --回滚到指定版本
            kubectl rollout pause deployment/nginx-deployment                    --暂停更新
            kubectl rollout resume deployment/nginx-deployment                   --恢复更新
        e.扩缩容
            kubectl scale deployment nginx-deployment --replicas=5               --手动扩容到5个副本
            kubectl scale deployment nginx-deployment --replicas=1               --手动缩容到1个副本
            -------------------------------------------------------------------------------------------------
            自动扩缩容(HPA):
            kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=80
            kubectl get hpa                                                      --查看HPA状态
        f.常用操作
            kubectl get deployment nginx-deployment -o yaml                      --导出YAML配置
            kubectl edit deployment nginx-deployment                             --在线编辑
            kubectl delete deployment nginx-deployment                           --删除Deployment
            kubectl describe deployment nginx-deployment                         --查看详细信息
    c.StatefulSet详解
        a.基本概念
            用于管理有状态应用
            提供稳定的网络标识符
            提供稳定的持久化存储
            有序的部署、扩展、删除和滚动更新
        b.创建StatefulSet
            YAML示例:
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-headless
            spec:
              clusterIP: None                                                    --Headless Service
              selector:
                app: nginx-stateful
              ports:
              - port: 80
            ---
            apiVersion: apps/v1
            kind: StatefulSet
            metadata:
              name: nginx-stateful
            spec:
              serviceName: nginx-headless                                        --关联Headless Service
              replicas: 3
              selector:
                matchLabels:
                  app: nginx-stateful
              template:
                metadata:
                  labels:
                    app: nginx-stateful
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.21
                    ports:
                    - containerPort: 80
                    volumeMounts:
                    - name: data
                      mountPath: /usr/share/nginx/html
              volumeClaimTemplates:
              - metadata:
                  name: data
                spec:
                  accessModes: [ "ReadWriteOnce" ]
                  resources:
                    requests:
                      storage: 1Gi
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-statefulset.yaml                              --创建StatefulSet
        c.StatefulSet特性
            Pod命名规则:
            <statefulset-name>-0
            <statefulset-name>-1
            <statefulset-name>-2
            -------------------------------------------------------------------------------------------------
            DNS记录:
            <pod-name>.<service-name>.<namespace>.svc.cluster.local
            示例:
            nginx-stateful-0.nginx-headless.default.svc.cluster.local
            nginx-stateful-1.nginx-headless.default.svc.cluster.local
            -------------------------------------------------------------------------------------------------
            存储特性:
            每个Pod有独立的PVC
            PVC不会随Pod删除而删除
            重新创建Pod会关联到相同的PVC
        d.扩缩容
            kubectl scale statefulset nginx-stateful --replicas=5                --扩容
            kubectl scale statefulset nginx-stateful --replicas=1                --缩容
            -------------------------------------------------------------------------------------------------
            扩缩容特点:
            按顺序创建Pod(0,1,2,3,4)
            按逆序删除Pod(4,3,2,1,0)
            必须等待前一个Pod就绪才会创建下一个
        e.更新策略
            滚动更新(RollingUpdate):
            apiVersion: apps/v1
            kind: StatefulSet
            metadata:
              name: nginx-stateful
            spec:
              updateStrategy:
                type: RollingUpdate
                rollingUpdate:
                  partition: 2                                                   --只更新序号>=2的Pod
              replicas: 3
              serviceName: nginx-headless
              selector:
                matchLabels:
                  app: nginx-stateful
              template:
                metadata:
                  labels:
                    app: nginx-stateful
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.22
            -------------------------------------------------------------------------------------------------
            OnDelete策略:
            apiVersion: apps/v1
            kind: StatefulSet
            metadata:
              name: nginx-stateful
            spec:
              updateStrategy:
                type: OnDelete                                                   --手动删除Pod才会更新
        f.常用操作
            kubectl get statefulset                                              --查看StatefulSet
            kubectl get pods -l app=nginx-stateful                               --查看Pod
            kubectl delete statefulset nginx-stateful                            --删除StatefulSet
            kubectl delete statefulset nginx-stateful --cascade=orphan           --删除StatefulSet但保留Pod
    d.DaemonSet详解
        a.基本概念
            在每个节点上运行一个Pod副本
            新节点加入时自动创建Pod
            节点移除时自动删除Pod
            适合运行集群级别的守护进程
        b.创建DaemonSet
            YAML示例:
            apiVersion: apps/v1
            kind: DaemonSet
            metadata:
              name: fluentd-daemonset
              namespace: kube-system
              labels:
                app: fluentd
            spec:
              selector:
                matchLabels:
                  app: fluentd
              template:
                metadata:
                  labels:
                    app: fluentd
                spec:
                  containers:
                  - name: fluentd
                    image: fluentd:v1.14
                    volumeMounts:
                    - name: varlog
                      mountPath: /var/log
                    - name: varlibdockercontainers
                      mountPath: /var/lib/docker/containers
                      readOnly: true
                  volumes:
                  - name: varlog
                    hostPath:
                      path: /var/log
                  - name: varlibdockercontainers
                    hostPath:
                      path: /var/lib/docker/containers
            -------------------------------------------------------------------------------------------------
            kubectl apply -f fluentd-daemonset.yaml                              --创建DaemonSet
        c.节点选择
            使用nodeSelector:
            apiVersion: apps/v1
            kind: DaemonSet
            metadata:
              name: nginx-daemonset
            spec:
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  nodeSelector:
                    disk: ssd                                                    --只在有ssd标签的节点运行
                  containers:
                  - name: nginx
                    image: nginx:1.21
            -------------------------------------------------------------------------------------------------
            使用nodeAffinity:
            apiVersion: apps/v1
            kind: DaemonSet
            metadata:
              name: nginx-daemonset
            spec:
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  affinity:
                    nodeAffinity:
                      requiredDuringSchedulingIgnoredDuringExecution:
                        nodeSelectorTerms:
                        - matchExpressions:
                          - key: node-role.kubernetes.io/worker
                            operator: Exists
                  containers:
                  - name: nginx
                    image: nginx:1.21
        d.更新策略
            滚动更新(RollingUpdate):
            apiVersion: apps/v1
            kind: DaemonSet
            metadata:
              name: fluentd-daemonset
            spec:
              updateStrategy:
                type: RollingUpdate
                rollingUpdate:
                  maxUnavailable: 1                                              --最多1个节点不可用
              selector:
                matchLabels:
                  app: fluentd
              template:
                metadata:
                  labels:
                    app: fluentd
                spec:
                  containers:
                  - name: fluentd
                    image: fluentd:v1.15
            -------------------------------------------------------------------------------------------------
            OnDelete策略:
            apiVersion: apps/v1
            kind: DaemonSet
            metadata:
              name: fluentd-daemonset
            spec:
              updateStrategy:
                type: OnDelete                                                   --手动删除Pod才会更新
        e.常用场景
            日志收集:
            fluentd、filebeat等日志收集器
            -------------------------------------------------------------------------------------------------
            监控代理:
            node-exporter、cAdvisor等监控工具
            -------------------------------------------------------------------------------------------------
            网络插件:
            calico-node、kube-proxy等网络组件
            -------------------------------------------------------------------------------------------------
            存储插件:
            ceph-osd、glusterd等存储组件
        f.常用操作
            kubectl get daemonset -A                                             --查看所有DaemonSet
            kubectl describe daemonset fluentd-daemonset -n kube-system          --查看详细信息
            kubectl delete daemonset fluentd-daemonset -n kube-system            --删除DaemonSet
    e.Job/CronJob详解
        a.Job基本概念
            用于运行一次性任务
            确保Pod成功完成指定次数
            支持并行执行
            任务完成后Pod不会自动删除
        b.创建Job
            YAML示例:
            apiVersion: batch/v1
            kind: Job
            metadata:
              name: pi-job
            spec:
              completions: 5                                                     --成功完成5次
              parallelism: 2                                                     --并行度为2
              template:
                spec:
                  containers:
                  - name: pi
                    image: perl:5.34
                    command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
                  restartPolicy: Never                                           --失败不重启
              backoffLimit: 4                                                    --最多重试4次
            -------------------------------------------------------------------------------------------------
            kubectl apply -f pi-job.yaml                                         --创建Job
            kubectl get jobs                                                     --查看Job状态
            kubectl get pods                                                     --查看Job的Pod
        c.Job完成模式
            Non-parallel Jobs:
            apiVersion: batch/v1
            kind: Job
            metadata:
              name: single-job
            spec:
              template:
                spec:
                  containers:
                  - name: busybox
                    image: busybox
                    command: ['sh', '-c', 'echo Hello && sleep 30']
                  restartPolicy: Never
            -------------------------------------------------------------------------------------------------
            Parallel Jobs with fixed completion count:
            apiVersion: batch/v1
            kind: Job
            metadata:
              name: parallel-job
            spec:
              completions: 10                                                    --完成10次
              parallelism: 3                                                     --同时运行3个Pod
              template:
                spec:
                  containers:
                  - name: busybox
                    image: busybox
                    command: ['sh', '-c', 'echo Processing && sleep 10']
                  restartPolicy: Never
            -------------------------------------------------------------------------------------------------
            Parallel Jobs with work queue:
            apiVersion: batch/v1
            kind: Job
            metadata:
              name: queue-job
            spec:
              parallelism: 5                                                     --并行度为5
              template:
                spec:
                  containers:
                  - name: worker
                    image: myworker:latest
                    command: ['./worker']
                  restartPolicy: Never
        d.CronJob基本概念
            用于定时任务
            基于Cron表达式调度
            自动创建Job
            支持任务历史记录管理
        e.创建CronJob
            YAML示例:
            apiVersion: batch/v1
            kind: CronJob
            metadata:
              name: hello-cronjob
            spec:
              schedule: "*/5 * * * *"                                            --每5分钟执行一次
              jobTemplate:
                spec:
                  template:
                    spec:
                      containers:
                      - name: hello
                        image: busybox
                        command: ['sh', '-c', 'echo Hello from CronJob']
                      restartPolicy: OnFailure
              successfulJobsHistoryLimit: 3                                      --保留3个成功的Job
              failedJobsHistoryLimit: 1                                          --保留1个失败的Job
            -------------------------------------------------------------------------------------------------
            kubectl apply -f hello-cronjob.yaml                                  --创建CronJob
        f.Cron表达式
            格式说明:
            * * * * *
            │ │ │ │ │
            │ │ │ │ └─ 星期几 (0-6, 0表示周日)
            │ │ │ └─── 月份 (1-12)
            │ │ └───── 日期 (1-31)
            │ └─────── 小时 (0-23)
            └───────── 分钟 (0-59)
            -------------------------------------------------------------------------------------------------
            常用示例:
            */5 * * * *                                                          --每5分钟
            0 * * * *                                                            --每小时
            0 0 * * *                                                            --每天午夜
            0 0 * * 0                                                            --每周日午夜
            0 0 1 * *                                                            --每月1号午夜
            0 2 * * 1-5                                                          --工作日凌晨2点
        g.CronJob并发策略
            Allow(默认):
            apiVersion: batch/v1
            kind: CronJob
            metadata:
              name: cronjob-allow
            spec:
              schedule: "*/1 * * * *"
              concurrencyPolicy: Allow                                           --允许并发执行
              jobTemplate:
                spec:
                  template:
                    spec:
                      containers:
                      - name: job
                        image: busybox
                        command: ['sh', '-c', 'sleep 120']
                      restartPolicy: OnFailure
            -------------------------------------------------------------------------------------------------
            Forbid:
            apiVersion: batch/v1
            kind: CronJob
            metadata:
              name: cronjob-forbid
            spec:
              schedule: "*/1 * * * *"
              concurrencyPolicy: Forbid                                          --禁止并发,跳过新任务
              jobTemplate:
                spec:
                  template:
                    spec:
                      containers:
                      - name: job
                        image: busybox
                        command: ['sh', '-c', 'sleep 120']
                      restartPolicy: OnFailure
            -------------------------------------------------------------------------------------------------
            Replace:
            apiVersion: batch/v1
            kind: CronJob
            metadata:
              name: cronjob-replace
            spec:
              schedule: "*/1 * * * *"
              concurrencyPolicy: Replace                                         --替换旧任务
              jobTemplate:
                spec:
                  template:
                    spec:
                      containers:
                      - name: job
                        image: busybox
                        command: ['sh', '-c', 'sleep 120']
                      restartPolicy: OnFailure
        h.常用操作
            kubectl get cronjobs                                                 --查看CronJob
            kubectl get jobs                                                     --查看Job
            kubectl describe cronjob hello-cronjob                               --查看详细信息
            kubectl delete cronjob hello-cronjob                                 --删除CronJob

02.配置资源
    a.ConfigMap详解
        a.基本概念
            用于存储非机密的配置数据
            以键值对形式存储
            可以被Pod引用
            支持多种使用方式
        b.创建ConfigMap
            从字面值创建:
            kubectl create configmap app-config \
              --from-literal=db_host=mysql.example.com \
              --from-literal=db_port=3306 \
              --from-literal=log_level=info
            -------------------------------------------------------------------------------------------------
            从文件创建:
            echo "server {}" > nginx.conf
            kubectl create configmap nginx-config --from-file=nginx.conf
            -------------------------------------------------------------------------------------------------
            从目录创建:
            kubectl create configmap app-configs --from-file=./configs/
            -------------------------------------------------------------------------------------------------
            从YAML创建:
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: app-config
              namespace: default
            data:
              db_host: mysql.example.com
              db_port: "3306"
              log_level: info
              application.properties: |
                server.port=8080
                spring.datasource.url=jdbc:mysql://mysql:3306/mydb
            -------------------------------------------------------------------------------------------------
            kubectl apply -f app-config.yaml
        c.使用ConfigMap
            环境变量方式:
            apiVersion: v1
            kind: Pod
            metadata:
              name: config-env-pod
            spec:
              containers:
              - name: app
                image: busybox
                command: ['sh', '-c', 'echo DB_HOST=$DB_HOST && sleep 3600']
                env:
                - name: DB_HOST
                  valueFrom:
                    configMapKeyRef:
                      name: app-config
                      key: db_host
                - name: DB_PORT
                  valueFrom:
                    configMapKeyRef:
                      name: app-config
                      key: db_port
            -------------------------------------------------------------------------------------------------
            全部导入环境变量:
            apiVersion: v1
            kind: Pod
            metadata:
              name: config-envfrom-pod
            spec:
              containers:
              - name: app
                image: busybox
                command: ['sh', '-c', 'env && sleep 3600']
                envFrom:
                - configMapRef:
                    name: app-config
            -------------------------------------------------------------------------------------------------
            挂载为Volume:
            apiVersion: v1
            kind: Pod
            metadata:
              name: config-volume-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: config-volume
                  mountPath: /etc/config
              volumes:
              - name: config-volume
                configMap:
                  name: app-config
            -------------------------------------------------------------------------------------------------
            挂载指定key:
            apiVersion: v1
            kind: Pod
            metadata:
              name: config-item-pod
            spec:
              containers:
              - name: nginx
                image: nginx:1.21
                volumeMounts:
                - name: config-volume
                  mountPath: /etc/nginx/nginx.conf
                  subPath: nginx.conf
              volumes:
              - name: config-volume
                configMap:
                  name: nginx-config
                  items:
                  - key: nginx.conf
                    path: nginx.conf
        d.更新ConfigMap
            kubectl edit configmap app-config                                    --在线编辑
            -------------------------------------------------------------------------------------------------
            注意事项:
            环境变量方式:需要重启Pod才能生效
            Volume挂载方式:会自动更新(可能有延迟)
        e.常用操作
            kubectl get configmaps                                               --查看ConfigMap列表
            kubectl describe configmap app-config                                --查看详细信息
            kubectl get configmap app-config -o yaml                             --导出YAML
            kubectl delete configmap app-config                                  --删除ConfigMap
    b.Secret详解
        a.基本概念
            用于存储机密数据
            数据经过Base64编码
            比ConfigMap更安全
            支持多种类型
        b.Secret类型
            Opaque                                                               通用Secret,默认类型
            kubernetes.io/service-account-token                                  ServiceAccount令牌
            kubernetes.io/dockerconfigjson                                       Docker镜像仓库认证
            kubernetes.io/tls                                                    TLS证书
            kubernetes.io/basic-auth                                             基本认证
            kubernetes.io/ssh-auth                                               SSH认证
        c.创建Secret
            从字面值创建:
            kubectl create secret generic db-secret \
              --from-literal=username=admin \
              --from-literal=password=P@ssw0rd
            -------------------------------------------------------------------------------------------------
            从文件创建:
            echo -n 'admin' > username.txt
            echo -n 'P@ssw0rd' > password.txt
            kubectl create secret generic db-secret \
              --from-file=username=username.txt \
              --from-file=password=password.txt
            -------------------------------------------------------------------------------------------------
            从YAML创建:
            apiVersion: v1
            kind: Secret
            metadata:
              name: db-secret
              namespace: default
            type: Opaque
            data:
              username: YWRtaW4=                                                  --Base64编码后的admin
              password: UEBzc3cwcmQ=                                              --Base64编码后的P@ssw0rd
            -------------------------------------------------------------------------------------------------
            kubectl apply -f db-secret.yaml
            -------------------------------------------------------------------------------------------------
            使用stringData(自动编码):
            apiVersion: v1
            kind: Secret
            metadata:
              name: db-secret
            type: Opaque
            stringData:
              username: admin
              password: P@ssw0rd
        d.创建Docker镜像仓库Secret
            kubectl create secret docker-registry harbor-secret \
              --docker-server=harbor.example.com \
              --docker-username=admin \
              --docker-password=Harbor12345 \
              [email protected]
            -------------------------------------------------------------------------------------------------
            使用示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: private-image-pod
            spec:
              containers:
              - name: app
                image: harbor.example.com/myapp:latest
              imagePullSecrets:
              - name: harbor-secret
        e.创建TLS Secret
            kubectl create secret tls tls-secret \
              --cert=path/to/tls.crt \
              --key=path/to/tls.key
            -------------------------------------------------------------------------------------------------
            使用示例:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: tls-ingress
            spec:
              tls:
              - hosts:
                - www.example.com
                secretName: tls-secret
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: web-service
                        port:
                          number: 80
        f.使用Secret
            环境变量方式:
            apiVersion: v1
            kind: Pod
            metadata:
              name: secret-env-pod
            spec:
              containers:
              - name: app
                image: busybox
                command: ['sh', '-c', 'echo USERNAME=$USERNAME && sleep 3600']
                env:
                - name: USERNAME
                  valueFrom:
                    secretKeyRef:
                      name: db-secret
                      key: username
                - name: PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: db-secret
                      key: password
            -------------------------------------------------------------------------------------------------
            挂载为Volume:
            apiVersion: v1
            kind: Pod
            metadata:
              name: secret-volume-pod
            spec:
              containers:
              - name: app
                image: busybox
                command: ['sh', '-c', 'cat /etc/secret/username && sleep 3600']
                volumeMounts:
                - name: secret-volume
                  mountPath: /etc/secret
                  readOnly: true
              volumes:
              - name: secret-volume
                secret:
                  secretName: db-secret
        g.常用操作
            kubectl get secrets                                                  --查看Secret列表
            kubectl describe secret db-secret                                    --查看详细信息
            kubectl get secret db-secret -o yaml                                 --导出YAML
            kubectl delete secret db-secret                                      --删除Secret
    c.使用示例
        a.Nginx配置示例
            创建ConfigMap:
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: nginx-config
            data:
              nginx.conf: |
                user nginx;
                worker_processes auto;
                error_log /var/log/nginx/error.log;
                pid /run/nginx.pid;

                events {
                    worker_connections 1024;
                }

                http {
                    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                                    '$status $body_bytes_sent "$http_referer" '
                                    '"$http_user_agent" "$http_x_forwarded_for"';

                    access_log /var/log/nginx/access.log main;

                    server {
                        listen 80;
                        server_name localhost;

                        location / {
                            root /usr/share/nginx/html;
                            index index.html;
                        }
                    }
                }
            -------------------------------------------------------------------------------------------------
            使用ConfigMap:
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment
            spec:
              replicas: 2
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.21
                    ports:
                    - containerPort: 80
                    volumeMounts:
                    - name: nginx-config
                      mountPath: /etc/nginx/nginx.conf
                      subPath: nginx.conf
                  volumes:
                  - name: nginx-config
                    configMap:
                      name: nginx-config
        b.MySQL配置示例
            创建Secret:
            apiVersion: v1
            kind: Secret
            metadata:
              name: mysql-secret
            type: Opaque
            stringData:
              root-password: MyR00tP@ss
              user: myuser
              password: MyUs3rP@ss
              database: mydb
            -------------------------------------------------------------------------------------------------
            创建ConfigMap:
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: mysql-config
            data:
              my.cnf: |
                [mysqld]
                character-set-server=utf8mb4
                collation-server=utf8mb4_unicode_ci
                max_connections=200
                default-time-zone='+8:00'
            -------------------------------------------------------------------------------------------------
            使用示例:
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: mysql-deployment
            spec:
              replicas: 1
              selector:
                matchLabels:
                  app: mysql
              template:
                metadata:
                  labels:
                    app: mysql
                spec:
                  containers:
                  - name: mysql
                    image: mysql:8.0
                    ports:
                    - containerPort: 3306
                    env:
                    - name: MYSQL_ROOT_PASSWORD
                      valueFrom:
                        secretKeyRef:
                          name: mysql-secret
                          key: root-password
                    - name: MYSQL_DATABASE
                      valueFrom:
                        secretKeyRef:
                          name: mysql-secret
                          key: database
                    - name: MYSQL_USER
                      valueFrom:
                        secretKeyRef:
                          name: mysql-secret
                          key: user
                    - name: MYSQL_PASSWORD
                      valueFrom:
                        secretKeyRef:
                          name: mysql-secret
                          key: password
                    volumeMounts:
                    - name: mysql-config
                      mountPath: /etc/mysql/conf.d/my.cnf
                      subPath: my.cnf
                    - name: mysql-data
                      mountPath: /var/lib/mysql
                  volumes:
                  - name: mysql-config
                    configMap:
                      name: mysql-config
                  - name: mysql-data
                    emptyDir: {}

03.服务资源
    a.Service详解
        a.基本概念
            为Pod提供稳定的网络访问入口
            通过标签选择器关联Pod
            支持负载均衡
            有固定的ClusterIP
        b.Service类型
            ClusterIP                                                            集群内部访问,默认类型
            NodePort                                                             在节点上开放端口,外部可访问
            LoadBalancer                                                         云平台负载均衡器
            ExternalName                                                         映射到外部DNS名称
        c.创建ClusterIP Service
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-service
              namespace: default
            spec:
              type: ClusterIP
              selector:
                app: nginx
              ports:
              - protocol: TCP
                port: 80                                                         --Service端口
                targetPort: 80                                                   --Pod端口
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-service.yaml
            kubectl get svc nginx-service
        d.创建NodePort Service
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-nodeport
            spec:
              type: NodePort
              selector:
                app: nginx
              ports:
              - protocol: TCP
                port: 80
                targetPort: 80
                nodePort: 30080                                                  --指定节点端口(30000-32767)
            -------------------------------------------------------------------------------------------------
            访问方式:
            curl http://<任意NodeIP>:30080
        e.会话亲和性
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-service
            spec:
              type: ClusterIP
              sessionAffinity: ClientIP                                          --基于客户端IP的会话保持
              sessionAffinityConfig:
                clientIP:
                  timeoutSeconds: 10800                                          --超时时间(默认10800秒)
              selector:
                app: nginx
              ports:
              - port: 80
                targetPort: 80
        f.Headless Service
            apiVersion: v1
            kind: Service
            metadata:
              name: nginx-headless
            spec:
              clusterIP: None                                                    --不分配ClusterIP
              selector:
                app: nginx
              ports:
              - port: 80
            -------------------------------------------------------------------------------------------------
            用途:
            StatefulSet中使用
            返回所有Pod的IP地址
            客户端可以自行选择要连接的Pod
    b.Endpoints详解
        a.基本概念
            Service与Pod之间的桥梁
            记录匹配selector的所有Pod IP
            自动创建和更新
            可以手动创建
        b.查看Endpoints
            kubectl get endpoints nginx-service                                  --查看Endpoints
            kubectl describe endpoints nginx-service                             --查看详细信息
            -------------------------------------------------------------------------------------------------
            输出示例:
            NAME            ENDPOINTS                               AGE
            nginx-service   10.244.1.5:80,10.244.2.6:80           1m
        c.手动创建Endpoints
            不使用selector的Service:
            apiVersion: v1
            kind: Service
            metadata:
              name: external-service
            spec:
              ports:
              - protocol: TCP
                port: 80
                targetPort: 80
            ---
            apiVersion: v1
            kind: Endpoints
            metadata:
              name: external-service
            subsets:
            - addresses:
              - ip: 192.168.1.100
              - ip: 192.168.1.101
              ports:
              - port: 80
            -------------------------------------------------------------------------------------------------
            用途:
            访问集群外部服务
            手动管理后端
    c.Ingress详解
        a.基本概念
            七层负载均衡器
            基于域名和路径路由
            支持SSL/TLS终止
            需要Ingress Controller
        b.创建Ingress
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: nginx-ingress
              annotations:
                nginx.ingress.kubernetes.io/rewrite-target: /
            spec:
              ingressClassName: nginx
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: nginx-service
                        port:
                          number: 80
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nginx-ingress.yaml
        c.多域名路由
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: multi-domain-ingress
            spec:
              ingressClassName: nginx
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: frontend-service
                        port:
                          number: 80
              - host: api.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: backend-service
                        port:
                          number: 8080
        d.TLS配置
            创建TLS Secret:
            kubectl create secret tls example-tls \
              --cert=tls.crt \
              --key=tls.key
            -------------------------------------------------------------------------------------------------
            配置HTTPS Ingress:
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: tls-ingress
            spec:
              ingressClassName: nginx
              tls:
              - hosts:
                - www.example.com
                secretName: example-tls
              rules:
              - host: www.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: nginx-service
                        port:
                          number: 80

04.资源配额
    a.ResourceQuota
        a.基本概念
            限制命名空间的资源使用
            可以限制CPU、内存、存储等
            可以限制对象数量
            需要启用admission controller
        b.创建ResourceQuota
            计算资源配额:
            apiVersion: v1
            kind: ResourceQuota
            metadata:
              name: compute-quota
              namespace: default
            spec:
              hard:
                requests.cpu: "10"                                               --总请求CPU
                requests.memory: 20Gi                                            --总请求内存
                limits.cpu: "20"                                                 --总限制CPU
                limits.memory: 40Gi                                              --总限制内存
            -------------------------------------------------------------------------------------------------
            kubectl apply -f compute-quota.yaml
            kubectl get resourcequota -n default
            kubectl describe resourcequota compute-quota -n default
        c.对象数量配额
            apiVersion: v1
            kind: ResourceQuota
            metadata:
              name: object-quota
              namespace: default
            spec:
              hard:
                pods: "10"                                                       --Pod数量限制
                services: "5"                                                    --Service数量限制
                persistentvolumeclaims: "5"                                      --PVC数量限制
                secrets: "20"                                                    --Secret数量限制
                configmaps: "20"                                                 --ConfigMap数量限制
        d.存储配额
            apiVersion: v1
            kind: ResourceQuota
            metadata:
              name: storage-quota
              namespace: default
            spec:
              hard:
                requests.storage: 100Gi                                          --总存储请求
                persistentvolumeclaims: 10                                       --PVC数量限制
        e.查看配额使用情况
            kubectl get resourcequota -n default                                 --查看配额
            kubectl describe resourcequota compute-quota -n default              --查看详细使用情况
            -------------------------------------------------------------------------------------------------
            输出示例:
            Name:                   compute-quota
            Namespace:              default
            Resource                Used   Hard
            --------                ----   ----
            limits.cpu              2      20
            limits.memory           4Gi    40Gi
            requests.cpu            1      10
            requests.memory         2Gi    20Gi
    b.LimitRange
        a.基本概念
            限制单个资源对象的资源使用
            可以设置默认值
            可以设置最小和最大值
            作用于命名空间
        b.创建LimitRange
            Pod资源限制:
            apiVersion: v1
            kind: LimitRange
            metadata:
              name: pod-limit-range
              namespace: default
            spec:
              limits:
              - max:
                  cpu: "2"                                                       --单个Pod最大CPU
                  memory: 2Gi                                                    --单个Pod最大内存
                min:
                  cpu: "100m"                                                    --单个Pod最小CPU
                  memory: 100Mi                                                  --单个Pod最小内存
                type: Pod
            -------------------------------------------------------------------------------------------------
            kubectl apply -f pod-limit-range.yaml
        c.Container资源限制
            apiVersion: v1
            kind: LimitRange
            metadata:
              name: container-limit-range
              namespace: default
            spec:
              limits:
              - max:
                  cpu: "1"                                                       --单个容器最大CPU
                  memory: 1Gi                                                    --单个容器最大内存
                min:
                  cpu: "50m"                                                     --单个容器最小CPU
                  memory: 50Mi                                                   --单个容器最小内存
                default:
                  cpu: "500m"                                                    --默认limits
                  memory: 512Mi
                defaultRequest:
                  cpu: "250m"                                                    --默认requests
                  memory: 256Mi
                type: Container
        d.PVC存储限制
            apiVersion: v1
            kind: LimitRange
            metadata:
              name: storage-limit-range
              namespace: default
            spec:
              limits:
              - max:
                  storage: 10Gi                                                  --单个PVC最大存储
                min:
                  storage: 1Gi                                                   --单个PVC最小存储
                type: PersistentVolumeClaim
        e.查看LimitRange
            kubectl get limitrange -n default                                    --查看LimitRange
            kubectl describe limitrange container-limit-range -n default         --查看详细信息
    c.最佳实践
        a.资源请求和限制
            为所有容器设置requests和limits
            requests用于调度决策
            limits用于资源限制
            -------------------------------------------------------------------------------------------------
            推荐设置:
            生产环境:requests = limits                                           --保证QoS为Guaranteed
            开发环境:requests < limits                                           --允许突发使用
        b.命名空间隔离
            为每个团队或项目创建独立命名空间
            为每个命名空间设置ResourceQuota
            为每个命名空间设置LimitRange
        c.监控和告警
            监控命名空间资源使用情况
            在达到配额阈值时告警
            定期review和调整配额

05.RBAC权限
    a.Role/ClusterRole
        a.基本概念
            Role:命名空间级别的权限
            ClusterRole:集群级别的权限
            定义可以执行的操作
            通过RoleBinding/ClusterRoleBinding绑定到用户
        b.创建Role
            apiVersion: rbac.authorization.k8s.io/v1
            kind: Role
            metadata:
              name: pod-reader
              namespace: default
            rules:
            - apiGroups: [""]                                                    --核心API组用空字符串表示
              resources: ["pods"]                                                --资源类型
              verbs: ["get", "watch", "list"]                                    --允许的操作
            -------------------------------------------------------------------------------------------------
            kubectl apply -f pod-reader-role.yaml
        c.创建ClusterRole
            apiVersion: rbac.authorization.k8s.io/v1
            kind: ClusterRole
            metadata:
              name: pod-reader-cluster
            rules:
            - apiGroups: [""]
              resources: ["pods"]
              verbs: ["get", "watch", "list"]
            - apiGroups: ["apps"]
              resources: ["deployments", "statefulsets"]
              verbs: ["get", "list"]
        d.常用verbs
            get                                                                  获取单个资源
            list                                                                 列出资源集合
            watch                                                                监视资源变化
            create                                                               创建资源
            update                                                               更新资源
            patch                                                                部分更新资源
            delete                                                               删除资源
            deletecollection                                                     批量删除资源
        e.资源示例
            核心组资源:
            apiVersion: rbac.authorization.k8s.io/v1
            kind: Role
            metadata:
              name: core-resources-manager
              namespace: default
            rules:
            - apiGroups: [""]
              resources: ["pods", "services", "configmaps", "secrets"]
              verbs: ["*"]                                                       --所有操作
            -------------------------------------------------------------------------------------------------
            apps组资源:
            apiVersion: rbac.authorization.k8s.io/v1
            kind: Role
            metadata:
              name: apps-manager
              namespace: default
            rules:
            - apiGroups: ["apps"]
              resources: ["deployments", "statefulsets", "daemonsets"]
              verbs: ["get", "list", "create", "update", "delete"]
    b.RoleBinding
        a.基本概念
            将Role绑定到用户、组或ServiceAccount
            只能绑定同命名空间的Role
            可以绑定ClusterRole(限定命名空间范围)
        b.创建RoleBinding
            绑定到用户:
            apiVersion: rbac.authorization.k8s.io/v1
            kind: RoleBinding
            metadata:
              name: read-pods-binding
              namespace: default
            subjects:
            - kind: User
              name: jane                                                         --用户名
              apiGroup: rbac.authorization.k8s.io
            roleRef:
              kind: Role
              name: pod-reader
              apiGroup: rbac.authorization.k8s.io
            -------------------------------------------------------------------------------------------------
            kubectl apply -f read-pods-binding.yaml
        c.绑定到ServiceAccount
            apiVersion: rbac.authorization.k8s.io/v1
            kind: RoleBinding
            metadata:
              name: sa-read-pods
              namespace: default
            subjects:
            - kind: ServiceAccount
              name: my-sa
              namespace: default
            roleRef:
              kind: Role
              name: pod-reader
              apiGroup: rbac.authorization.k8s.io
        d.绑定到组
            apiVersion: rbac.authorization.k8s.io/v1
            kind: RoleBinding
            metadata:
              name: group-read-pods
              namespace: default
            subjects:
            - kind: Group
              name: dev-team                                                     --组名
              apiGroup: rbac.authorization.k8s.io
            roleRef:
              kind: Role
              name: pod-reader
              apiGroup: rbac.authorization.k8s.io
        e.ClusterRoleBinding
            apiVersion: rbac.authorization.k8s.io/v1
            kind: ClusterRoleBinding
            metadata:
              name: cluster-admin-binding
            subjects:
            - kind: User
              name: admin
              apiGroup: rbac.authorization.k8s.io
            roleRef:
              kind: ClusterRole
              name: cluster-admin                                                --集群管理员角色
              apiGroup: rbac.authorization.k8s.io
    c.ServiceAccount
        a.基本概念
            为Pod提供身份标识
            每个命名空间都有default ServiceAccount
            可以为应用创建专用ServiceAccount
            自动挂载token到Pod
        b.创建ServiceAccount
            apiVersion: v1
            kind: ServiceAccount
            metadata:
              name: my-sa
              namespace: default
            -------------------------------------------------------------------------------------------------
            kubectl apply -f my-sa.yaml
            kubectl get sa my-sa
        c.使用ServiceAccount
            apiVersion: v1
            kind: Pod
            metadata:
              name: sa-pod
              namespace: default
            spec:
              serviceAccountName: my-sa                                          --指定ServiceAccount
              containers:
              - name: app
                image: busybox
                command: ['sh', '-c', 'sleep 3600']
        d.禁用自动挂载token
            apiVersion: v1
            kind: ServiceAccount
            metadata:
              name: my-sa
            automountServiceAccountToken: false                                  --禁用自动挂载
            -------------------------------------------------------------------------------------------------
            或在Pod中禁用:
            apiVersion: v1
            kind: Pod
            metadata:
              name: no-token-pod
            spec:
              serviceAccountName: my-sa
              automountServiceAccountToken: false
              containers:
              - name: app
                image: busybox
                command: ['sh', '-c', 'sleep 3600']
        e.完整示例
            创建ServiceAccount:
            apiVersion: v1
            kind: ServiceAccount
            metadata:
              name: app-sa
              namespace: default
            ---
            apiVersion: rbac.authorization.k8s.io/v1
            kind: Role
            metadata:
              name: app-role
              namespace: default
            rules:
            - apiGroups: [""]
              resources: ["pods", "services"]
              verbs: ["get", "list"]
            ---
            apiVersion: rbac.authorization.k8s.io/v1
            kind: RoleBinding
            metadata:
              name: app-binding
              namespace: default
            subjects:
            - kind: ServiceAccount
              name: app-sa
              namespace: default
            roleRef:
              kind: Role
              name: app-role
              apiGroup: rbac.authorization.k8s.io
            -------------------------------------------------------------------------------------------------
            使用ServiceAccount:
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: app-deployment
              namespace: default
            spec:
              replicas: 2
              selector:
                matchLabels:
                  app: myapp
              template:
                metadata:
                  labels:
                    app: myapp
                spec:
                  serviceAccountName: app-sa
                  containers:
                  - name: app
                    image: myapp:latest
        f.查看权限
            kubectl auth can-i get pods --as=system:serviceaccount:default:app-sa   --检查权限
            kubectl auth can-i create deployments --as=system:serviceaccount:default:app-sa
            -------------------------------------------------------------------------------------------------
            查看所有权限:
            kubectl get rolebindings -n default                                  --查看RoleBinding
            kubectl get clusterrolebindings                                      --查看ClusterRoleBinding
            kubectl describe rolebinding app-binding -n default                  --查看详细信息

3.7 [2]storage

01.存储基础
    a.Volume类型
        a.Volume概述
            Pod中的容器重启后数据会丢失
            Volume可以在容器重启时保留数据
            Volume的生命周期与Pod相同
            Pod删除后Volume也会被删除(除了PV)
        b.常用Volume类型
            emptyDir                                                             临时存储,Pod删除时清空
            hostPath                                                             挂载宿主机目录
            nfs                                                                  NFS网络存储
            configMap                                                            挂载ConfigMap
            secret                                                               挂载Secret
            persistentVolumeClaim                                                挂载PVC
            downwardAPI                                                          Pod元数据
        c.Volume配置示例
            apiVersion: v1
            kind: Pod
            metadata:
              name: volume-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: data-volume
                  mountPath: /usr/share/nginx/html
                - name: config-volume
                  mountPath: /etc/config
                - name: cache-volume
                  mountPath: /tmp/cache
              volumes:
              - name: data-volume
                hostPath:
                  path: /data
                  type: DirectoryOrCreate
              - name: config-volume
                configMap:
                  name: app-config
              - name: cache-volume
                emptyDir: {}
    b.emptyDir
        a.基本概念
            在Pod创建时创建的空目录
            Pod删除时emptyDir也会被删除
            同一Pod内所有容器共享emptyDir
            数据存储在节点的磁盘或内存中
        b.使用场景
            临时缓存数据
            多容器间共享数据
            检查点保存
            临时文件存储
        c.配置示例
            基本用法:
            apiVersion: v1
            kind: Pod
            metadata:
              name: emptydir-pod
            spec:
              containers:
              - name: writer
                image: busybox
                command: ['sh', '-c', 'echo "Hello from writer" > /data/message && sleep 3600']
                volumeMounts:
                - name: shared-data
                  mountPath: /data
              - name: reader
                image: busybox
                command: ['sh', '-c', 'cat /data/message && sleep 3600']
                volumeMounts:
                - name: shared-data
                  mountPath: /data
              volumes:
              - name: shared-data
                emptyDir: {}
            -------------------------------------------------------------------------------------------------
            使用内存存储:
            apiVersion: v1
            kind: Pod
            metadata:
              name: emptydir-memory-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: cache
                  mountPath: /tmp/cache
              volumes:
              - name: cache
                emptyDir:
                  medium: Memory                                                 --使用内存作为存储
                  sizeLimit: 1Gi                                                 --限制大小为1GB
        d.注意事项
            emptyDir数据不会持久化
            使用Memory时会占用Pod的内存限制
            节点磁盘满时可能导致Pod驱逐
    c.hostPath
        a.基本概念
            挂载宿主机的文件或目录到Pod
            Pod重启后数据不会丢失
            不同节点上的hostPath路径可能不同
            需要谨慎使用,可能带来安全风险
        b.hostPath类型
            DirectoryOrCreate                                                    目录不存在则创建
            Directory                                                            必须存在的目录
            FileOrCreate                                                         文件不存在则创建
            File                                                                 必须存在的文件
            Socket                                                               UNIX套接字
            CharDevice                                                           字符设备
            BlockDevice                                                          块设备
        c.配置示例
            挂载目录:
            apiVersion: v1
            kind: Pod
            metadata:
              name: hostpath-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: data
                  mountPath: /usr/share/nginx/html
              volumes:
              - name: data
                hostPath:
                  path: /data/nginx                                              --宿主机路径
                  type: DirectoryOrCreate                                        --目录不存在则创建
            -------------------------------------------------------------------------------------------------
            挂载文件:
            apiVersion: v1
            kind: Pod
            metadata:
              name: hostpath-file-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: config
                  mountPath: /etc/nginx/nginx.conf
                  subPath: nginx.conf
              volumes:
              - name: config
                hostPath:
                  path: /etc/nginx/nginx.conf
                  type: File
        d.使用场景
            访问Docker引擎(挂载/var/run/docker.sock)
            监控节点日志(挂载/var/log)
            需要访问宿主机文件系统
            DaemonSet中使用
        e.安全注意事项
            避免挂载敏感目录(如/etc、/var/lib/kubelet)
            使用只读挂载(readOnly: true)
            限制Pod的安全上下文
            -------------------------------------------------------------------------------------------------
            只读挂载示例:
            apiVersion: v1
            kind: Pod
            metadata:
              name: hostpath-readonly-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: data
                  mountPath: /data
                  readOnly: true                                                 --只读挂载
              volumes:
              - name: data
                hostPath:
                  path: /data
                  type: Directory

02.持久化存储
    a.PersistentVolume
        a.基本概念
            PV是集群级别的存储资源
            由管理员创建或通过StorageClass动态创建
            独立于Pod的生命周期
            可以被多个Pod通过PVC使用
        b.PV访问模式
            ReadWriteOnce(RWO)                                                   单节点读写
            ReadOnlyMany(ROX)                                                    多节点只读
            ReadWriteMany(RWX)                                                   多节点读写
            ReadWriteOncePod(RWOP)                                               单Pod读写(K8s 1.22+)
        c.PV回收策略
            Retain                                                               保留数据,需要手动清理
            Recycle                                                              清空数据后重新可用(已废弃)
            Delete                                                               删除PV和底层存储
        d.PV状态
            Available                                                            可用状态,未被绑定
            Bound                                                                已绑定到PVC
            Released                                                             PVC已删除,但资源未回收
            Failed                                                               自动回收失败
        e.创建NFS类型PV
            apiVersion: v1
            kind: PersistentVolume
            metadata:
              name: nfs-pv
            spec:
              capacity:
                storage: 10Gi                                                    --存储容量
              accessModes:
              - ReadWriteMany                                                    --访问模式
              persistentVolumeReclaimPolicy: Retain                              --回收策略
              nfs:
                server: 192.168.1.100                                            --NFS服务器地址
                path: /data/nfs                                                  --NFS共享路径
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nfs-pv.yaml
            kubectl get pv                                                       --查看PV状态
        f.创建HostPath类型PV
            apiVersion: v1
            kind: PersistentVolume
            metadata:
              name: hostpath-pv
            spec:
              capacity:
                storage: 5Gi
              accessModes:
              - ReadWriteOnce
              persistentVolumeReclaimPolicy: Delete
              hostPath:
                path: /data/pv                                                   --宿主机路径
                type: DirectoryOrCreate
        g.PV标签和选择器
            apiVersion: v1
            kind: PersistentVolume
            metadata:
              name: labeled-pv
              labels:
                type: fast
                tier: gold
            spec:
              capacity:
                storage: 10Gi
              accessModes:
              - ReadWriteOnce
              persistentVolumeReclaimPolicy: Retain
              nfs:
                server: 192.168.1.100
                path: /data/fast-storage
    b.PersistentVolumeClaim
        a.基本概念
            PVC是命名空间级别的资源
            用户对存储的请求
            自动绑定到满足条件的PV
            Pod通过PVC使用存储
        b.创建PVC
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: nfs-pvc
              namespace: default
            spec:
              accessModes:
              - ReadWriteMany                                                    --访问模式要匹配PV
              resources:
                requests:
                  storage: 5Gi                                                   --请求容量
            -------------------------------------------------------------------------------------------------
            kubectl apply -f nfs-pvc.yaml
            kubectl get pvc                                                      --查看PVC状态
        c.使用标签选择器
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: fast-pvc
            spec:
              accessModes:
              - ReadWriteOnce
              resources:
                requests:
                  storage: 5Gi
              selector:
                matchLabels:
                  type: fast                                                     --匹配PV的标签
        d.Pod中使用PVC
            apiVersion: v1
            kind: Pod
            metadata:
              name: pvc-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: data
                  mountPath: /usr/share/nginx/html
              volumes:
              - name: data
                persistentVolumeClaim:
                  claimName: nfs-pvc                                             --引用PVC名称
        e.PVC扩容
            支持扩容的StorageClass:
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: expandable-storage
            provisioner: kubernetes.io/aws-ebs
            allowVolumeExpansion: true                                           --允许扩容
            -------------------------------------------------------------------------------------------------
            扩容PVC:
            kubectl edit pvc my-pvc                                              --修改spec.resources.requests.storage
            -------------------------------------------------------------------------------------------------
            或使用patch:
            kubectl patch pvc my-pvc -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
        f.查看PVC详情
            kubectl get pvc                                                      --查看PVC列表
            kubectl describe pvc nfs-pvc                                         --查看PVC详情
            kubectl get pvc nfs-pvc -o yaml                                      --查看YAML配置
    c.StorageClass
        a.基本概念
            StorageClass定义存储类型
            支持动态创建PV
            不同的StorageClass对应不同的存储后端
            可以定义不同的性能等级
        b.创建NFS StorageClass
            # 安装NFS Provisioner
            helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
            helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
              --set nfs.server=192.168.1.100 \
              --set nfs.path=/data/nfs
            -------------------------------------------------------------------------------------------------
            创建StorageClass:
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: nfs-storage
            provisioner: nfs.csi.k8s.io                                          --Provisioner类型
            parameters:
              server: 192.168.1.100                                              --NFS服务器
              share: /data/nfs                                                   --NFS共享路径
            reclaimPolicy: Delete                                                --回收策略
            volumeBindingMode: Immediate                                         --绑定模式
        c.创建Local StorageClass
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: local-storage
            provisioner: kubernetes.io/no-provisioner                            --不支持动态创建
            volumeBindingMode: WaitForFirstConsumer                              --延迟绑定
        d.默认StorageClass
            kubectl get storageclass                                             --查看StorageClass
            -------------------------------------------------------------------------------------------------
            设置默认StorageClass:
            kubectl patch storageclass nfs-storage -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
            -------------------------------------------------------------------------------------------------
            取消默认StorageClass:
            kubectl patch storageclass nfs-storage -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
        e.使用StorageClass动态创建PVC
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: dynamic-pvc
            spec:
              accessModes:
              - ReadWriteOnce
              storageClassName: nfs-storage                                      --指定StorageClass
              resources:
                requests:
                  storage: 5Gi
            -------------------------------------------------------------------------------------------------
            如果不指定storageClassName,会使用默认StorageClass

03.动态供应
    a.NFS动态供应
        a.部署NFS服务器
            # 在NFS服务器节点安装NFS
            apt-get install -y nfs-kernel-server                                 --Ubuntu/Debian
            yum install -y nfs-utils                                             --CentOS/RHEL
            -------------------------------------------------------------------------------------------------
            # 创建共享目录
            mkdir -p /data/nfs
            chmod 777 /data/nfs
            -------------------------------------------------------------------------------------------------
            # 配置NFS导出
            echo "/data/nfs *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
            -------------------------------------------------------------------------------------------------
            # 重启NFS服务
            systemctl restart nfs-server
            systemctl enable nfs-server
            -------------------------------------------------------------------------------------------------
            # 查看NFS导出
            exportfs -v
        b.安装NFS Provisioner
            使用Helm安装:
            helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
            helm repo update
            helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
              --set nfs.server=192.168.1.100 \
              --set nfs.path=/data/nfs \
              --set storageClass.name=nfs-client \
              --set storageClass.defaultClass=true
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get pods -l app=nfs-subdir-external-provisioner
            kubectl get storageclass
        c.测试动态创建PVC
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: test-pvc
            spec:
              accessModes:
              - ReadWriteMany
              storageClassName: nfs-client
              resources:
                requests:
                  storage: 1Gi
            -------------------------------------------------------------------------------------------------
            kubectl apply -f test-pvc.yaml
            kubectl get pvc test-pvc
            kubectl get pv
        d.测试Pod使用PVC
            apiVersion: v1
            kind: Pod
            metadata:
              name: test-pod
            spec:
              containers:
              - name: busybox
                image: busybox
                command: ['sh', '-c', 'echo "Hello NFS" > /data/message && sleep 3600']
                volumeMounts:
                - name: nfs-data
                  mountPath: /data
              volumes:
              - name: nfs-data
                persistentVolumeClaim:
                  claimName: test-pvc
            -------------------------------------------------------------------------------------------------
            kubectl apply -f test-pod.yaml
            kubectl exec test-pod -- cat /data/message
    b.Ceph动态供应
        a.Ceph RBD介绍
            Ceph是分布式存储系统
            RBD(RADOS Block Device)提供块存储
            支持快照、克隆等高级特性
            适合大规模集群
        b.安装Ceph CSI
            helm repo add ceph-csi https://ceph.github.io/csi-charts
            helm repo update
            helm install ceph-csi-rbd ceph-csi/ceph-csi-rbd \
              --namespace ceph-csi-rbd \
              --create-namespace
        c.创建Ceph StorageClass
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: ceph-rbd
            provisioner: rbd.csi.ceph.com
            parameters:
              clusterID: b9127830-b0cc-4e34-aa47-9d1a2e9949a8                    --Ceph集群ID
              pool: kubernetes                                                   --Ceph存储池
              imageFeatures: layering                                            --RBD镜像特性
              csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
              csi.storage.k8s.io/provisioner-secret-namespace: default
              csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
              csi.storage.k8s.io/controller-expand-secret-namespace: default
              csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
              csi.storage.k8s.io/node-stage-secret-namespace: default
              csi.storage.k8s.io/fstype: ext4
            reclaimPolicy: Delete
            allowVolumeExpansion: true
            mountOptions:
            - discard
        d.创建Ceph Secret
            apiVersion: v1
            kind: Secret
            metadata:
              name: csi-rbd-secret
              namespace: default
            type: Opaque
            stringData:
              userID: admin
              userKey: AQBRbmVoAAAAABAAp1234567890abcdef==                        --Ceph用户密钥
    c.云存储动态供应
        a.AWS EBS
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: aws-ebs-gp3
            provisioner: ebs.csi.aws.com
            parameters:
              type: gp3                                                          --卷类型
              iops: "3000"                                                       --IOPS
              throughput: "125"                                                  --吞吐量(MB/s)
              encrypted: "true"                                                  --加密
            volumeBindingMode: WaitForFirstConsumer
            allowVolumeExpansion: true
        b.Azure Disk
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: azure-disk-premium
            provisioner: disk.csi.azure.com
            parameters:
              skuName: Premium_LRS                                               --磁盘类型
              kind: Managed
              cachingMode: ReadOnly
            volumeBindingMode: WaitForFirstConsumer
            allowVolumeExpansion: true
        c.Google Cloud Persistent Disk
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: gce-pd-ssd
            provisioner: pd.csi.storage.gke.io
            parameters:
              type: pd-ssd                                                       --磁盘类型
              replication-type: regional-pd                                      --区域复制
            volumeBindingMode: WaitForFirstConsumer
            allowVolumeExpansion: true

04.存储实践
    a.MySQL持久化
        a.创建PVC
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: mysql-pvc
            spec:
              accessModes:
              - ReadWriteOnce
              storageClassName: nfs-client
              resources:
                requests:
                  storage: 10Gi
        b.创建MySQL Deployment
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: mysql
            spec:
              replicas: 1
              selector:
                matchLabels:
                  app: mysql
              template:
                metadata:
                  labels:
                    app: mysql
                spec:
                  containers:
                  - name: mysql
                    image: mysql:8.0
                    env:
                    - name: MYSQL_ROOT_PASSWORD
                      value: MyP@ssw0rd
                    ports:
                    - containerPort: 3306
                    volumeMounts:
                    - name: mysql-data
                      mountPath: /var/lib/mysql                                  --MySQL数据目录
                  volumes:
                  - name: mysql-data
                    persistentVolumeClaim:
                      claimName: mysql-pvc
            -------------------------------------------------------------------------------------------------
            kubectl apply -f mysql-deployment.yaml
        c.创建Service
            apiVersion: v1
            kind: Service
            metadata:
              name: mysql
            spec:
              selector:
                app: mysql
              ports:
              - port: 3306
                targetPort: 3306
            -------------------------------------------------------------------------------------------------
            kubectl apply -f mysql-service.yaml
        d.测试持久化
            # 写入数据
            kubectl exec -it mysql-xxxx -- mysql -uroot -pMyP@ssw0rd -e "CREATE DATABASE testdb;"
            kubectl exec -it mysql-xxxx -- mysql -uroot -pMyP@ssw0rd -e "USE testdb; CREATE TABLE users (id INT, name VARCHAR(50));"
            kubectl exec -it mysql-xxxx -- mysql -uroot -pMyP@ssw0rd -e "USE testdb; INSERT INTO users VALUES (1, 'Alice');"
            -------------------------------------------------------------------------------------------------
            # 删除Pod
            kubectl delete pod mysql-xxxx
            -------------------------------------------------------------------------------------------------
            # 验证数据还在
            kubectl exec -it mysql-yyyy -- mysql -uroot -pMyP@ssw0rd -e "USE testdb; SELECT * FROM users;"
    b.Redis持久化
        a.创建ConfigMap
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: redis-config
            data:
              redis.conf: |
                appendonly yes                                                   --启用AOF持久化
                appendfsync everysec                                             --每秒同步
                save 900 1                                                       --RDB快照规则
                save 300 10
                save 60 10000
        b.创建StatefulSet
            apiVersion: apps/v1
            kind: StatefulSet
            metadata:
              name: redis
            spec:
              serviceName: redis
              replicas: 1
              selector:
                matchLabels:
                  app: redis
              template:
                metadata:
                  labels:
                    app: redis
                spec:
                  containers:
                  - name: redis
                    image: redis:7.0
                    command: ["redis-server"]
                    args: ["/etc/redis/redis.conf"]
                    ports:
                    - containerPort: 6379
                    volumeMounts:
                    - name: redis-config
                      mountPath: /etc/redis
                    - name: redis-data
                      mountPath: /data                                           --Redis数据目录
                  volumes:
                  - name: redis-config
                    configMap:
                      name: redis-config
              volumeClaimTemplates:
              - metadata:
                  name: redis-data
                spec:
                  accessModes: [ "ReadWriteOnce" ]
                  storageClassName: nfs-client
                  resources:
                    requests:
                      storage: 5Gi
        c.测试持久化
            # 写入数据
            kubectl exec -it redis-0 -- redis-cli SET key1 value1
            kubectl exec -it redis-0 -- redis-cli GET key1
            -------------------------------------------------------------------------------------------------
            # 删除Pod
            kubectl delete pod redis-0
            -------------------------------------------------------------------------------------------------
            # 验证数据还在
            kubectl exec -it redis-0 -- redis-cli GET key1
    c.文件共享
        a.多Pod共享存储
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: shared-pvc
            spec:
              accessModes:
              - ReadWriteMany                                                    --多节点读写
              storageClassName: nfs-client
              resources:
                requests:
                  storage: 10Gi
            -------------------------------------------------------------------------------------------------
            创建多个Pod:
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: shared-storage
            spec:
              replicas: 3
              selector:
                matchLabels:
                  app: shared-app
              template:
                metadata:
                  labels:
                    app: shared-app
                spec:
                  containers:
                  - name: app
                    image: nginx:1.21
                    volumeMounts:
                    - name: shared-data
                      mountPath: /usr/share/nginx/html
                  volumes:
                  - name: shared-data
                    persistentVolumeClaim:
                      claimName: shared-pvc
        b.文件上传示例
            apiVersion: v1
            kind: Pod
            metadata:
              name: file-uploader
            spec:
              containers:
              - name: uploader
                image: busybox
                command: ['sh', '-c', 'while true; do echo $(date) >> /shared/upload.log; sleep 10; done']
                volumeMounts:
                - name: shared-data
                  mountPath: /shared
              volumes:
              - name: shared-data
                persistentVolumeClaim:
                  claimName: shared-pvc
            -------------------------------------------------------------------------------------------------
            查看文件:
            kubectl exec shared-storage-xxxx -- cat /usr/share/nginx/html/upload.log
        c.静态网站托管
            # 上传网站文件到共享存储
            kubectl cp ./website/ shared-storage-xxxx:/usr/share/nginx/html/
            -------------------------------------------------------------------------------------------------
            # 所有nginx Pod都能访问相同的网站文件

05.CSI驱动
    a.CSI介绍
        a.什么是CSI
            Container Storage Interface                                          容器存储接口
            Kubernetes存储插件的标准接口
            替代早期的in-tree存储插件
            支持第三方存储供应商
        b.CSI架构
            CSI Controller                                                       负责卷的创建、删除、挂载等
            CSI Node                                                             负责在节点上挂载卷到Pod
            CSI Driver                                                           具体存储的实现
        c.CSI优势
            解耦存储代码和Kubernetes核心代码
            支持更多存储类型
            存储插件可以独立升级
            第三方可以开发自己的CSI插件
    b.常用CSI驱动
        a.NFS CSI Driver
            部署NFS CSI:
            helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
            helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs \
              --namespace kube-system \
              --set controller.replicas=1
            -------------------------------------------------------------------------------------------------
            创建StorageClass:
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: nfs-csi
            provisioner: nfs.csi.k8s.io
            parameters:
              server: 192.168.1.100
              share: /data/nfs
            reclaimPolicy: Delete
            volumeBindingMode: Immediate
            mountOptions:
            - nfsvers=4.1
        b.Local Path CSI
            安装Local Path Provisioner:
            kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
            -------------------------------------------------------------------------------------------------
            创建StorageClass:
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: local-path
            provisioner: rancher.io/local-path
            volumeBindingMode: WaitForFirstConsumer
            reclaimPolicy: Delete
        c.Longhorn
            安装Longhorn:
            kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.5.0/deploy/longhorn.yaml
            -------------------------------------------------------------------------------------------------
            访问UI:
            kubectl port-forward -n longhorn-system svc/longhorn-frontend 8080:80
            -------------------------------------------------------------------------------------------------
            创建StorageClass:
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: longhorn
            provisioner: driver.longhorn.io
            allowVolumeExpansion: true
            parameters:
              numberOfReplicas: "3"                                              --副本数量
              staleReplicaTimeout: "2880"                                        --过期副本超时
              fromBackup: ""
        d.OpenEBS
            安装OpenEBS:
            helm repo add openebs https://openebs.github.io/charts
            helm install openebs openebs/openebs --namespace openebs --create-namespace
            -------------------------------------------------------------------------------------------------
            创建StorageClass(Local PV):
            apiVersion: storage.k8s.io/v1
            kind: StorageClass
            metadata:
              name: openebs-hostpath
            provisioner: openebs.io/local
            volumeBindingMode: WaitForFirstConsumer
    c.配置示例
        a.NFS CSI使用示例
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: nfs-csi-pvc
            spec:
              accessModes:
              - ReadWriteMany
              storageClassName: nfs-csi
              resources:
                requests:
                  storage: 10Gi
            ---
            apiVersion: v1
            kind: Pod
            metadata:
              name: nfs-csi-pod
            spec:
              containers:
              - name: app
                image: nginx:1.21
                volumeMounts:
                - name: data
                  mountPath: /usr/share/nginx/html
              volumes:
              - name: data
                persistentVolumeClaim:
                  claimName: nfs-csi-pvc
        b.快照功能
            创建VolumeSnapshotClass:
            apiVersion: snapshot.storage.k8s.io/v1
            kind: VolumeSnapshotClass
            metadata:
              name: csi-snapshot-class
            driver: nfs.csi.k8s.io                                               --CSI驱动名称
            deletionPolicy: Delete
            -------------------------------------------------------------------------------------------------
            创建快照:
            apiVersion: snapshot.storage.k8s.io/v1
            kind: VolumeSnapshot
            metadata:
              name: my-snapshot
            spec:
              volumeSnapshotClassName: csi-snapshot-class
              source:
                persistentVolumeClaimName: nfs-csi-pvc                           --源PVC
            -------------------------------------------------------------------------------------------------
            从快照恢复:
            apiVersion: v1
            kind: PersistentVolumeClaim
            metadata:
              name: restored-pvc
            spec:
              accessModes:
              - ReadWriteMany
              storageClassName: nfs-csi
              dataSource:
                name: my-snapshot                                                --指定快照
                kind: VolumeSnapshot
                apiGroup: snapshot.storage.k8s.io
              resources:
                requests:
                  storage: 10Gi
        c.存储扩容
            查看是否支持扩容:
            kubectl get storageclass nfs-csi -o yaml | grep allowVolumeExpansion
            -------------------------------------------------------------------------------------------------
            扩容PVC:
            kubectl patch pvc nfs-csi-pvc -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
            -------------------------------------------------------------------------------------------------
            查看扩容状态:
            kubectl describe pvc nfs-csi-pvc
        d.存储监控
            查看PV使用情况:
            kubectl get pv
            kubectl describe pv <pv-name>
            -------------------------------------------------------------------------------------------------
            查看PVC使用情况:
            kubectl get pvc -A
            kubectl describe pvc <pvc-name>
            -------------------------------------------------------------------------------------------------
            使用df查看Pod内存储:
            kubectl exec <pod-name> -- df -h

3.8 [3]tools

01.Dashboard
    a.安装Dashboard
        a.获取安装文件
            kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get pods -n kubernetes-dashboard                             --查看Dashboard Pod
            kubectl get svc -n kubernetes-dashboard                              --查看Dashboard Service
        b.创建管理员账号
            创建ServiceAccount:
            cat <<EOF | kubectl apply -f -
            apiVersion: v1
            kind: ServiceAccount
            metadata:
              name: admin-user
              namespace: kubernetes-dashboard
            ---
            apiVersion: rbac.authorization.k8s.io/v1
            kind: ClusterRoleBinding
            metadata:
              name: admin-user
            roleRef:
              apiGroup: rbac.authorization.k8s.io
              kind: ClusterRole
              name: cluster-admin
            subjects:
            - kind: ServiceAccount
              name: admin-user
              namespace: kubernetes-dashboard
            EOF
        c.获取访问Token
            kubectl -n kubernetes-dashboard create token admin-user              --临时Token(24小时)
            -------------------------------------------------------------------------------------------------
            创建永久Token:
            cat <<EOF | kubectl apply -f -
            apiVersion: v1
            kind: Secret
            metadata:
              name: admin-user-secret
              namespace: kubernetes-dashboard
              annotations:
                kubernetes.io/service-account.name: admin-user
            type: kubernetes.io/service-account-token
            EOF
            -------------------------------------------------------------------------------------------------
            获取永久Token:
            kubectl get secret admin-user-secret -n kubernetes-dashboard -o jsonpath='{.data.token}' | base64 -d
    b.访问Dashboard
        a.kubectl proxy方式
            kubectl proxy                                                        --启动代理(默认8001端口)
            -------------------------------------------------------------------------------------------------
            访问地址:
            http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
        b.NodePort方式
            kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
            -------------------------------------------------------------------------------------------------
            修改type为NodePort:
            spec:
              type: NodePort
              ports:
              - port: 443
                targetPort: 8443
                nodePort: 30443                                                  --指定端口(30000-32767)
            -------------------------------------------------------------------------------------------------
            访问:https://<NodeIP>:30443
        c.Ingress方式
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              name: dashboard-ingress
              namespace: kubernetes-dashboard
              annotations:
                nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
                nginx.ingress.kubernetes.io/ssl-passthrough: "true"
            spec:
              ingressClassName: nginx
              rules:
              - host: dashboard.example.com
                http:
                  paths:
                  - path: /
                    pathType: Prefix
                    backend:
                      service:
                        name: kubernetes-dashboard
                        port:
                          number: 443
            -------------------------------------------------------------------------------------------------
            kubectl apply -f dashboard-ingress.yaml
            -------------------------------------------------------------------------------------------------
            访问:https://dashboard.example.com
        d.port-forward方式
            kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8443:443
            -------------------------------------------------------------------------------------------------
            访问:https://localhost:8443
    c.Dashboard功能
        a.资源查看
            查看所有命名空间的资源
            实时监控Pod状态和资源使用
            查看Deployment、Service、Ingress等详情
            查看ConfigMap和Secret(隐藏敏感信息)
        b.日志和终端
            查看Pod实时日志
            支持多容器Pod的日志切换
            Web终端访问容器
            支持文件上传下载
        c.资源操作
            创建、编辑、删除资源
            扩缩容Deployment
            重启Pod
            查看和编辑YAML配置

02.Helm包管理
    a.Helm安装
        a.脚本安装
            curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
            -------------------------------------------------------------------------------------------------
            验证安装:
            helm version                                                         --查看Helm版本
        b.二进制安装
            # 下载Helm
            wget https://get.helm.sh/helm-v3.13.0-linux-amd64.tar.gz
            tar -zxvf helm-v3.13.0-linux-amd64.tar.gz
            sudo mv linux-amd64/helm /usr/local/bin/helm
            -------------------------------------------------------------------------------------------------
            # macOS
            brew install helm
        c.初始化配置
            helm repo add stable https://charts.helm.sh/stable                  --添加stable仓库
            helm repo add bitnami https://charts.bitnami.com/bitnami            --添加bitnami仓库
            helm repo update                                                     --更新仓库索引
            -------------------------------------------------------------------------------------------------
            查看仓库列表:
            helm repo list
    b.Chart使用
        a.搜索Chart
            helm search hub nginx                                                --在Artifact Hub搜索
            helm search repo nginx                                               --在本地仓库搜索
            -------------------------------------------------------------------------------------------------
            查看Chart详情:
            helm show chart bitnami/nginx                                        --查看Chart信息
            helm show values bitnami/nginx                                       --查看可配置参数
            helm show readme bitnami/nginx                                       --查看README
        b.安装Chart
            helm install my-nginx bitnami/nginx                                  --安装Chart
            helm install my-nginx bitnami/nginx -n production                    --安装到指定命名空间
            helm install my-nginx bitnami/nginx --create-namespace -n prod       --自动创建命名空间
            -------------------------------------------------------------------------------------------------
            自定义配置:
            helm install my-nginx bitnami/nginx --set service.type=NodePort      --命令行设置
            helm install my-nginx bitnami/nginx -f values.yaml                   --使用values文件
            -------------------------------------------------------------------------------------------------
            干运行(不实际安装):
            helm install my-nginx bitnami/nginx --dry-run --debug                --查看渲染后的YAML
        c.管理Release
            helm list                                                            --查看已安装的Release
            helm list -A                                                         --查看所有命名空间
            helm status my-nginx                                                 --查看Release状态
            helm get values my-nginx                                             --查看使用的配置
            helm get manifest my-nginx                                           --查看生成的清单
        d.升级Release
            helm upgrade my-nginx bitnami/nginx                                  --升级到最新版本
            helm upgrade my-nginx bitnami/nginx --set replicas=3                 --修改配置并升级
            helm upgrade my-nginx bitnami/nginx -f new-values.yaml               --使���新配置升级
            helm upgrade my-nginx bitnami/nginx --reuse-values                   --保持当前值升级
        e.回滚Release
            helm history my-nginx                                                --查看版本历史
            helm rollback my-nginx                                               --回滚到上一版本
            helm rollback my-nginx 2                                             --回滚到指定版本
        f.卸载Release
            helm uninstall my-nginx                                              --卸载Release
            helm uninstall my-nginx --keep-history                               --保留历史记录
    c.自定义Chart
        a.创建Chart
            helm create mychart                                                  --创建Chart模板
            -------------------------------------------------------------------------------------------------
            Chart目录结构:
            mychart/
            ├── Chart.yaml                                                       --Chart元数据
            ├── values.yaml                                                      --默认配置值
            ├── charts/                                                          --依赖的Chart
            ├── templates/                                                       --模板文件
            │   ├── deployment.yaml
            │   ├── service.yaml
            │   ├── ingress.yaml
            │   ├── _helpers.tpl                                                 --模板辅助函数
            │   └── NOTES.txt                                                    --安装后提示信息
            └── .helmignore                                                      --忽略文件
        b.Chart.yaml配置
            apiVersion: v2
            name: mychart
            description: A Helm chart for my application
            type: application
            version: 0.1.0                                                       --Chart版本
            appVersion: "1.0"                                                    --应用版本
            keywords:
              - nginx
              - web
            maintainers:
              - name: Your Name
                email: [email protected]
        c.values.yaml配置
            replicaCount: 3

            image:
              repository: nginx
              tag: "1.21"
              pullPolicy: IfNotPresent

            service:
              type: ClusterIP
              port: 80

            resources:
              limits:
                cpu: 100m
                memory: 128Mi
              requests:
                cpu: 50m
                memory: 64Mi

            ingress:
              enabled: false
              className: nginx
              hosts:
                - host: chart-example.local
                  paths:
                    - path: /
                      pathType: Prefix
        d.模板语法
            Deployment模板示例:
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: {{ include "mychart.fullname" . }}                          --使用辅助函数
              labels:
                {{- include "mychart.labels" . | nindent 4 }}                   --包含标签
            spec:
              replicas: {{ .Values.replicaCount }}                              --引用values值
              selector:
                matchLabels:
                  {{- include "mychart.selectorLabels" . | nindent 6 }}
              template:
                metadata:
                  labels:
                    {{- include "mychart.selectorLabels" . | nindent 8 }}
                spec:
                  containers:
                  - name: {{ .Chart.Name }}
                    image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
                    imagePullPolicy: {{ .Values.image.pullPolicy }}
                    ports:
                    - containerPort: 80
                    resources:
                      {{- toYaml .Values.resources | nindent 12 }}              --转换为YAML
        e.常用函数
            {{ .Values.key }}                                                    --获取values值
            {{ default "默认值" .Values.key }}                                    --设置默认值
            {{ required "必需的值" .Values.key }}                                 --必填项检查
            {{ if .Values.enabled }}...{{ end }}                                 --条件判断
            {{ range .Values.list }}...{{ end }}                                 --循环
            {{ .Values.text | quote }}                                           --添加引号
            {{ .Values.text | upper }}                                           --转大写
            {{ include "模板名" . }}                                              --包含模板
            {{- 内容 }}                                                          --去除左侧空白
            {{ 内容 -}}                                                          --去除右侧空白
        f.Chart使用
            helm lint mychart                                                    --检查Chart语法
            helm template mychart                                                --渲染模板(不安装)
            helm package mychart                                                 --打包Chart
            helm install myapp ./mychart                                         --安装本地Chart
            helm install myapp mychart-0.1.0.tgz                                 --安装打包的Chart

03.监控工具
    a.Prometheus
        a.安装Prometheus
            使用Helm安装:
            helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
            helm repo update
            helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get pods -n monitoring                                       --查看Prometheus组件
            kubectl get svc -n monitoring                                        --查看Service
        b.访问Prometheus
            kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090
            -------------------------------------------------------------------------------------------------
            访问:http://localhost:9090
        c.常用查询
            查看节点CPU使用率:
            100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
            -------------------------------------------------------------------------------------------------
            查看Pod内存使用:
            sum(container_memory_working_set_bytes{pod!=""}) by (pod)
            -------------------------------------------------------------------------------------------------
            查看Pod CPU使用率:
            sum(rate(container_cpu_usage_seconds_total{pod!=""}[5m])) by (pod) * 100
            -------------------------------------------------------------------------------------------------
            查看磁盘使用率:
            (node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_free_bytes{mountpoint="/"}) / node_filesystem_size_bytes{mountpoint="/"} * 100
        d.配置告警规则
            创建PrometheusRule:
            apiVersion: monitoring.coreos.com/v1
            kind: PrometheusRule
            metadata:
              name: custom-alerts
              namespace: monitoring
            spec:
              groups:
              - name: custom-rules
                interval: 30s
                rules:
                - alert: HighPodMemory
                  expr: sum(container_memory_working_set_bytes{pod!=""}) by (pod) / 1024 / 1024 / 1024 > 1
                  for: 5m
                  labels:
                    severity: warning
                  annotations:
                    summary: "Pod {{ $labels.pod }} memory usage high"
                    description: "Pod {{ $labels.pod }} memory usage is {{ $value }}GB"
                - alert: NodeDown
                  expr: up{job="node-exporter"} == 0
                  for: 1m
                  labels:
                    severity: critical
                  annotations:
                    summary: "Node {{ $labels.instance }} is down"
            -------------------------------------------------------------------------------------------------
            kubectl apply -f prometheus-rules.yaml
        e.ServiceMonitor配置
            监控自定义应用:
            apiVersion: monitoring.coreos.com/v1
            kind: ServiceMonitor
            metadata:
              name: myapp-monitor
              namespace: monitoring
            spec:
              selector:
                matchLabels:
                  app: myapp
              endpoints:
              - port: metrics
                interval: 30s
                path: /metrics
    b.Grafana
        a.访问Grafana
            kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80
            -------------------------------------------------------------------------------------------------
            访问:http://localhost:3000
            -------------------------------------------------------------------------------------------------
            默认凭证:
            用户名:admin
            密码:kubectl get secret -n monitoring prometheus-grafana -o jsonpath="{.data.admin-password}" | base64 -d
        b.导入Dashboard
            推荐的Dashboard ID:
            315                                                                  --Kubernetes cluster monitoring
            8588                                                                 --Kubernetes Deployment Statefulset Daemonset metrics
            6417                                                                 --Kubernetes Cluster (Prometheus)
            13770                                                                --Kubernetes / Views / Pods
            -------------------------------------------------------------------------------------------------
            导入步骤:
            点击"+" -> Import
            输入Dashboard ID
            选择Prometheus数据源
            点击Import
        c.创建自定义Dashboard
            添加Panel步骤:
            1. 点击"Create" -> "Dashboard"
            2. 点击"Add new panel"
            3. 输入PromQL查询
            4. 选择可视化类型(Graph、Stat、Gauge等)
            5. 配置显示选项
            6. 保存Dashboard
            -------------------------------------------------------------------------------------------------
            常用Panel示例:
            CPU使用率:
            sum(rate(container_cpu_usage_seconds_total{pod!=""}[5m])) by (pod) * 100
            -------------------------------------------------------------------------------------------------
            内存使用量:
            sum(container_memory_working_set_bytes{pod!=""}) by (pod) / 1024 / 1024 / 1024
            -------------------------------------------------------------------------------------------------
            网络流量:
            sum(rate(container_network_receive_bytes_total[5m])) by (pod)
        d.配置告警通知
            配置Email通知:
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: grafana-config
              namespace: monitoring
            data:
              grafana.ini: |
                [smtp]
                enabled = true
                host = smtp.gmail.com:587
                user = [email protected]
                password = your-password
                from_address = [email protected]
                from_name = Grafana
            -------------------------------------------------------------------------------------------------
            配置Webhook通知:
            在Grafana UI中:
            Alerting -> Contact points -> New contact point
            选择Webhook类型
            输入Webhook URL
        e.数据源配置
            添加Prometheus数据源:
            Configuration -> Data Sources -> Add data source
            选择Prometheus
            URL:http://prometheus-kube-prometheus-prometheus.monitoring.svc:9090
            点击"Save & Test"
    c.Metrics Server
        a.安装Metrics Server
            kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get deployment metrics-server -n kube-system
            kubectl get apiservice v1beta1.metrics.k8s.io -o yaml
        b.修复证书问题
            kubectl edit deployment metrics-server -n kube-system
            -------------------------------------------------------------------------------------------------
            添加启动参数:
            spec:
              containers:
              - args:
                - --cert-dir=/tmp
                - --secure-port=4443
                - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
                - --kubelet-use-node-status-port
                - --metric-resolution=15s
                - --kubelet-insecure-tls                                         --跳过证书验证(测试环境)
        c.使用Metrics Server
            kubectl top nodes                                                    --查看节点资源使用
            kubectl top pods -A                                                  --查看Pod资源使用
            kubectl top pods --containers                                        --查看容器资源使用
        d.配置HPA
            基于CPU的自动扩缩容:
            kubectl autoscale deployment nginx --cpu-percent=50 --min=1 --max=10
            -------------------------------------------------------------------------------------------------
            YAML方式:
            apiVersion: autoscaling/v2
            kind: HorizontalPodAutoscaler
            metadata:
              name: nginx-hpa
            spec:
              scaleTargetRef:
                apiVersion: apps/v1
                kind: Deployment
                name: nginx
              minReplicas: 1
              maxReplicas: 10
              metrics:
              - type: Resource
                resource:
                  name: cpu
                  target:
                    type: Utilization
                    averageUtilization: 50
              - type: Resource
                resource:
                  name: memory
                  target:
                    type: Utilization
                    averageUtilization: 80

04.日志工具
    a.EFK Stack
        a.部署Elasticsearch
            使用Helm安装:
            helm repo add elastic https://helm.elastic.co
            helm repo update
            helm install elasticsearch elastic/elasticsearch -n logging --create-namespace \
              --set replicas=1 \
              --set resources.requests.memory=2Gi \
              --set resources.limits.memory=2Gi
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get pods -n logging | grep elasticsearch
        b.部署Fluent Bit
            helm install fluent-bit fluent/fluent-bit -n logging \
              --set config.outputs.es.host=elasticsearch-master \
              --set config.outputs.es.port=9200
            -------------------------------------------------------------------------------------------------
            配置文件示例:
            apiVersion: v1
            kind: ConfigMap
            metadata:
              name: fluent-bit-config
              namespace: logging
            data:
              fluent-bit.conf: |
                [SERVICE]
                    Flush         5
                    Daemon        off
                    Log_Level     info

                [INPUT]
                    Name              tail
                    Path              /var/log/containers/*.log
                    Parser            docker
                    Tag               kube.*
                    Refresh_Interval  5

                [FILTER]
                    Name                kubernetes
                    Match               kube.*
                    Kube_URL            https://kubernetes.default.svc:443
                    Kube_CA_File        /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
                    Kube_Token_File     /var/run/secrets/kubernetes.io/serviceaccount/token

                [OUTPUT]
                    Name            es
                    Match           *
                    Host            elasticsearch-master
                    Port            9200
                    Logstash_Format On
                    Logstash_Prefix kubernetes
                    Retry_Limit     False
        c.部署Kibana
            helm install kibana elastic/kibana -n logging \
              --set elasticsearchHosts=http://elasticsearch-master:9200
            -------------------------------------------------------------------------------------------------
            访问Kibana:
            kubectl port-forward -n logging svc/kibana-kibana 5601:5601
            -------------------------------------------------------------------------------------------------
            访问:http://localhost:5601
        d.Kibana使用
            创建Index Pattern:
            Stack Management -> Index Patterns -> Create index pattern
            输入:kubernetes-*
            选择时间字段:@timestamp
            -------------------------------------------------------------------------------------------------
            查询日志:
            Discover -> 选择Index Pattern
            -------------------------------------------------------------------------------------------------
            常用查询语法:
            kubernetes.pod_name:"nginx-*"                                        --按Pod名称过滤
            kubernetes.namespace_name:"default"                                  --按命名空间过滤
            log:"error" OR log:"ERROR"                                           --搜索错误日志
            kubernetes.labels.app:"myapp" AND log:"timeout"                      --组合查询
    b.Loki
        a.安装Loki Stack
            helm repo add grafana https://grafana.github.io/helm-charts
            helm repo update
            helm install loki grafana/loki-stack -n logging --create-namespace \
              --set grafana.enabled=true \
              --set prometheus.enabled=true \
              --set promtail.enabled=true
            -------------------------------------------------------------------------------------------------
            验证安装:
            kubectl get pods -n logging
        b.Promtail配置
            查看配置:
            kubectl get configmap loki-promtail -n logging -o yaml
            -------------------------------------------------------------------------------------------------
            配置示例:
            server:
              http_listen_port: 9080
              grpc_listen_port: 0

            positions:
              filename: /tmp/positions.yaml

            clients:
              - url: http://loki:3100/loki/api/v1/push

            scrape_configs:
              - job_name: kubernetes-pods
                kubernetes_sd_configs:
                  - role: pod
                relabel_configs:
                  - source_labels: [__meta_kubernetes_pod_label_app]
                    target_label: app
                  - source_labels: [__meta_kubernetes_namespace]
                    target_label: namespace
                  - source_labels: [__meta_kubernetes_pod_name]
                    target_label: pod
        c.Grafana集成Loki
            添加Loki数据源:
            Configuration -> Data Sources -> Add data source
            选择Loki
            URL:http://loki:3100
            点击"Save & Test"
            -------------------------------------------------------------------------------------------------
            创建日志查询面板:
            Explore -> 选择Loki数据源
            输入LogQL查询
        d.LogQL查询语法
            基本查询:
            {namespace="default"}                                                --查询default命名空间日志
            {app="nginx"}                                                        --查询nginx应用日志
            {pod="nginx-7c5ddbdf54-abc12"}                                       --查询指定Pod日志
            -------------------------------------------------------------------------------------------------
            过滤查询:
            {namespace="default"} |= "error"                                     --包含error的日志
            {namespace="default"} != "debug"                                     --不包含debug的日志
            {namespace="default"} |~ "error|ERROR"                               --正则匹配
            -------------------------------------------------------------------------------------------------
            聚合查询:
            sum(rate({namespace="default"}[5m]))                                 --5分钟内日志速率
            count_over_time({namespace="default"}[1h])                           --1小时内日志数量
            -------------------------------------------------------------------------------------------------
            多标签查询:
            {namespace="default", app="nginx"} |= "error"                        --多条件查询

05.其他工具
    a.k9s
        a.安装k9s
            macOS:
            brew install k9s
            -------------------------------------------------------------------------------------------------
            Linux:
            wget https://github.com/derailed/k9s/releases/download/v0.27.0/k9s_Linux_amd64.tar.gz
            tar -xzf k9s_Linux_amd64.tar.gz
            sudo mv k9s /usr/local/bin/
            -------------------------------------------------------------------------------------------------
            Windows:
            choco install k9s
        b.基本使用
            启动k9s:
            k9s                                                                  --连接默认集群
            k9s --context my-context                                             --指定上下文
            k9s -n default                                                       --指定命名空间
            -------------------------------------------------------------------------------------------------
            常用快捷键:
            :pods                                                                --查看Pod
            :svc                                                                 --查看Service
            :deploy                                                              --查看Deployment
            :nodes                                                               --查看Node
            0                                                                    --查看所有命名空间
            /                                                                    --搜索过滤
            l                                                                    --查看日志
            d                                                                    --描述资源
            e                                                                    --编辑资源
            delete                                                               --删除资源
            s                                                                    --进入Shell
            Ctrl+d                                                               --删除资源
            ?                                                                    --帮助
        c.高级功能
            实时监控资源:
            :pulse                                                               --查看集群脉冲
            :xray deploy                                                         --查看Deployment关联资源
            -------------------------------------------------------------------------------------------------
            查看事件:
            :events                                                              --查看集群事件
            -------------------------------------------------------------------------------------------------
            端口转发:
            在Pod视图下按 Shift+f                                                --配置端口转发
        d.自定义配置
            配置文件位置:~/.k9s/config.yml
            -------------------------------------------------------------------------------------------------
            配置示例:
            k9s:
              refreshRate: 2
              maxConnRetry: 5
              readOnly: false
              noExitOnCtrlC: false
              ui:
                enableMouse: true
                headless: false
                logoless: false
                crumbsless: false
              skipLatestRevCheck: false
              logger:
                tail: 100
                buffer: 5000
                sinceSeconds: 60
    b.Lens
        a.安装Lens
            macOS:
            brew install --cask lens
            -------------------------------------------------------------------------------------------------
            Windows/Linux:
            下载地址:https://k8slens.dev/
            -------------------------------------------------------------------------------------------------
            验证安装:
            lens --version
        b.添加集群
            方法1:自动发现
            Lens会自动读取~/.kube/config中的集群
            -------------------------------------------------------------------------------------------------
            方法2:手动添加
            File -> Add Cluster
            选择kubeconfig文件或粘贴内容
            点击Add Cluster
        c.主要功能
            集群概览:
            查看集群状态、节点数量、Pod数量
            实时监控CPU、内存、磁盘使用
            -------------------------------------------------------------------------------------------------
            资源管理:
            查看所有资源类型
            实时更新资源状态
            支持YAML编辑
            -------------------------------------------------------------------------------------------------
            日志和终端:
            实时查看Pod日志
            多容器Pod日志切换
            Web终端访问容器
            支持多Tab
            -------------------------------------------------------------------------------------------------
            Helm Charts:
            浏览Helm仓库
            安装Chart
            管理Release
            -------------------------------------------------------------------------------------------------
            Prometheus集成:
            查看资源使用图表
            自定义监控面板
        d.扩展插件
            安装插件:
            File -> Extensions
            搜索插件名称
            点击Install
            -------------------------------------------------------------------------------------------------
            推荐插件:
            @alebcay/openlens-node-pod-menu                                      --节点Pod快捷菜单
            @nevalla/kube-rabbitmq                                               --RabbitMQ管理
    c.kubectx/kubens
        a.安装kubectx和kubens
            macOS:
            brew install kubectx
            -------------------------------------------------------------------------------------------------
            Linux:
            sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
            sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
            sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens
        b.kubectx使用
            查看所有上下文:
            kubectx                                                              --列出所有上下文
            -------------------------------------------------------------------------------------------------
            切换上下文:
            kubectx my-context                                                   --切换到指定上下文
            kubectx -                                                            --切换到上一个上下文
            -------------------------------------------------------------------------------------------------
            重命名上下文:
            kubectx new-name=old-name                                            --重命名上下文
            -------------------------------------------------------------------------------------------------
            删除上下文:
            kubectx -d context-name                                              --删除指定上下文
        c.kubens使用
            查看所有命名空间:
            kubens                                                               --列出所有命名空间
            -------------------------------------------------------------------------------------------------
            切换命名空间:
            kubens default                                                       --切换到default命名空间
            kubens -                                                             --切换到上一个命名空间
        d.配置补全
            Bash补全:
            echo 'source /opt/kubectx/completion/kubectx.bash' >>~/.bashrc
            echo 'source /opt/kubectx/completion/kubens.bash' >>~/.bashrc
            -------------------------------------------------------------------------------------------------
            Zsh补全:
            mkdir -p ~/.oh-my-zsh/completions
            ln -s /opt/kubectx/completion/kubectx.zsh ~/.oh-my-zsh/completions/_kubectx
            ln -s /opt/kubectx/completion/kubens.zsh ~/.oh-my-zsh/completions/_kubens
        e.使用技巧
            快速切换:
            kubectx production && kubens default                                 --同时切换上下文和命名空间
            -------------------------------------------------------------------------------------------------
            查看当前:
            kubectx -c                                                           --查看当前上下文
            kubens -c                                                            --查看当前命名空间
            -------------------------------------------------------------------------------------------------
            交互式选择(需要fzf):
            kubectx -i                                                           --交互式选择上下文
            kubens -i                                                            --交互式选择命名空间

3.9 [3]troubles

01.Pod故障排查
    a.Pod状态异常
        a.常见Pod状态
            Pending                                                              等待调度或拉取镜像
            Running                                                              正常运行中
            Succeeded                                                            成功完成(Job/CronJob)
            Failed                                                               执行失败
            Unknown                                                              状态未知(节点失联)
            CrashLoopBackOff                                                     容器反复崩溃重启
            ImagePullBackOff                                                     镜像拉取失败
            CreateContainerError                                                 容器创建失败
            ErrImagePull                                                         镜像拉取错误
        b.Pending状态排查
            kubectl describe pod <pod-name>                                      --查看详细信息
            -------------------------------------------------------------------------------------------------
            常见原因:
            原因1: 资源不足
            Events: 0/3 nodes are available: 3 Insufficient cpu.
            解决: 调整Pod资源请求或扩容节点
            -------------------------------------------------------------------------------------------------
            原因2: 节点选择器不匹配
            Events: 0/3 nodes are available: 3 node(s) didn't match node selector.
            解决: 检查nodeSelector配置或给节点打标签
            -------------------------------------------------------------------------------------------------
            原因3: PVC未绑定
            Events: pod has unbound immediate PersistentVolumeClaims
            解决: 检查PVC状态,创建对应的PV
        c.CrashLoopBackOff排查
            kubectl logs <pod-name>                                              --查看容器日志
            kubectl logs <pod-name> --previous                                   --查看崩溃前日志
            kubectl describe pod <pod-name>                                      --查看事件
            -------------------------------------------------------------------------------------------------
            常见原因:
            原因1: 应用启动失败
            解决: 检查应用日志,修复配置错误
            -------------------------------------------------------------------------------------------------
            原因2: 健康检查失败
            解决: 调整livenessProbe配置或修复应用
            -------------------------------------------------------------------------------------------------
            原因3: 资源限制过低
            解决: 增加resources.limits配置
        d.ImagePullBackOff排查
            kubectl describe pod <pod-name>                                      --查看拉取错误
            -------------------------------------------------------------------------------------------------
            常见原因:
            原因1: 镜像不存在
            Events: Failed to pull image "nginx:wrongtag": rpc error: code = NotFound
            解决: 检查镜像名称和标签是否正确
            -------------------------------------------------------------------------------------------------
            原因2: 私有镜像无认证
            Events: Failed to pull image: pull access denied
            解决: 创建imagePullSecrets
            kubectl create secret docker-registry my-secret \
              --docker-server=harbor.example.com \
              --docker-username=admin \
              --docker-password=password
            -------------------------------------------------------------------------------------------------
            原因3: 网络问题
            解决: 检查节点到镜像仓库的网络连通性
    b.容器启动失败
        a.查看容器状态
            kubectl get pods <pod-name> -o jsonpath='{.status.containerStatuses[*]}'   --查看容器状态
            kubectl describe pod <pod-name>                                      --查看详细事件
        b.启动命令错误
            常见错误:
            Error: failed to create containerd task: failed to create shim: OCI runtime create failed
            -------------------------------------------------------------------------------------------------
            排查步骤:
            1. 检查容器启动命令是否正确
            2. 检查容器工作目录是否存在
            3. 检查环境变量配置
            -------------------------------------------------------------------------------------------------
            kubectl logs <pod-name> -c <container-name>                          --查看容器日志
        c.权限问题
            常见错误:
            Error: container has runAsNonRoot and image has non-numeric user (www-data)
            -------------------------------------------------------------------------------------------------
            解决方案:
            方法1: 修改SecurityContext
            securityContext:
              runAsUser: 33                                                      --指定用户ID
              runAsGroup: 33
            -------------------------------------------------------------------------------------------------
            方法2: 修改镜像Dockerfile
            USER 1000:1000
        d.存储挂载失败
            常见错误:
            Error: failed to mount volume: mount failed: exit status 32
            -------------------------------------------------------------------------------------------------
            排查步骤:
            1. 检查PVC是否已绑定
            kubectl get pvc
            -------------------------------------------------------------------------------------------------
            2. 检查挂载路径权限
            kubectl exec <pod-name> -- ls -la /mount/path
            -------------------------------------------------------------------------------------------------
            3. 检查存储类是否支持访问模式
    c.镜像拉取失败
        a.认证问题
            创建Docker镜像仓库Secret:
            kubectl create secret docker-registry harbor-secret \
              --docker-server=harbor.example.com \
              --docker-username=admin \
              --docker-password=Harbor12345 \
              [email protected]
            -------------------------------------------------------------------------------------------------
            在Pod中使用:
            apiVersion: v1
            kind: Pod
            metadata:
              name: private-pod
            spec:
              containers:
              - name: app
                image: harbor.example.com/myapp:latest
              imagePullSecrets:
              - name: harbor-secret
        b.镜像地址错误
            检查镜像配置:
            kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].image}'
            -------------------------------------------------------------------------------------------------
            常见错误:
            错误1: 镜像名称拼写错误
            错误2: 标签不存在
            错误3: 镜像仓库地址错误
        c.网络连通性
            测试节点到镜像仓库连通性:
            kubectl debug node/<node-name> -it --image=busybox
            ping harbor.example.com
            nslookup harbor.example.com
            -------------------------------------------------------------------------------------------------
            检查代理配置:
            systemctl show docker --property=Environment                         --查看Docker代理配置
        d.镜像拉取策略
            imagePullPolicy配置:
            Always                                                               总是拉取最新镜像
            IfNotPresent                                                         本地不存在才拉取
            Never                                                                从不拉取,只使用本地镜像
            -------------------------------------------------------------------------------------------------
            配置示例:
            containers:
            - name: app
              image: nginx:1.21
              imagePullPolicy: IfNotPresent                                      --优先使用本地镜像

02.网络故障排查
    a.Service无法访问
        a.检查Service配置
            kubectl get svc <service-name>                                       --查看Service
            kubectl describe svc <service-name>                                  --查看详细信息
            kubectl get endpoints <service-name>                                 --查看Endpoints
            -------------------------------------------------------------------------------------------------
            常见问题:
            问题1: Endpoints为空
            原因: selector标签不匹配
            解决: 检查Service的selector是否与Pod的labels匹配
            kubectl get pods --show-labels
            -------------------------------------------------------------------------------------------------
            问题2: Service端口配置错误
            解决: 检查Service的port和targetPort配置
            kubectl get svc <service-name> -o yaml
        b.测试Service连通性
            在集群内测试:
            kubectl run test-pod --image=busybox -it --rm -- sh
            wget -O- http://<service-name>:<port>
            nslookup <service-name>
            -------------------------------------------------------------------------------------------------
            测试DNS解析:
            kubectl run test-dns --image=busybox -it --rm -- nslookup <service-name>
            kubectl run test-dns --image=busybox -it --rm -- nslookup <service-name>.<namespace>.svc.cluster.local
        c.检查网络策略
            kubectl get networkpolicies -n <namespace>                           --查看NetworkPolicy
            kubectl describe networkpolicy <policy-name>                         --查看详细信息
            -------------------------------------------------------------------------------------------------
            常见问题:
            NetworkPolicy阻止流量
            解决: 检查ingress和egress规则
    b.Pod间通信失败
        a.测试Pod连通性
            获取Pod IP:
            kubectl get pods -o wide                                             --查看Pod IP
            -------------------------------------------------------------------------------------------------
            测试连通性:
            kubectl exec <source-pod> -- ping <target-pod-ip>
            kubectl exec <source-pod> -- wget -O- http://<target-pod-ip>:<port>
        b.检查CNI插件
            查看CNI状态:
            kubectl get pods -n kube-system -l k8s-app=calico-node               --Calico
            kubectl get pods -n kube-system -l k8s-app=flannel                   --Flannel
            kubectl logs <cni-pod> -n kube-system                                --查看CNI日志
            -------------------------------------------------------------------------------------------------
            常见问题:
            问题1: CNI Pod未就绪
            解决: 检查CNI配置和日志
            -------------------------------------------------------------------------------------------------
            问题2: 网络插件配置错误
            解决: 检查/etc/cni/net.d/配置文件
        c.检查iptables规则
            查看iptables规则:
            iptables -t nat -L -n -v | grep <service-name>
            iptables -t filter -L -n -v
            -------------------------------------------------------------------------------------------------
            常见问题:
            kube-proxy未正常工作
            解决: 检查kube-proxy日志
            kubectl logs -n kube-system -l k8s-app=kube-proxy
    c.DNS解析问题
        a.测试DNS解析
            kubectl run test-dns --image=busybox -it --rm -- nslookup kubernetes.default
            kubectl run test-dns --image=busybox -it --rm -- nslookup <service-name>
            kubectl run test-dns --image=busybox -it --rm -- cat /etc/resolv.conf
        b.检查CoreDNS
            kubectl get pods -n kube-system -l k8s-app=kube-dns                  --查看CoreDNS状态
            kubectl logs -n kube-system -l k8s-app=kube-dns                      --查看CoreDNS日志
            kubectl get svc -n kube-system kube-dns                              --查看DNS Service
            -------------------------------------------------------------------------------------------------
            常见问题:
            问题1: CoreDNS Pod未就绪
            解决: 检查CoreDNS资源限制和日志
            -------------------------------------------------------------------------------------------------
            问题2: DNS解析超时
            解决: 检查CoreDNS配置
            kubectl get configmap coredns -n kube-system -o yaml
        c.检查Pod DNS配置
            kubectl get pod <pod-name> -o jsonpath='{.spec.dnsPolicy}'           --查看DNS策略
            kubectl exec <pod-name> -- cat /etc/resolv.conf                      --查看DNS配置
            -------------------------------------------------------------------------------------------------
            DNS策略:
            ClusterFirst                                                         使用集群DNS(默认)
            Default                                                              使用节点DNS
            ClusterFirstWithHostNet                                              hostNetwork Pod使用集群DNS
            None                                                                 自定义DNS配置
    d.Ingress访问失败
        a.检查Ingress配置
            kubectl get ingress                                                  --查看Ingress
            kubectl describe ingress <ingress-name>                              --查看详细信息
            kubectl get svc -n ingress-nginx                                     --查看Ingress Controller
            -------------------------------------------------------------------------------------------------
            常见问题:
            问题1: Ingress Controller未运行
            解决: 检查Ingress Controller状态
            kubectl get pods -n ingress-nginx
            -------------------------------------------------------------------------------------------------
            问题2: Ingress规则配置错误
            解决: 检查host和path配置
        b.检查Ingress Controller日志
            kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
            -------------------------------------------------------------------------------------------------
            常见错误:
            错误1: Backend Service不存在
            错误2: SSL证书配置错误
            错误3: 注解配置错误
        c.测试后端服务
            kubectl get svc <backend-service>                                    --检查后端Service
            kubectl get endpoints <backend-service>                              --检查Endpoints
            kubectl port-forward svc/<backend-service> 8080:80                   --测试Service

03.存储故障排查
    a.PVC绑定失败
        a.检查PVC状态
            kubectl get pvc                                                      --查看PVC状态
            kubectl describe pvc <pvc-name>                                      --查看详细信息
            kubectl get pv                                                       --查看PV状态
            -------------------------------------------------------------------------------------------------
            常见状态:
            Pending                                                              等待绑定PV
            Bound                                                                已绑定PV
            Lost                                                                 PV丢失
        b.PVC Pending排查
            kubectl describe pvc <pvc-name>                                      --查看Events
            -------------------------------------------------------------------------------------------------
            常见原因:
            原因1: 没有匹配的PV
            Events: no persistent volumes available
            解决: 创建符合要求的PV或使用StorageClass动态创建
            -------------------------------------------------------------------------------------------------
            原因2: StorageClass不存在
            Events: storageclass.storage.k8s.io "xxx" not found
            解决: 创建StorageClass或使用已存在的
            kubectl get storageclass
            -------------------------------------------------------------------------------------------------
            原因3: 访问模式不匹配
            Events: access mode mismatch
            解决: 调整PVC的accessModes配置
        c.检查StorageClass
            kubectl get storageclass                                             --查看StorageClass
            kubectl describe storageclass <sc-name>                              --查看详细信息
            -------------------------------------------------------------------------------------------------
            常见问题:
            问题1: StorageClass未设置为默认
            解决: 设置默认StorageClass
            kubectl patch storageclass <sc-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
    b.卷挂载失败
        a.检查挂载错误
            kubectl describe pod <pod-name>                                      --查看Events
            -------------------------------------------------------------------------------------------------
            常见错误:
            错误1: MountVolume.SetUp failed
            原因: 存储后端不可用或配置错误
            -------------------------------------------------------------------------------------------------
            错误2: Unable to attach or mount volumes
            原因: 节点无法访问存储
        b.检查存储插件
            kubectl get pods -n kube-system -l app=csi-driver                    --查看CSI驱动
            kubectl logs <csi-pod> -n kube-system                                --查看驱动日志
        c.检查节点挂载
            ssh到节点检查:
            mount | grep <volume-name>                                           --查看挂载点
            df -h                                                                --查看磁盘使用
            dmesg | tail                                                         --查看内核日志
    c.存储空间不足
        a.检查PVC使用量
            kubectl get pvc                                                      --查看PVC容量
            kubectl exec <pod-name> -- df -h /mount/path                         --查看实际使用
        b.扩容PVC
            编辑PVC:
            kubectl edit pvc <pvc-name>
            -------------------------------------------------------------------------------------------------
            修改spec.resources.requests.storage值:
            spec:
              resources:
                requests:
                  storage: 20Gi                                                  --扩容到20Gi
            -------------------------------------------------------------------------------------------------
            注意事项:
            1. StorageClass必须支持扩容(allowVolumeExpansion: true)
            2. 某些存储需要重启Pod才能生效
            3. 只能扩容不能缩容

04.节点故障排查
    a.节点NotReady
        a.检查节点状态
            kubectl get nodes                                                    --查看节点状态
            kubectl describe node <node-name>                                    --查看详细信息
            -------------------------------------------------------------------------------------------------
            常见状态:
            Ready                                                                节点健康
            NotReady                                                             节点异常
            SchedulingDisabled                                                   节点已禁止调度
            Unknown                                                              无法获取节点状态
        b.NotReady常见原因
            kubectl describe node <node-name>                                    --查看Conditions
            -------------------------------------------------------------------------------------------------
            原因1: kubelet未运行
            Condition: Ready=False, Reason: KubeletNotReady
            解决: 登录节点检查kubelet
            systemctl status kubelet
            systemctl restart kubelet
            journalctl -u kubelet -f
            -------------------------------------------------------------------------------------------------
            原因2: 网络插件故障
            解决: 检查CNI插件状态
            kubectl get pods -n kube-system
            -------------------------------------------------------------------------------------------------
            原因3: 磁盘压力
            Condition: DiskPressure=True
            解决: 清理磁盘空间
            df -h
            docker system prune -a
            -------------------------------------------------------------------------------------------------
            原因4: 内存压力
            Condition: MemoryPressure=True
            解决: 释放内存或增加节点资源
        c.检查节点日志
            journalctl -u kubelet -f                                             --查看kubelet日志
            dmesg | tail                                                         --查看内核日志
            /var/log/messages                                                    --查看系统日志
    b.节点资源耗尽
        a.检查节点资源
            kubectl top node                                                     --查看节点资源使用
            kubectl describe node <node-name>                                    --查看资源分配
            -------------------------------------------------------------------------------------------------
            查看Allocated resources:
            Resource                    Requests      Limits
            --------                    --------      ------
            cpu                         2500m (62%)   4000m (100%)
            memory                      6Gi (75%)     8Gi (100%)
        b.检查Pod资源
            kubectl top pods -n <namespace>                                      --查看Pod资源使用
            kubectl get pods -n <namespace> --sort-by=.status.podIP              --查看Pod分布
        c.解决方案
            方案1: 驱逐Pod
            kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --force
            -------------------------------------------------------------------------------------------------
            方案2: 扩容节点
            增加节点数量或升级节点规格
            -------------------------------------------------------------------------------------------------
            方案3: 调整资源配额
            减少Pod的requests和limits配置
    c.磁盘压力
        a.检查磁盘使用
            登录节点:
            df -h                                                                --查看磁盘使用
            du -sh /var/lib/docker                                               --Docker数据目录
            du -sh /var/lib/kubelet                                              --Kubelet数据目录
            du -sh /var/log                                                      --日志目录
        b.清理磁盘空间
            清理Docker:
            docker system df                                                     --查看Docker空间使用
            docker system prune -a                                               --清理未使用的镜像和容器
            docker volume prune                                                  --清理未使用的卷
            -------------------------------------------------------------------------------------------------
            清理日志:
            journalctl --vacuum-time=7d                                          --保留7天日志
            find /var/log -name "*.log" -mtime +7 -delete                        --删除7天前日志
            -------------------------------------------------------------------------------------------------
            清理Kubelet缓存:
            kubectl get pods --all-namespaces -o wide | grep <node-name>         --查看节点上的Pod
            kubectl delete pod <completed-pod> -n <namespace>                    --删除已完成的Pod
        c.配置日志轮转
            配置logrotate:
            /var/log/containers/*.log {
                daily
                rotate 7
                compress
                missingok
                notifempty
                create 0644 root root
            }
    d.网络插件问题
        a.检查CNI插件
            kubectl get pods -n kube-system -l k8s-app=calico-node               --Calico
            kubectl get pods -n kube-system -l app=flannel                       --Flannel
            kubectl get pods -n kube-system -l k8s-app=cilium                    --Cilium
            -------------------------------------------------------------------------------------------------
            检查日志:
            kubectl logs <cni-pod> -n kube-system
        b.检查CNI配置
            登录节点:
            ls /etc/cni/net.d/                                                   --查看CNI配置文件
            cat /etc/cni/net.d/10-calico.conflist                                --查看配置内容
        c.重启网络插件
            kubectl delete pod <cni-pod> -n kube-system                          --重启CNI Pod
            systemctl restart kubelet                                            --重启kubelet

05.集群故障排查
    a.组件故障
        a.检查控制平面组件
            kubectl get pods -n kube-system                                      --查看组件状态
            -------------------------------------------------------------------------------------------------
            关键组件:
            kube-apiserver                                                       API服务器
            kube-controller-manager                                              控制器管理器
            kube-scheduler                                                       调度器
            etcd                                                                 数据存储
        b.检查API Server
            kubectl get --raw /healthz                                           --健康检查
            kubectl get --raw /readyz                                            --就绪检查
            kubectl get cs                                                       --组件状态(已废弃)
            -------------------------------------------------------------------------------------------------
            检查日志:
            kubectl logs -n kube-system kube-apiserver-<node>
            journalctl -u kube-apiserver
        c.检查Controller Manager
            kubectl logs -n kube-system kube-controller-manager-<node>
            -------------------------------------------------------------------------------------------------
            常见问题:
            问题1: Leader选举失败
            问题2: 控制器循环错误
        d.检查Scheduler
            kubectl logs -n kube-system kube-scheduler-<node>
            -------------------------------------------------------------------------------------------------
            常见问题:
            问题1: Pod无法调度
            问题2: 调度策略错误
    b.证书过期
        a.检查证书有效期
            kubeadm certs check-expiration                                       --检查证书过期时间
            -------------------------------------------------------------------------------------------------
            输出示例:
            CERTIFICATE                EXPIRES                  RESIDUAL TIME
            admin.conf                 Jan 01, 2025 00:00 UTC   364d
            apiserver                  Jan 01, 2025 00:00 UTC   364d
            apiserver-kubelet-client   Jan 01, 2025 00:00 UTC   364d
        b.手动检查证书
            openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text      --查看证书详情
            openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates     --查看有效期
        c.更新证书
            备份证书:
            cp -r /etc/kubernetes/pki /etc/kubernetes/pki.backup
            -------------------------------------------------------------------------------------------------
            更新所有证书:
            kubeadm certs renew all                                              --更新所有证书
            -------------------------------------------------------------------------------------------------
            更新指定证书:
            kubeadm certs renew apiserver                                        --更新API Server证书
            kubeadm certs renew apiserver-kubelet-client                         --更新kubelet客户端证书
            -------------------------------------------------------------------------------------------------
            重启控制平面组件:
            kubectl -n kube-system delete pod -l component=kube-apiserver
            kubectl -n kube-system delete pod -l component=kube-controller-manager
            kubectl -n kube-system delete pod -l component=kube-scheduler
        d.更新kubeconfig
            cp /etc/kubernetes/admin.conf ~/.kube/config                         --更新配置文件
            kubeadm init phase kubeconfig all                                    --重新生成所有kubeconfig
    c.etcd问题
        a.检查etcd状态
            kubectl get pods -n kube-system -l component=etcd                    --查看etcd Pod
            kubectl logs -n kube-system etcd-<node>                              --查看etcd日志
            -------------------------------------------------------------------------------------------------
            使用etcdctl检查:
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              endpoint health
            -------------------------------------------------------------------------------------------------
            查看成员:
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              member list
        b.etcd备份
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              snapshot save /backup/etcd-snapshot.db
            -------------------------------------------------------------------------------------------------
            验证备份:
            ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot.db
        c.etcd恢复
            停止API Server:
            mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
            -------------------------------------------------------------------------------------------------
            恢复数据:
            ETCDCTL_API=3 etcdctl \
              snapshot restore /backup/etcd-snapshot.db \
              --data-dir=/var/lib/etcd-restore
            -------------------------------------------------------------------------------------------------
            修改etcd配置指向新数据目录,重启etcd和API Server
        d.etcd空间清理
            检查空间使用:
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              endpoint status --write-out=table
            -------------------------------------------------------------------------------------------------
            压缩历史版本:
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              compact $(ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --write-out="json" | jq -r '.[0].Status.header.revision')
            -------------------------------------------------------------------------------------------------
            碎片整理:
            ETCDCTL_API=3 etcdctl \
              --endpoints=https://127.0.0.1:2379 \
              --cacert=/etc/kubernetes/pki/etcd/ca.crt \
              --cert=/etc/kubernetes/pki/etcd/server.crt \
              --key=/etc/kubernetes/pki/etcd/server.key \
              defrag
    d.API Server问题
        a.API Server无法访问
            检查API Server进程:
            ps aux | grep kube-apiserver
            -------------------------------------------------------------------------------------------------
            检查监听端口:
            netstat -tlnp | grep 6443
            ss -tlnp | grep 6443
            -------------------------------------------------------------------------------------------------
            检查防火墙:
            iptables -L -n | grep 6443
            firewall-cmd --list-ports
        b.认证授权问题
            kubectl get --raw /api/v1                                            --测试API访问
            curl -k https://localhost:6443/api/v1                                --测试API访问
            -------------------------------------------------------------------------------------------------
            检查证书:
            openssl s_client -connect localhost:6443 -showcerts
            -------------------------------------------------------------------------------------------------
            检查RBAC:
            kubectl auth can-i --list                                            --查看当前用户权限
            kubectl auth can-i get pods                                          --检查特定权限
        c.API Server性能问题
            检查API Server指标:
            kubectl get --raw /metrics | grep apiserver_request_duration
            -------------------------------------------------------------------------------------------------
            检查慢请求:
            kubectl logs -n kube-system kube-apiserver-<node> | grep "Trace\["
            -------------------------------------------------------------------------------------------------
            优化方案:
            1. 增加API Server副本数
            2. 启用API优先级和公平性(APF)
            3. 调整etcd性能
    e.调度器问题
        a.Pod无法调度
            kubectl describe pod <pod-name>                                      --查看调度失败原因
            -------------------------------------------------------------------------------------------------
            常见原因:
            原因1: Insufficient cpu/memory
            解决: 调整资源请求或增加节点
            -------------------------------------------------------------------------------------------------
            原因2: No nodes are available
            解决: 检查节点状态和污点
            kubectl get nodes
            kubectl describe node <node-name> | grep Taints
            -------------------------------------------------------------------------------------------------
            原因3: Node affinity/selector不匹配
            解决: 调整Pod的nodeSelector或affinity配置
        b.调度器日志
            kubectl logs -n kube-system kube-scheduler-<node>
            -------------------------------------------------------------------------------------------------
            查看调度决策:
            kubectl logs -n kube-system kube-scheduler-<node> --v=5
        c.手动调度
            创建Pod时指定节点:
            apiVersion: v1
            kind: Pod
            metadata:
              name: manual-schedule-pod
            spec:
              nodeName: node01                                                   --手动指定节点
              containers:
              - name: nginx
                image: nginx:1.21

4 container

4.1 jdk

01.安装JDK
    a.Dockerfile
        # 使用官方的 OpenJDK 镜像作为基础镜像
        FROM openjdk:8-jdk-alpine

        # 设置工作目录
        WORKDIR /app

        # 复制应用程序文件到容器中(如果有的话)
        # COPY . /app

        # 暴露必要的端口(如果需要)
        # EXPOSE 8080

        # 设置默认命令(如果需要)
        # CMD ["java", "-jar", "your-app.jar"]
    b.构建镜像
        docker build -t my-jdk8-image .
    c.运行容器
        docker run -d --name my-jdk8-container my-jdk8-image

02.安装JDK
    a.拉取镜像
        docker pull openjdk:8-jdk-alpine
    b.运行容器
        docker run -d --name my-jdk8-container openjdk:8-jdk-alpine
    c.进入容器
        docker exec -it my-jdk8-container /bin/sh
    d.验证
        java -version

03.挂载全局
    a.挂载JDK到主机系统
        docker cp my-jdk8-container:/usr/lib/jvm/java-8-openjdk /path/to/host/directory
    b.环境变量:~/.bashrc 或 /etc/profile
        export JAVA_HOME=/path/to/host/directory/java-8-openjdk
        export PATH=$JAVA_HOME/bin:$PATH
    c.刷新配置
        source ~/.bashrc
    d.验证
        java -version

4.2 minio

01.常用信息1
    a.第1步:查看系统信息
        a.查看系统架构
            uname -m
        b.查看Docker版本
            docker version
        c.查看系统版本
            cat /etc/os-release
    b.第2步:选择合适的MinIO镜像
        a.镜像说明
            镜像名称:quay.io/minio/minio:latest
            说明:官方最新稳定版(推荐)
            推荐场景:生产环境
        b.镜像说明
            镜像名称:minio/minio:latest
            说明:Docker Hub 镜像
            推荐场景:备用选择
        c.镜像说明
            镜像名称:quay.io/minio/minio:RELEASE.2024-XX-XX
            说明:指定版本
            推荐场景:需要特定版本时
    c.第3步:安装前准备
        a.创建数据目录
            ---
            mkdir -p /data/minio/data
            ---
        b.创建配置目录
            ---
            mkdir -p /data/minio/config
            ---
    
02.常用信息2
    a.第1步:运行MinIO容器
        a.执行命令
            # 创建数据目录
            mkdir -p /opt/minio/data
            -------------------------------------------------------------------------------------------------
            # 运行 MinIO 容器
            docker run -d \
              --name minio \
              --restart=unless-stopped \
              -p 9000:9000 \
              -p 9001:9001 \
              -e MINIO_ROOT_USER=admin \
              -e MINIO_ROOT_PASSWORD=Admin@123456 \
              -v /opt/minio/data:/data \
              quay.io/minio/minio server /data --console-address ":9001"
            -------------------------------------------------------------------------------------------------
            目录                优点                                缺点
            /opt/minio/data     符合 Linux 规范,可选软件安装目录    无
            /data/minio/data    简洁明了                            需要单独分区
            /home/minio/data    用户目录                            不符合生产规范
        b.参数说明
            参数:-p 9000:9000
            说明:API 端口
        c.参数说明
            参数:-p 9001:9001
            说明:Web 控制台端口
        d.参数说明
            参数:MINIO_ROOT_USER
            说明:管理员账号(默认 minioadmin)
        e.参数说明
            参数:MINIO_ROOT_PASSWORD
            说明:密码(至少8位)
        f.参数说明
            参数:-v /data/minio/data:/data
            说明:数据持久化
        g.参数说明
            参数:--console-address ":9001"
            说明:指定控制台端口
    b.第2步:验证安装
        a.查看容器状态
            ---
            docker ps | grep minio
            ---
        b.查看日志
            ---
            docker logs minio
            ---
        c.检查端口
            ---
            netstat -tunlp | grep -E '9000|9001'
            ---
    c.访问方式
        a.Web控制台
            http://你的IP:9001
        b.API端点
            http://你的IP:9000

4.3 redis1

01.镜像
    docker pull redis:latest

02.部署
    docker run -itd --name redis -p 6379:6379 redis --requirepass myslayers

03.运行
    docker start d5667c109040                                               --启动容器
    docker stop d5667c109040                                                --停止容器
    docker restart d5667c109040                                             --重启容器
    docker rm d5667c109040                                                  --卸载容器
    docker logs d5667c109040                                                --查看日志
    docker exec -it redis /bin/bash                                         --进入容器
    redis-cli -p 6379 -a myslayers                                          --测试(用户root密码myslayers)

4.4 redis2

01.镜像
    docker pull redis:latest

02.运行命令下载默认的redis.conf   其中-P可指定下载目录
    wget -p /docker/redis/conf https://raw.githubusercontent.com/antirez/redis/5.0/redis.conf -O redis.conf

03.运行命令创建文件夹,用来映射配置文件
    mkdir -p /docker/redis/conf
    mkdir -p /docker/redis/data
    把2下载的redis.conf移动到4中的conf文件夹中

04.修改redis.conf文件
    requirepass xxxxx # 设置密码
    bind 127.0.0.1    # 注释掉,可以允许外网访问
    protected-mode no # yes改成no启用保护模式

05.运行命令,运行镜像,其中 -v 后面映射的目录为上面创建的文件夹地址
    docker run -d --privileged=true -p 6389:6379 --restart always -v /docker/redis/conf/redis.conf:/etc/redis/redis.conf -v /docker/redis/data:/data --name redis6389 redis redis-server /etc/redis/redis.conf --appendonly yes

06.运行成功
    docker start d5667c109040                                               --启动容器
    docker stop d5667c109040                                                --停止容器
    docker restart d5667c109040                                             --重启容器
    docker rm d5667c109040                                                  --卸载容器
    docker logs d5667c109040                                                --查看日志
    docker exec -it redis /bin/bash                                         --进入容器
    redis-cli -p 6379 -a myslayers                                          --测试(用户root密码myslayers)

4.5 mysql

01.镜像
    docker pull mysql:5.7.27
    docker pull mysql:latest

02.部署
    docker run -itd --name mysql5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.27
    # arm64,支持最低为8.0.31
    docker run -itd --name mysql8 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.31
    # arm64,支持最低为8.0.31,由于在docker属于linux系统,需要开启忽略大小写
    docker run -itd --name mysql8 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.31 --lower-case-table-names=1

03.运行
    docker start 80576e5ea74a                                               --启动容器
    docker stop 80576e5ea74a                                                --停止容器
    docker restart 80576e5ea74a                                             --重启容器
    docker rm 80576e5ea74a                                                  --移除容器
    docker logs 80576e5ea74a                                                --查看日志
    docker exec -it mysql8 /bin/bash                                        --进入容器
    docker exec -it mysql5 /bin/bash                                        --进入容器
    mysql -u root -p                                                        --测试(用户root密码4033665)

04.外部访问
    GRANT ALL PRIVILEGES on *.* to root@'%' WITH GRANT OPTION;
    ALTER user 'root'@'%' IDENTIFIED BY '123456' PASSWORD EXPIRE NEVER;
    ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    flush privileges;

4.6 postgres

01.镜像
    docker pull postgres:latest

02.部署
    docker run -itd -p 5432:5432 -v /data/postgres_docker/pgdata:/var/lib/postgresql/data --name pgsql postgres:latest

03.运行
    docker exec -it pgsql /bin/bash
    psql -h localhost -U postgres -p 5432                                  --(用户postgres 密码初始随机)
    alter user postgres with password '123456';

4.7 oracle11g

01.镜像
    docker pull rohitbasu77/oracle11g

02.部署
    docker run -d \
    --name myslayers-oracle11g \
    -p 40022:22 \
    -p 41521:1521 \
    -p 48080:8080 \
    rohitbasu77/oracle11g:latest
    ---------------------------------------------------------------------------------------------------------
    docker run -d --name oracle11g -p 40022:22 -p 41521:1521 -p 48080:8080 rohitbasu77/oracle11g:latest

03.运行
    docker start 80576e5ea74a                                               --启动容器
    docker stop 80576e5ea74a                                                --停止容器
    docker restart 80576e5ea74a                                             --重启容器
    docker rm 80576e5ea74a                                                  --移除容器
    docker logs 80576e5ea74a                                                --查看日志
    docker exec -it oracle11g /bin/bash                                     --进入容器
    ---------------------------------------------------------------------------------------------------------
    sqlplus system/oracle                                                   --测试(system/oracle)

04.连接
    a.Navicat连接
        hostname: localhost or docker machine ip
        port: 41521
        sid: xe
        username: system
        password: oracle(默认),tiger(新密码)
        Password for SYS & SYSTEM is oracle
        Password for fareuser, searchuser, bookinguser, checkinuser is rohit123
    b.SSH连接
        Login by SSH:
        ssh root@docker_machine_ip -p 40022
        password: admin                                                     --Oracle容器内的Ubuntu 14.04 LTS
        -----------------------------------------------------------------------------------------------------
        Login by SSH:
        ssh root@docker_machine_ip -p 22
        password: 403366X                                                   --docker_machine远程的debian

4.8 mongodb

01.镜像
    docker pull mongo:latest

02.部署
    docker run -itd --name mongodb -p 27017:27017 mongo --auth

03.运行(设置密码)
    docker exec -it mongodb mongo admin
    db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'}]});
    db.auth('admin', '123456')                                             --测试(用户admin 密码123456)

4.9 activemq

01.镜像
    docker pull webcenter/activemq

02.部署
    docker run -d --name activemq -p 61616:61616 -p 8161:8161 webcenter/activemq

03.运行
    docker exec -it activemq /bin/bash                                      --进入容器
    vi /opt/activemq/conf/jetty-realm.properties
    myslayers: 4033665, admin                                               --修改依次为账号、密码、角色

04.测试
    http://127.0.0.1:8161                                               --测试(用户admin 密码admin)

4.10 rabbitmq

01.镜像
    docker pull rabbitmq:management                                         --图形化界面:management

02.部署
    docker run -itd --name rabbitmq --hostname my-rabbit -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672  rabbitmq:management

03.运行
    docker start cfbabdfacbbe                                               --启动容器
    docker stop cfbabdfacbbe                                                --停止容器
    docker restart cfbabdfacbbe                                             --重启容器
    docker rm cfbabdfacbbe                                                  --移除容器
    docker logs cfbabdfacbbe                                                --查看日志
    docker exec -it rabbitmq /bin/bash                                      --进入容器
    http://127.0.0.1:15672                                                  --测试(用户guest 密码guest)

4.11 elasticsearch

01.解决:docker启动ElasticSearch,报错bootstrap checks failed
    sudo sysctl -w vm.max_map_count=262144                                  --临时修改
    ---------------------------------------------------------------------------------------------------------
    vi /etc/sysctl.conf                                                     --永久修改
    vm.max_map_count=262144                                                 --追加内容
    sudo sysctl -p                                                          --刷新

02.安装
    docker pull elasticsearch:6.4.3

03.部署
    docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 elasticsearch:6.4.3

04.安装中文分词插件
    docker exec -it elasticsearch bash
    ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.3/elasticsearch-analysis-ik-6.4.3.zip

05.配置
    docker exec -it elasticsearch bash
    vi ./config/elasticsearch.yml
    cluster.name: "docker-cluster"
    network.host: 0.0.0.0
    # minimum_master_nodes need to be explicitly set when bound on a public IP
    # set to 1 to allow single node clusters
    # Details: https://github.com/elastic/elasticsearch/pull/17288
    discovery.zen.minimum_master_nodes: 1

06.运行
    docker start cfbabdfacbbe                                               --启动容器
    docker stop cfbabdfacbbe                                                --停止容器
    docker restart cfbabdfacbbe                                             --重启容器
    docker rm cfbabdfacbbe                                                  --移除容器
    docker logs -f elasticsearch                                            --查看日志
    docker exec -it elasticsearch /bin/bash                                 --进入容器
    http://127.0.0.1:9200                                                   --测试

4.12 wordpress

01.镜像
    docker pull mysql:latest && docker pull wordpress:latest

02.部署
    docker run -d --privileged=true --name Mysql_Test -v /data/mysql:/var/lib/mysql -e MYSQL_DATABASE=wordpress -e MYSQL_ROOT_PASSWORD=4033665  mysql && docker run -d --name Wordpress_Test -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_PASSWORD=4033665 -p 8888:80 --link Mysql_Test:mysql wordpress

03.运行
    登录:http://halavah.top:8888/wp-admin/index.php
    登录:http://halavah.xyz:8888/wp-admin/index.php
    标题:勿因喜而轻诺!
    用户名:myslayers
    密码:4033665
    邮箱:[email protected]
    主题:Blackoot Lite

04.解决
    WordPress无法连接MySQL,无法识别MySQL8默认用户认证方式,plugin需要从caching_sha2_password变为mysql_native_password
    ---------------------------------------------------------------------------------------------------------
    docker exec -it Mysql_Test mysql -p
    mysql> mysql -u root -p
    mysql> use mysql;
    mysql> select host, user, plugin from user;
    mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '4033665';
    mysql> select host, user, plugin from user;
    mysql> exit

5 方式1:docker-compose.yml启动项目

5.1 gitlab

01.使用docker-compose部署
    a.安装
        sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    b.版本
        [root@bigdata01 ~]# sudo chmod +x /usr/local/bin/docker-compose         --授予当前用户执行权限
        [root@bigdata01 ~]# docker-compose version                              --版本
        docker-compose version 1.25.0, build 0a186604
        docker-py version: 4.1.0
        CPython version: 3.7.4
        OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019
    c.操作
        docker search gitlab                                                    --查看gitlab镜像
        docker pull gitlab/gitlab-ce:latest                                     --拉取gitlab镜像
    d.创建文件夹
        [root@bigdata01 ~]# cd /usr/local
        [root@bigdata01 local]# mkdir docker
        [root@bigdata01 local]# cd docker/
        [root@bigdata01 docker]# mkdir gitlab_docker
        [root@bigdata01 docker]# cd gitlab_docker/
        [root@bigdata01 gitlab_docker]# pwd
        /usr/local/docker/gitlab_docker
    e.创建docker-compose.yml文件
        cd /usr/local/docker/gitlab_docker
        vi docker-compose.yml
        -----------------------------------------------------------------------------------------------------
        version: '3.1'
        services:
          gitlab:
            image: 'gitlab/gitlab-ce:latest'
            container_name: gitlab
            restart: always
            environment:
              GITLAB_OMNIBUS_CONFIG: |
                external_url 'http://192.168.2.129:8929'
                gitlab_rails['gitlab_shell_ssh_port'] = 2224
            ports:
              - '8929:8929'
              - '2224:2224'
            volumes:
              - './config:/etc/gitlab'
              - './logs:/var/log/gitlab'
              - './data:/var/opt/gitlab'
    f.启动docker-compose
        cd /usr/local/docker/gitlab_docker
        docker-compose up -d                                                    --启动
        docker-compose logs -f gitlab                                           --日志
    g.访问
        http://127.0.0.1:8929                                                   --访问
        root
        glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
    h.获取默认密码
        [root@bigdata01 gitlab_docker]# docker exec -it gitlab bash             --进入容器
        root@f48f17cf9d8a:/# cat /etc/gitlab/initial_root_password              --查看密码
        # WARNING: This value is valid only in the following conditions
        #          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
        #          2. Password hasn't been changed manually, either via UI or via command line.
        #
        #          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

        Password: glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=

        # NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
        root@f48f17cf9d8a:/#
    i.修改密码
        http://127.0.0.1:8929/                                                  --访问
        root
        12345678
    j.设置容器开机自启动
        a.开启
            docker update --restart=always gitlab
        b.关闭
            docker update --restart=no gitlab

5.2 jenkins

00.使用docker-compose部署
    a.安装
        docker pull jenkins/jenkins:2.401.2-lts
    b.创建文件夹
        [root@bigdata01 ~]# cd /usr/local
        [root@bigdata01 local]# mkdir docker
        [root@bigdata01 local]# cd docker/
        [root@bigdata01 docker]# mkdir jenkins_docker
        [root@bigdata01 docker]# cd jenkins_docker/
        [root@bigdata01 gitlab_docker]# pwd
        /usr/local/docker/jenkins_docker
    c.创建docker-compose.yml文件
        cd /usr/local/docker/jenkins_docker
        vi docker-compose.yml
        -----------------------------------------------------------------------------------------------------
        version: "3.1"
        services:
          jenkins:
            image: jenkins/jenkins:2.401.2-lts
            container_name: jenkins
            ports:
              - 8080:8080
              - 50000:50000
            volumes:
              - ./data/:/var/jenkins_home/
    d.启动docker-compose
        cd /usr/local/docker/jenkins_docker
        docker-compose up -d                                                    --启动
        docker-compose logs -f jenkins                                          --日志
    e.解决权限问题
        cd /usr/local/docker/jenkins_docker
        chmod -R 777 data
    f.查看日志
        docker restart jenkins
        docker-compose logs -f jenkins                                          --日志
    g.访问
        http://127.0.0.1:8080                                                   --访问
        3b4119ffb9994eb9af73b3a38a89b311
    h.获取默认密码
        [root@bigdata01 gitlab_docker]# docker-compose logs -f jenkins          --查看日志
        jenkins    | Jenkins initial setup is required. An admin user has been created and a password generated.
        jenkins    | Please use the following password to proceed to installation:
        jenkins    |
        jenkins    | 3b4119ffb9994eb9af73b3a38a89b311
        jenkins    |
        jenkins    | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
    i.镜像地址
        [root@bigdata02 data]# vi /usr/local/docker/jenkins_docker/data/hudson.model.UpdateCenter.xml
        <?xml version='1.1' encoding='UTF-8'?>
        <sites>
          <site>
            <id>default</id>
            <url>http://mirror.esuni.jp/jenkins/updates/update-center.json</url>
          </site>
        </sites>
    j.下载插件
        Git Parameter
        Publish Over SSH
    k.修改密码
        http://127.0.0.1:8080                                                   --访问
        root
        12345678
    l.设置容器开机自启动
        a.开启
            docker update --restart=always jenkins
        b.关闭
            docker update --restart=no jenkins

01.DevOps
    DevOps的方式可以让公司能够更快地应对更新和市场发展变化,开发可以快速交付,部署也更加稳定。
    核心就在于简化Dev和Ops团队之间的流程,使整体软件开发过程更快速
    ---------------------------------------------------------------------------------------------------------
    整体的软件开发流程包括:
        PLAN:开发团队根据客户的目标制定开发计划
        CODE:根据PLAN开始编码过程,需要将不同版本的代码存储在一个库中。
        BUILD:编码完成后,需要将代码构建并且运行。
        TEST:成功构建项目后,需要测试代码是否存在BUG或错误。
        DEPLOY:代码经过手动测试和自动化测试后,认定代码已经准备好部署并且交给运维团队。
        OPERATE:运维团队将代码部署到生产环境中。
        MONITOR:项目部署上线后,需要持续的监控产品。
        INTEGRATE:然后将监控阶段收到的反馈发送回PLAN阶段,整体反复的流程就是DevOps的核心,即持续集成、持续部署。

02.CI/CD
    Jenkins最主要的工作就是将GitLab上可以构建的工程代码拉取并且进行构建,再根据流程可以选择发布到测试环境或是生产环境。
    ---------------------------------------------------------------------------------------------------------
    一般是GitLab上的代码经过大量的测试后,确定发行版本,再发布到生产环境。
    CI/CD可以理解为:
    CI过程即是通过Jenkins将代码拉取、构建、制作镜像交给测试人员测试。
        持续集成:让软件代码可以持续的集成到主干上,并自动构建和测试。
    CD过程即是通过Jenkins将打好标签的发行版本代码拉取、构建、制作镜像交给运维人员部署。
        持续交付:让经过持续集成的代码可以进行手动部署。
        持续部署:让可以持续交付的代码随时随地的自动化部署

03.Jenkins全局工具配置、目标服务器
    a.全局工具配置
        a.安装jdk、maven
            tar -zxvf jdk-8u202-linux-x64.tar.gz -C /usr/local/docker/jenkins_docker/data
            tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /usr/local/docker/jenkins_docker/data
        b.将jdk、maven配置到jenkins容器中
            jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> jdk1.8.0_202          /var/jenkins_home/jdk1.8.0_202
            jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> git-2.38.1            /usr/bin/git
            jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> apache-maven-3.6.3    /var/jenkins_home/apache-maven-3.6.3
    b.目标服务器
        jenkins -> Dashboard -> 系统管理 -> 系统配置 -> SSH Servers -> SSH Server Name        192.168.2.129
                                                                   -> Hostname               192.168.2.129
                                                                   -> Username               root
                                                                   -> Use Password           123456
                                                                   -> Remote Directory       /data/mytest_docker/

04.基础CI操作
    a.第1步
        工程mytest -> 工作空间 -> mytest / .git
                                          .idea
                                          src
                                          target:mytest-0.0.1-SNAPSHOT.jar
                                          pom.xm
    b.第2步
        Dockerfile         -> FROM daocloud.io/library/java:8u40-jdk
                              COPY mytest-0.0.1-SNAPSHOT.jar /usr/local/
                              WORKDIR /usr/local
                              CMD java -jar mytest-0.0.1-SNAPSHOT.jar

        docker-compose.yml -> version: '3.1'
                              services:
                                mytest:
                                  build:
                                    context: ./
                                    dockerfile: Dockerfile
                                  image: mytest: v1.0.0
                                  container_name: mytest
                                  ports:
                                    - 8088:8088

        MyTest.java        -> @RestController
                              public class MyTest {
                                  @GetMapping("/test")
                                  public String Test() {
                                      return "Jenkin 3.0";
                                  }
                              }
    c.第3步
        工程mytest -> 配置 -> 源码管理 -> http://192.168.2.129:8929/troyekk/mytest.git -> 保存

    d.第4步
        工程mytest -> 配置 -> Build Steps -> 调用顶层 Maven 目标 -> Maven版本:apache-maven-3.6.3
                                                                  目标:clean package -DskipTests
    e.第5步
        工程mytest -> 配置 -> 构建后操作 -> Send build artifacts over SSH -> Name:192.168.2.129
                                                                            Transfer Set Source files:target/*.jar docker/*
                                                                            Exec command:cd /data/mytest_docker/docker/
                                                                                          mv ../target/*.jar ./
                                                                                          docker-compose down
                                                                                          docker-compose up -d --build
                                                                                          docker image prune -f
    f.第6步
        工程mytest -> 立即构建(手动)
    g.第7步
        http://192.168.2.129:8088/test

05.基础CD操作
    a.基于tag
        git tag v1.0.0 && git push origin v1.0.0
        git tag v2.0.0 && git push origin v2.0.0
    b.第1步
        工程mytest -> 配置 -> 参数化构建过程 -> 参数类型:标签、默认值:origin/master
    c.第2步
        工程mytest -> 配置 -> Build Steps -> 执行 shell         -> git checkout $tag
    d.第3步
        工程mytest -> 立即构建(手动)
    e.第4步
        http://192.168.2.129:8088/test

5.3 sonarqube

00.使用docker-compose部署
    a.安装
        docker pull postgres:latest
        docker pull sonarqube:8.9.3-community
    b.创建文件夹
        /data/sonarqube_docker/
    c.创建docker-compose.yml文件
        vi docker-compose.yml
        -----------------------------------------------------------------------------------------------------
        version: "3"

        services:
          sonarqube:
            image: sonarqube:7.4-community
            ports:
              - "9089:9000"
            networks:
              - sonarnet
            environment:
              - SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
            volumes:
              - sonarqube_conf:/opt/sonarqube/conf
              - sonarqube_data:/opt/sonarqube/data
              - sonarqube_extensions:/opt/sonarqube/extensions
              - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins

          db:
            image: postgres:11.1
            networks:
              - sonarnet
            environment:
              - POSTGRES_USER=sonar
              - POSTGRES_PASSWORD=sonar
            volumes:
              - postgresql_data:/var/lib/postgresql/data

        networks:
          sonarnet:
            driver: bridge

        volumes:
          sonarqube_conf:
          sonarqube_data:
          sonarqube_extensions:
          sonarqube_bundled-plugins:
          postgresql_data:

    c.创建docker-compose.yml文件
        version: "3.1"
        services:
          db:
              image: postgres
              container_name: db
              ports:
                - 5432:5432
              networks:
                - sonarnet
              environment:
                POSTGRES_USER: sonar
             POSTGRES_PASSWORD: sonar
          sonarqube:
              image: sonarqube:8.9.3-community
              container_name: sonarqube
              depends_on:
                - db
              ports:
                - 9089:9000
              networks:
                - sonarnet
              environment:
                SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
                SONAR_JDBC_USERNAME: sonar
                SONAR_JDBC_PASSWORD: sonar
        networks:
          sonarnet:
            driver: bridge
    d.启动docker-compose
        cd /data/sonarqube_docker/
        docker-compose up -d                                                    --启动
        docker logs -f sonargube                                                --日志
    e.配置
        vi /etc/sysctl.conf                                                     --永久修改
        vm.max_map_count=262144                                                 --追加内容
        sudo sysctl -p                                                          --刷新
    f.访问
        http://127.0.0.1:9089/                                                  --访问(初始用户admin、初始密码admin)
        admin
        12345678
    g.设置容器开机自启动
        a.开启
            docker update --restart=always sonarqube db
        b.关闭
            docker update --restart=no sonarqube db
    h.容器
        docker stop  sonarqube db
        docker start sonarqube db

01.介绍
    SonarQube 是一个开源的代码分析平台,用来持续分析和评测项目源代码的质量。
    通过SonarQube我们可以检测出项目中重复代码,潜在bug,代码规范,安全性漏洞等问题,并通过SonarQube web UI展示出来。
    1、代码质量和安全扫描和分析平台。
    2、多维度分析代码:代码量、安全隐患、编写规范隐患、重复度、复杂度、代码增量、测试覆盖率等。
    3、支持25+编程语言的代码扫描和分析,包含java\python\C#\javascript\go\C++等。
    4、涵盖了编程语言的静态扫描规则: 代码编写规范+安全规范。
    5、能够与代码编辑器、CI/CD平台完美集成。
    6、能够与SCM集成,可以直接在平台上看到代码问题是由哪位开发人员提交。
    7、帮助程序猿写出更干净、更安全的代码。

02.sonar静态代码扫描由2部分组成:sonarQube平台,sonar-scanner扫描器
    Web界面管理平台
    1)展示所有的项目代码的质量数据。
    2)配置质量规则、管理项目、配置通知、配置SCM等。
    sonarScanner: 代码扫描工具
    1)专门用来扫描和分析项目代码。支持20+语言。
    2)代码扫描和分析完成之后,会将扫描结果存储到数据库当中,在sonarQube平台可以看到扫描数据。

03.方式一:Maven实现代码检测
    a.修改Maven的settings.xml文件配置Sonar Qube信息
        <profile>
            <id>sonar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <sonar.login>admin</sonar.login>
                <sonar.password>12345678</sonar.password>
                <sonar.host.url>http://192.168.2.129:9089</sonar.host.url>
            </properties>
        </profile>
    b.执行命令检测代码
        cd D:\software_xare\workspace_idea\mytest
        mvn sonar:sonar
    c.查看Sonar Qube界面检测结果
        略

04.方式二:Sonar-scanner实现代码检测
    a.安装
        [root@bigdata02 data]# cd /data/jenkins_docker/data/
        [root@bigdata02 data]# unzip sonar-scanner-cli-4.8.0.2856-linux.zip
        [root@bigdata02 conf]# cd /data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/bin/
        [root@bigdata02 bin]# pwd
        /data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/bin
    b.配置
        vi /data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/conf/sonar-scanner.properties
        #----- Default SonarQube server
        sonar.host.url=http://192.168.2.129:9089

        #----- Default source code encoding
        sonar.sourceEncoding=UTF-8
    c.执行命令检测代码
        [root@bigdata02 mytest]# cd /data/jenkins_docker/data/workspace/mytest/
        [root@bigdata02 mytest]# /data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=linux-test -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=linux-test -Dsonar.java.binaries=./target/

05.方式三:Jenkins整合SonarQube
    a.全局工具配置
        jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> sonar-scanner-4.8.0.2856-linux     /var/jenkins_home/sonar-scanner-4.8.0.2856-linux
    b. SonarQube servers
        jenkins -> Dashboard -> 系统管理 -> 系统配置 ->  SonarQube servers -> Name            SonarQube
                                                                             Server URL      http://192.168.2.129:9089/
                                                                             Secret text     003ebe4eacdae15ca461a47af1eb4118d93caaa3
    c.第1步
        工程mytest -> 配置 -> Build Steps -> Execute SonarQube Scanner -> JDK                 jdk1.8.0_202
                                                                       -> Analysis properties sonar.projectname=${JOB_NAME}
                                                                                              sonar.projectKey=${JOB_NAME}
                                                                                              sonar.source=./
                                                                                              sonar.java.binaries=target
    d.第2步
        工程mytest -> 立即构建(手动)
    e.第3步
        http://192.168.2.129:9089/

5.4 rabbitmq+canal

01.环境配置
    a.docker-compose.yml
        version: '3.8'

        services:
          redis:
            container_name: redis
            image: redis:6.2.7
            restart: always
            networks:
              - app_net
            ports:
              - "6379:6379"
            volumes:
              - /usr/local/docker/redis/data:/data
              - /usr/local/docker/redis/config/redis.conf:/usr/local/redis/config/redis.conf
              - /usr/local/docker/redis/logs:/logs
            command: [ "redis-server","/usr/local/redis/config/redis.conf" ]

          mysql:
            container_name: mysql
            image: mysql:8.0.30
            restart: always
            networks:
              - app_net
            ports:
              - "3306:3306"
            volumes:
              - /usr/local/docker/mysql/data:/var/lib/mysql
              - /usr/local/docker/mysql/config:/etc/mysql/conf.d
            environment:
              MYSQL_ROOT_PASSWORD: root
              TZ: Asia/Shanghai
            command:
              --default-authentication-plugin=mysql_native_password
              --character-set-server=utf8mb4
              --collation-server=utf8mb4_general_ci
              --explicit_defaults_for_timestamp=true
              --lower_case_table_names=1
              --log-bin=/var/lib/mysql/mysql-bin
              --server-id=1
              --binlog-format=ROW
              --expire_logs_days=7
              --max_binlog_size=500M

          canal:
            image: canal/canal-server:v1.1.5
            container_name: canal
            restart: always
            ports:
              - 11110:11110
              - 11111:11111
              - 11112:11112
            volumes:
              - /usr/local/docker/canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties
              - /usr/local/docker/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties
              - /usr/local/docker/canal/logs:/home/admin/canal-server/logs
            networks:
              - app_net
            depends_on:
              - mysql
              - rabbitmq

          rabbitmq:
            image: rabbitmq:3-management
            container_name: rabbitmq
            restart: always
            ports:
              - "5672:5672"
              - "15672:15672"
            volumes:
              - /usr/local/docker/rabbitmq/data/:/var/lib/rabbitmq/
              - /usr/local/docker/rabbitmq/log/:/var/log/rabbitmq/
            environment:
              - RABBITMQ_DEFAULT_USER=guest
              - RABBITMQ_DEFAULT_PASS=guest
            networks:
              - app_net

        networks:
          app_net:
            driver: bridge
    b.常用命令
        # 后台启动容器编排文件
        docker-compose up -d [service]
        # 停止up命令所启动的容器,并移除网络
        docker-compose down
        # 进入指定容器
        docker-compose exec [service]
        # 列出项目中所有的容器
        docker-compose ps [service]
        # 重启项目中容器
        docker-compose restart [service]
        # 删除项目中所有容器
        docker-compose rm -f [service]
        # 启动项目中容器(或指定容器)
        docker-compose start [service]
        # 暂停项目中容器(或指定容器)
        docker-compose stop [service]
    c.镜像服务启动状态
        [root@lavm-13jmyj9ugf docker]# docker ps -a
        CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS                                                                                                                                                 NAMES
        0d4260bc557b   canal/canal-server:v1.1.5       "/alidata/bin/main.s…"   38 minutes ago   Up 38 minutes   9100/tcp, 0.0.0.0:11110-11112->11110-11112/tcp, :::11110-11112->11110-11112/tcp                                                                       canal
        c66b3f1f13a9   mysql:8.0.30                    "docker-entrypoint.s…"   38 minutes ago   Up 38 minutes   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                                                                                  mysql
        645e27bd4001   rabbitmq:3-management           "docker-entrypoint.s…"   5 hours ago      Up 49 minutes   4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, :::5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp, :::15672->15672/tcp   rabbitmq
        f55d42cbbd8e   redis:6.2.7                     "docker-entrypoint.s…"   3 days ago       Up 49 minutes   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp                                                                                                             redis

02.binlog配置
    a.docker-compose command 配置 binlog
        --log-bin=/var/lib/mysql/mysql-bin
        --server-id=1
        --binlog-format=ROW
        --expire_logs_days=7
        --max_binlog_size=500M
    b.创建canal用户,以及查看是否开启binlog
        mysql> CREATE USER canal IDENTIFIED BY 'canal';
        Query OK, 0 rows affected (0.05 sec)

        mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
        Query OK, 0 rows affected (0.05 sec)

        mysql> FLUSH PRIVILEGES;
        Query OK, 0 rows affected (0.05 sec)

        mysql> select * from mysql.user where User = 'canal';
        +------+-------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+--------------------------+-----------------+
        | Host | User  | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Show_db_priv | Super_priv | Create_tmp_table_priv | Lock_tables_priv | Execute_priv | Repl_slave_priv | Repl_client_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Create_user_priv | Event_priv | Trigger_priv | Create_tablespace_priv | ssl_type | ssl_cipher | x509_issuer | x509_subject | max_questions | max_updates | max_connections | max_user_connections | plugin                | authentication_string                     | password_expired | password_last_changed | password_lifetime | account_locked | Create_role_priv | Drop_role_priv | Password_reuse_history | Password_reuse_time | Password_require_current | User_attributes |
        +------+-------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+--------------------------+-----------------+
        | %    | canal | Y           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          | N            | N          | N                     | N                | N            | Y               | Y                | N                | N              | N                   | N                  | N                | N          | N            | N                      |          |            |             |              |             0 |           0 |               0 |                    0 | mysql_native_password | *E3619321C1A937C46A0D8BD1DAC39F93B27D4458 | N                |   2025-03-10 11:53:49 | NULL              | N              | N                | N              | NULL                   | NULL                | NULL                     | NULL            |
        +------+-------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+--------------------------+-----------------+
        1 row in set (0.08 sec)

        mysql> show variables like 'log_bin';
        +---------------+-------+
        | Variable_name | Value |
        +---------------+-------+
        | log_bin       | ON    |
        +---------------+-------+
        1 row in set (0.30 sec)

03.canal相关配置文件
    a.canal.properties主要核心配置
        canal.serverMode=rabbitMQ:选择 RabbitMQ 作为通知服务模型
        rabbitmq.host=rabbitmq:基于 Docker 同一网络下,可以使用容器名称代替 host
        rabbitmq.queue、rabbitmq.routingKey、rabbitmq.exchange : RabbitMQ 的三件套,用于后续创建具体通道监听
        -----------------------------------------------------------------------------------------------------
        #################################################
        #########               common argument         #############
        #################################################
        # tcp, kafka, rocketMQ, rabbitMQ, pulsarMQ 支持的服务模型,tcp直连或mq,此处我选择RabbitMQ
        canal.serverMode=rabbitMQ

        ##################################################
        #########                   RabbitMQ         #############
        ##################################################
        rabbitmq.host=rabbitmq
        rabbitmq.virtual.host=/
        rabbitmq.exchange=canal-exchange
        rabbitmq.username=guest
        rabbitmq.password=guest
        rabbitmq.queue=canal-queue
        rabbitmq.routingKey=canal-routing-key
        rabbitmq.deliveryMode=
    b.instance.properties 主要核心配置
        canal.instance.master.address   数据库地址
        canal.instance.dbUsername       数据库用户名
        canal.instance.dbPassword           数据库密码
        canal.mq.topic                  RabbitMQ路由
        -----------------------------------------------------------------------------------------------------
        # 数据地址,此处mysql,是因为canal和mysql是同一network下,可以使用容器名称代替具体ip
        canal.instance.master.address=mysql:3306

        # username/password
        canal.instance.dbUsername=root
        canal.instance.dbPassword=root

        # mq config
        canal.mq.topic=canal-routing-key
    c.canal.properties 完整文件
        #################################################
        #########               common argument         #############
        #################################################
        canal.ip=
        canal.register.ip=
        canal.port=11111
        canal.metrics.pull.port=11112
        canal.admin.port=11110
        canal.admin.user=admin
        canal.admin.passwd=
        canal.zkServers=
        canal.zookeeper.flush.period=1000
        canal.withoutNetty=false
        canal.serverMode=rabbitMQ
        canal.file.data.dir=${canal.conf.dir}
        canal.file.flush.period=1000
        canal.instance.memory.buffer.size=16384
        canal.instance.memory.buffer.memunit=1024
        canal.instance.memory.batch.mode=MEMSIZE
        canal.instance.memory.rawEntry=true
        canal.instance.detecting.enable=false
        canal.instance.detecting.sql=select 1
        canal.instance.detecting.interval.time=3
        canal.instance.detecting.retry.threshold=3
        canal.instance.detecting.heartbeatHaEnable=false
        canal.instance.transaction.size=1024
        canal.instance.fallbackIntervalInSeconds=60
        canal.instance.network.receiveBufferSize=16384
        canal.instance.network.sendBufferSize=16384
        canal.instance.network.soTimeout=30
        canal.instance.filter.druid.ddl=true
        canal.instance.filter.query.dcl=false
        canal.instance.filter.query.dml=false
        canal.instance.filter.query.ddl=false
        canal.instance.filter.table.error=false
        canal.instance.filter.rows=false
        canal.instance.filter.transaction.entry=false
        canal.instance.filter.dml.insert=false
        canal.instance.filter.dml.update=false
        canal.instance.filter.dml.delete=false
        canal.instance.binlog.format=ROW,STATEMENT,MIXED
        canal.instance.binlog.image=FULL,MINIMAL,NOBLOB
        canal.instance.get.ddl.isolation=false
        canal.instance.parser.parallel=true
        canal.instance.parser.parallelThreadSize = 16
        canal.instance.parser.parallelBufferSize=256
        canal.instance.tsdb.enable=true
        canal.instance.tsdb.dir=${canal.file.data.dir:../conf}/${canal.instance.destination:}
        canal.instance.tsdb.url=jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
        canal.instance.tsdb.dbUsername=canal
        canal.instance.tsdb.dbPassword=canal
        canal.instance.tsdb.snapshot.interval=24
        canal.instance.tsdb.snapshot.expire=360
        #################################################
        #########               destinations            #############
        #################################################
        canal.destinations=example
        canal.conf.dir=../conf
        canal.auto.scan=true
        canal.auto.scan.interval=5
        canal.auto.reset.latest.pos.mode=false
        canal.instance.tsdb.spring.xml=classpath:spring/tsdb/h2-tsdb.xml
        canal.instance.global.mode=spring
        canal.instance.global.lazy=false
        canal.instance.global.manager.address=${canal.admin.manager}
        canal.instance.global.spring.xml=classpath:spring/file-instance.xml
        ##################################################
        #########             MQ Properties      #############
        ##################################################
        canal.aliyun.accessKey=
        canal.aliyun.secretKey=
        canal.aliyun.uid=
        canal.mq.flatMessage=true
        canal.mq.canalBatchSize=50
        canal.mq.canalGetTimeout=100
        canal.mq.accessChannel=local
        canal.mq.database.hash=true
        canal.mq.send.thread.size=30
        canal.mq.build.thread.size=8
        ##################################################
        #########                    Kafka                   #############
        ##################################################
        kafka.bootstrap.servers=127.0.0.1:9092
        kafka.acks=all
        kafka.compression.type=none
        kafka.batch.size=16384
        kafka.linger.ms=1
        kafka.max.request.size=1048576
        kafka.buffer.memory=33554432
        kafka.max.in.flight.requests.per.connection=1
        kafka.retries=0
        kafka.kerberos.enable=false
        kafka.kerberos.krb5.file=../conf/kerberos/krb5.conf
        kafka.kerberos.jaas.file=../conf/kerberos/jaas.conf
        ##################################################
        #########                   RocketMQ         #############
        ##################################################
        rocketmq.producer.group=test
        rocketmq.enable.message.trace=false
        rocketmq.customized.trace.topic=
        rocketmq.namespace=
        rocketmq.namesrv.addr=127.0.0.1:9876
        rocketmq.retry.times.when.send.failed=0
        rocketmq.vip.channel.enabled=false
        rocketmq.tag=
        ##################################################
        #########                   RabbitMQ         #############
        ##################################################
        rabbitmq.host=rabbitmq
        rabbitmq.virtual.host=/
        rabbitmq.exchange=canal-exchange
        rabbitmq.username=guest
        rabbitmq.password=guest
        rabbitmq.queue=canal-queue
        rabbitmq.routingKey=canal-routing-key
        rabbitmq.deliveryMode=
        ##################################################
        #########                     Pulsar         #############
        ##################################################
        pulsarmq.serverUrl=
        pulsarmq.roleToken=
        pulsarmq.topicTenantPrefix=
    d.instance.properties 完整文件
        #################################################
        ## mysql serverId , v1.0.26+ will autoGen
        # canal.instance.mysql.slaveId=0

        # enable gtid use true/false
        canal.instance.gtidon=false

        # rds oss binlog
        canal.instance.rds.accesskey=
        canal.instance.rds.secretkey=
        canal.instance.rds.instanceId=

        # position info
        canal.instance.master.address=mysql:3306
        canal.instance.master.journal.name=
        canal.instance.master.position=
        canal.instance.master.timestamp=
        canal.instance.master.gtid=

        # multi stream for polardbx
        canal.instance.multi.stream.on=false

        # ssl
        #canal.instance.master.sslMode=DISABLED
        #canal.instance.master.tlsVersions=
        #canal.instance.master.trustCertificateKeyStoreType=
        #canal.instance.master.trustCertificateKeyStoreUrl=
        #canal.instance.master.trustCertificateKeyStorePassword=
        #canal.instance.master.clientCertificateKeyStoreType=
        #canal.instance.master.clientCertificateKeyStoreUrl=
        #canal.instance.master.clientCertificateKeyStorePassword=

        # table meta tsdb info
        canal.instance.tsdb.enable=true
        #canal.instance.tsdb.url=jdbc:mysql://127.0.0.1:3306/canal_tsdb
        #canal.instance.tsdb.dbUsername=canal
        #canal.instance.tsdb.dbPassword=canal

        #canal.instance.standby.address =
        #canal.instance.standby.journal.name =
        #canal.instance.standby.position =
        #canal.instance.standby.timestamp =
        #canal.instance.standby.gtid=

        # username/password
        canal.instance.dbUsername=root
        canal.instance.dbPassword=admin123!@#
        canal.instance.connectionCharset = UTF-8
        # enable druid Decrypt database password
        canal.instance.enableDruid=false
        #canal.instance.pwdPublicKey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALK4BUxdDltRRE5/zXpVEVPUgunvscYFtEip3pmLlhrWpacX7y7GCMo2/JM6LeHmiiNdH1FWgGCpUfircSwlWKUCAwEAAQ==

        # table regex
        canal.instance.filter.regex=.*\\..*
        # table black regex
        canal.instance.filter.black.regex=mysql\\.slave_.*
        # table field filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)
        #canal.instance.filter.field=test1.t_product:id/subject/keywords,test2.t_company:id/name/contact/ch
        # table field black filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)
        #canal.instance.filter.black.field=test1.t_product:subject/product_image,test2.t_company:id/name/contact/ch

        # mq config
        canal.mq.topic=canal-routing-key
        # dynamic topic route by schema or table regex
        #canal.mq.dynamicTopic=mytest1.user,topic2:mytest2\\..*,.*\\..*
        canal.mq.partition=0
        # hash partition config
        #canal.mq.enableDynamicQueuePartition=false
        #canal.mq.partitionsNum=3
        #canal.mq.dynamicTopicPartitionNum=test.*:4,mycanal:6
        #canal.mq.partitionHash=test.table:id^name,.*\\..*
        #################################################
    e.检查配置是否与宿主机一致
        进入容器内部:docker exec -it canal bash
        检查配置文件内容是否与宿主机一致:
        cat /home/admin/canal-server/conf/canal.properties
        cat /home/admin/canal-server/conf/example/instance.properties
    f.开启相关端口防火墙配置
        canal:11110、11111、11112
        mysql:3306
        redis:6379
        RabbitMQ: 15672、5672

04.代码实现
    a.相关pom依赖引入
        <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.7.15</version>
          <relativePath/> <!-- lookup parent from repository -->
        </parent>

        <!-- Spring Boot MQ 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

          <!-- canal -->
        <dependency>
            <groupId>com.alibaba.otter</groupId>
            <artifactId>canal.client</artifactId>
            <version>1.1.0</version>
        </dependency>
    b.完整pom.xml
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>

            <groupId>com.neo</groupId>
            <artifactId>code-repository</artifactId>
            <version>1.0-SNAPSHOT</version>
            <packaging>jar</packaging>

            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.7.15</version>
                <relativePath/> <!-- lookup parent from repository -->
            </parent>

            <name>code-repository</name>

            <properties>
                <java.version>17</java.version>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <hutool.version>5.8.20</hutool.version>
                <mysql.version>8.0.30</mysql.version>
                <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
                <redis.version>3.1.0</redis.version>
                <druid.version>1.2.16</druid.version>
                <fastjson.version>1.2.83</fastjson.version>
                <sa-token.version>1.37.0</sa-token.version>
            </properties>

            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-data-redis</artifactId>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-test</artifactId>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-mail</artifactId>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-aop</artifactId>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-amqp</artifactId>
                </dependency>

                <dependency>
                    <groupId>org.apache.commons</groupId>
                    <artifactId>commons-pool2</artifactId>
                </dependency>

                <dependency>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                    <version>${mybatis-plus.version}</version>
                </dependency>

                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>

                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid-spring-boot-starter</artifactId>
                    <version>${druid.version}</version>
                </dependency>

                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>fastjson</artifactId>
                    <version>${fastjson.version}</version>
                </dependency>

                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <optional>true</optional>
                </dependency>

                <dependency>
                    <groupId>cn.hutool</groupId>
                    <artifactId>hutool-all</artifactId>
                    <version>${hutool.version}</version>
                </dependency>

                <dependency>
                    <groupId>cn.dev33</groupId>
                    <artifactId>sa-token-spring-boot-starter</artifactId>
                    <version>${sa-token.version}</version>
                </dependency>
                <dependency>
                    <groupId>cn.dev33</groupId>
                    <artifactId>sa-token-redis-jackson</artifactId>
                    <version>${sa-token.version}</version>
                </dependency>

                <dependency>
                    <groupId>com.alibaba.otter</groupId>
                    <artifactId>canal.client</artifactId>
                    <version>1.1.0</version>
                </dependency>

            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                    </plugin>
                </plugins>
            </build>
        </project>
    c.application.yml 配置
        spring:
          rabbitmq:
            host: localhost
            port: 5672
            username: guest
            password: guest
            virtual-host: /
            publisher-confirm-type: correlated
            publisher-returns: true
    d.完整application.yml配置
        server:
          port: 8088
          servlet:
            context-path: /api

        spring:
          datasource:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://localhost:3306/db_v1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
            username: root
            password: root
            druid:
              initial-size: 5
              min-idle: 5
              max-active: 20
              max-wait: 60000
              validation-query: SELECT 1
              test-while-idle: true
              stat-view-servlet:
                enabled: true
                url-pattern: /druid/*
                login-username: admin
                login-password: admin123
              web-stat-filter:
                enabled: true
                url-pattern: /*
                exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
              filter:
                stat:
                  enabled: true
                  log-slow-sql: true
                  slow-sql-millis: 1000
                wall:
                  enabled: true
                  config:
                    drop-table-allow: false
          redis:
            host: localhost
            port: 6379
            password: 123456
            database: 0
            timeout: 5000
            lettuce:
              pool:
                max-active: 8
                max-wait: -1
                max-idle: 8
                min-idle: 0
          mail:
            host: smtp.aliyun.com
            username:
            password:
            port: 25
            properties:
              mail:
                smtp:
                  auth: true
                starttls:
                  enable: true
                  required: true
          rabbitmq:
            host: localhost
            port: 5672
            username: guest
            password: guest
            virtual-host: /
            publisher-confirm-type: correlated
            publisher-returns: true

        mybatis-plus:
          mapper-locations: classpath*:mapper/*_Mapper.xml
          global-config:
            db-config:
              logic-delete-field: delFlag
              logic-delete-value: 1
              logic-not-delete-value: 0
          configuration:
            log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    e.RabbitConstants 基础常量配置
        public interface RabbitConstants {

            interface Canal {
                String QUEUE = "canal-queue";
                String EXCHANGE = "canal-exchange";
                String ROUTING = "canal-routing-key";
            }

            interface EventType {
                String INSERT = "INSERT";
                String UPDATE = "UPDATE";
                String DELETE = "DELETE";
            }

        }
    f.CanalMqConfigure MQ队列交换机配置
        @Configuration
        public class CanalMqConfigure {

            @Bean
            public Queue queue() {
                return new Queue(RabbitConstants.Canal.QUEUE, true);
            }

            @Bean
            public DirectExchange directExchange() {
                return new DirectExchange(RabbitConstants.Canal.EXCHANGE, true, false);
            }

            @Bean
            public Binding bindingCanal() {
                return BindingBuilder.bind(queue())
                        .to(directExchange())
                        .with(RabbitConstants.Canal.ROUTING);
            }
        }
    g.CanalConsumer 消费者
        package com.neo.core.canal;

        import com.neo.core.constant.RabbitConstants;
        import lombok.extern.slf4j.Slf4j;
        import org.springframework.amqp.rabbit.annotation.RabbitHandler;
        import org.springframework.amqp.rabbit.annotation.RabbitListener;
        import org.springframework.stereotype.Component;

        import java.util.List;
        import java.util.Map;

        @Slf4j
        @Component
        @RabbitListener(queues = RabbitConstants.Canal.QUEUE)
        public class CanalConsumer {
            @RabbitHandler
            public void execute(Map<String, Object> msg) {
                log.info("canal消息监听事件触发,消息内容:{}", msg);

                boolean isDdl = (boolean) msg.get("isDdl");

                if (isDdl) {
                    return;
                }

                String database = (String) msg.get("database");
                String table = (String) msg.get("table");
                String type = (String) msg.get("type");
                List<?> data = (List<?>) msg.get("data");

                log.info("database:{}.table:{}", database, table);

                if (RabbitConstants.EventType.INSERT.equalsIgnoreCase(type)) {
                    System.out.println("INSERT");
                } else if (RabbitConstants.EventType.UPDATE.equalsIgnoreCase(type)) {
                    System.out.println("UPDATE");
                } else if (RabbitConstants.EventType.DELETE.equalsIgnoreCase(type)) {
                    System.out.println("DELETE");
                } else {
                    // 其他事件
                }
            }
        }

6 方式2:通过deploy.sh自定义脚本启动项目

00.命令
    deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}

01.自由风格
    [root@bigdata02 ~]# cd /data/harbor_docker/
    [root@bigdata02 harbor_docker]# vi deploy.sh
    -------------------------------------------------------------------------------------------------
    harbor_url=$1
    harbor_project_name=$2
    project_name=$3
    tag=$4
    port=$5

    imageName=$harbor_url/$harbor_project_name/$project_name:$tag

    containerId=`docker ps -a | grep ${project_name} | awk '{print $1}'`
    if [ "$containerId" != "" ] ; then
        docker stop $containerId
        docker rm $containerId
        echo "Delete Container Success"
    fi

    imageId=`docker images | grep ${project_name} | awk '{print $3}'`

    if [ "$imageId" != "" ] ; then
        docker rmi -f $imageId
        echo "Delete Image Success"
    fi

    docker login -u DevOps -p P@ssw0rd $harbor_url

    docker pull $imageName

    docker run -d -p $port:$port --name $project_name $imageName

    echo "Start Container Success"
    echo $project_name

02.流水线风格
    // 所有的脚本命令都放在pipeline中
    pipeline {

      // 指定任务在哪个集群节点中执行
      agent any

      // 声明全局变量
      environment {
        harborUser = 'admin'
        harborPasswd = 'Harbor12345'
        harborAddress = '192.168.2.129:8085'
        harborRepo = 'repo'
      }

      // 存放所有任务的合集
      stages {
        stage('拉取git仓库代码') {
          steps {
            checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.129:8929/troyekk/mytest.git']])
          }
        }

        stage('通过maven构建项目') {
          steps {
            sh '/var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
          }
        }

        stage('通过SonarQube做代码质量检测') {
          steps {
            sh '/var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/'
          }
        }

        stage('通过Docker制作自定义镜像') {
          steps {
           sh '''
           cp ./target/*.jar ./docker/
           docker build -t ${JOB_NAME}:${tag} ./docker/
           '''
          }
        }

        stage('通过自定义镜像推送到Harbor') {
          steps {
            sh '''
            docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
            docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
            docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
            '''
          }
        }

        stage('通过Publish Over SSH通知目标服务器') {
          steps {
            sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
          }
        }
      }
    }

6.1 harbor:自由风格

00.安装
    a.安装包
        tar -zxvf harbor-offline-installer-v2.3.4.tgz -C /usr/local/
    b.配置
        cd /usr/local/harbor
        cp harbor.yml.tmpl harbor.yml
        -----------------------------------------------------------------------------------------------------
        vi harbor.yml

        hostname: 192.168.2.129

        http:
          # port for http, default is 80. If https enabled, this port will redirect to https port
          port: 8085

        #https:
          # https port for harbor, default is 443
          # port: 443
          # The path of cert and key files for nginx
          # certificate: /your/certificate/path
          # private_key: /your/private/key/path

        harbor_admin_password: Harbor12345
    c.启动Harbor
        ./install.sh
    d.访问
        http://127.0.0.1:8085/
        admin
        Harbor12345
    e.设置容器开机自启动
        a.开启
            docker update --restart=always nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log
        b.关闭
            docker update --restart=no nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log
    f.容器
        docker stop  nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log
        docker start nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log

01.介绍
    前面在部署项目时,我们主要采用Jenkins推送jar包到指定服务器,再通过脚本命令让目标服务器对当前jar进行部署,
    这种方式在项目较多时,每个目标服务器都需要将jar包制作成自定义镜像再通过docker进行启动,重复操作比较多,会降低项目部署时间。
    ---------------------------------------------------------------------------------------------------------
    我们可以通过Harbor作为私有的Docker镜像仓库。让Jenkins统一将项目打包并制作成Docker镜像发布到Harbor仓库中,
    只需要通知目标服务,让目标服务统一去Harbor仓库上拉取镜像并在本地部署即可。
    Docker官方提供了Registry镜像仓库,但是Registry的功能相对简陋。
    Harbor是VMware公司提供的一款镜像仓库,提供了权限控制、分布式发布、强大的安全扫描与审查机制等功能

02.Harbor的基本操作
    a.修改配置文件
        vi /etc/docker/daemon.json
        {
            "data-root":"/data/docker",
            "registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
            "insecure-registries" : ["192.168.2.129:8085"]
        }
        -----------------------------------------------------------------------------------------------------
        systemctl daemon-reload                                          --重新加载daemon.json文件
        systemctl restart docker.service                                 --重启docker服务
        docker info                                                      --验证
    b.修改镜像
        [root@bigdata02 harbor]# docker images
        REPOSITORY                      TAG               IMAGE ID       CREATED         SIZE
        mytest                          v5.0.0            0818e45d38be   22 hours ago    833MB
        mytest                          v2.0.0            c3136680a20f   22 hours ago    833MB
        mytest                          v1.0.0            3b0efa72116f   25 hours ago    833MB
        -----------------------------------------------------------------------------------------------------
        [root@bigdata02 harbor]# docker tag 0818e45d38be 192.168.2.129:8085/repo/mytest:v5.0.0
        [root@bigdata02 harbor]# docker images
        REPOSITORY                       TAG               IMAGE ID       CREATED         SIZE
        192.168.2.129:8085/repo/mytest   v5.0.0            0818e45d38be   22 hours ago    833MB
        mytest                           v5.0.0            0818e45d38be   22 hours ago    833MB
        mytest                           v2.0.0            c3136680a20f   22 hours ago    833MB
    c.PUSH镜像到Harbor
        [root@bigdata02 harbor]# docker login -u admin -p Harbor12345 192.168.2.129:8085
        WARNING! Using --password via the CLI is insecure. Use --password-stdin.
        WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
        Configure a credential helper to remove this warning. See
        https://docs.docker.com/engine/reference/commandline/login/#credentials-store
        Login Succeeded
        -----------------------------------------------------------------------------------------------------
        [root@bigdata02 harbor]# docker push 192.168.2.129:8085/repo/mytest:v5.0.0
        The push refers to repository [192.168.2.129:8085/repo/mytest]
        de80d7910b36: Pushed
        50ecdabc71b7: Pushed
        3e9cda2eceec: Pushed
        5f70bf18a086: Pushed
        bb7b60f93aea: Pushed
        0ef3d186e2bd: Pushed
        1e0931f30489: Pushed
        fd97e4a10f39: Pushed
        v5.0.0: digest: sha256:1de4a7c964f041d0a817555b9759aa145a60cc2b272d83de5ff460160656408c size: 2828
    d.从Harbor来PULL镜像
        [root@bigdata02 harbor]# docker pull 192.168.2.129:8085/repo/mytest:v5.0.0
        v5.0.0: Pulling from repo/mytest
        4f4fb700ef54: Already exists
        44180127f7f4: Already exists
        cf743f247f7a: Already exists
        582dc57764f8: Already exists
        d2318f6b7a5a: Already exists
        971a7b8b8320: Already exists
        0d862dd52090: Already exists
        1935c08d3603: Already exists
        Digest: sha256:1de4a7c964f041d0a817555b9759aa145a60cc2b272d83de5ff460160656408c
        Status: Downloaded newer image for 192.168.2.129:8085/repo/mytest:v5.0.0
        192.168.2.129:8085/repo/mytest:v5.0.0
        -----------------------------------------------------------------------------------------------------
        [root@bigdata02 harbor]# docker images
        REPOSITORY                       TAG               IMAGE ID       CREATED         SIZE
        192.168.2.129:8085/repo/mytest   v5.0.0            0818e45d38be   22 hours ago    833MB

03.Jenkins容器内部使用Docker
    a.创建一个脚本(例如set-docker-socket-permissions.sh)并添加以下内容:
        #!/bin/bash

        # Wait for Docker daemon to start (if needed)
        # sleep 5

        # Set the correct owner and permissions for docker.sock
        chown root:root /var/run/docker.sock
        chmod o+rw /var/run/docker.sock
    b.将脚本复制到系统的一个适当位置(例如/usr/local/bin)并添加可执行权限:
        sudo cp set-docker-socket-permissions.sh /usr/local/bin
        sudo chmod +x /usr/local/bin/set-docker-socket-permissions.sh
    c.创建一个systemd服务单元文件(例如set-docker-socket-permissions.service)来在Docker服务启动之后自动运行该脚本,并添加以下内容:
        [Unit]
        Description=Set Docker Socket Permissions After Docker Start
        After=docker.service

        [Service]
        Type=oneshot
        ExecStart=/usr/local/bin/set-docker-socket-permissions.sh

        [Install]
        WantedBy=multi-user.target
    d.将set-docker-socket-permissions.service复制到/etc/systemd/system/目录,并刷新systemd服务列表:
        sudo cp set-docker-socket-permissions.service /etc/systemd/system/
        sudo systemctl daemon-reload
    e.启用并启动该服务:
        sudo systemctl enable set-docker-socket-permissions.service
        sudo systemctl start set-docker-socket-permissions.service
        -----------------------------------------------------------------------------------------------------
        现在,每当Docker服务启动时,set-docker-socket-permissions.sh脚本将被执行,并设置docker.sock的权限和所有者

04.Jenkins容器内部使用Docker
    a.第1步
        [root@bigdata02 ~]# cd /var/run/
        [root@bigdata02 run]# chown root:root /var/run/docker.sock              --将docker.sock设置为root
        [root@bigdata02 run]# ll
        drwx------  8 root root  180 Jul 23 05:15 docker
        -rw-r--r--  1 root root    4 Jul 23 05:14 docker.pid
        srw-rw----  1 root root    0 Jul 23 05:14 docker.sock
        [root@bigdata02 run]# chmod o+rw /var/run/docker.sock                   --修改权限,其他用户也可以使用docker
    b.第2步
        [root@bigdata02 run]# cd /data/jenkins_docker/
        [root@bigdata02 jenkins_docker]# vi docker-compose.yml
        -----------------------------------------------------------------------------------------------------
        version: "3.1"
        services:
          jenkins:
            image: jenkins/jenkins:2.401.2-lts
            container_name: jenkins
            ports:
              - 8080:8080
              - 50000:50000
            volumes:
              - ./data/:/var/jenkins_home/
              - /var/run/docker.sock:/var/run/docker.sock
              - /usr/bin/docker:/usr/bin/docker
              - /etc/docker/daemon.json:/etc/docker/daemon.json
    c.第3步
        docker-compose up -d                                                    --启动
    d.测试
        [root@bigdata02 jenkins_docker]# docker exec -it jenkins bash
        jenkins@d1ba4ac42552:/$ docker version                                  --Jenkins容器内部使用Docker
        Client: Docker Engine - Community
         Version:           24.0.4
         API version:       1.43
         Go version:        go1.20.5
         Git commit:        3713ee1
         Built:             Fri Jul  7 14:54:21 2023
         OS/Arch:           linux/amd64
         Context:           default

05.操作
    a.Jenkins实现制作自定义镜像并推送harbor
        工程mytest -> 配置 -> Build Steps -> 执行 shell -> cp target/*.jar docker/
                                                          docker build -t mytest:$tag docker/
                                                          docker login -u admin -p Harbor12345 192.168.2.129:8085
                                                          docker tag mytest:$tag 192.168.2.129:8085/repo/mytest:$tag
                                                          docker push 192.168.2.129:8085/repo/mytest:$tag

    b.目标服务器准备脚本文件1
        a.脚本
            [root@bigdata02 ~]# cd /data/harbor_docker/
            [root@bigdata02 harbor_docker]# vi deploy.sh
            -------------------------------------------------------------------------------------------------
            harbor_url=$1
            harbor_project_name=$2
            project_name=$3
            tag=$4
            port=$5

            imageName=$harbor_url/$harbor_project_name/$project_name:$tag

            containerId=`docker ps -a | grep ${project_name} | awk '{print $1}'`
            if [ "$containerId" != "" ] ; then
                docker stop $containerId
                docker rm $containerId
                echo "Delete Container Success"
            fi

            imageId=`docker images | grep ${project_name} | awk '{print $3}'`

            if [ "$imageId" != "" ] ; then
                docker rmi -f $imageId
                echo "Delete Image Success"
            fi

            docker login -u DevOps -p P@ssw0rd $harbor_url

            docker pull $imageName

            docker run -d -p $port:$port --name $project_name $imageName

            echo "Start Container Success"
            echo $project_name
        b.运行
            [root@bigdata03 data]# echo $PATH                                                          --查看环境变量
            [root@bigdata03 data]# mv deploy.sh /usr/bin                                               --移至/usr/bin
            [root@bigdata02 harbor_docker]# chmod a+x deploy.sh                                        --权限为可执行
            [root@bigdata02 harbor_docker]# ./deploy.sh 192.168.2.129:8085 repo mytest v6.0.0 8088     --PULL操作
            dd91c4df71eb
            dd91c4df71eb
            Delete Container Success
            WARNING! Using --password via the CLI is insecure. Use --password-stdin.
            Error response from daemon: Get "http://192.168.2.129:8085/v2/": unauthorized: authent                                                                    ication required
            v6.0.0: Pulling from repo/mytest
            4f4fb700ef54: Already exists
            44180127f7f4: Already exists
            cf743f247f7a: Already exists
            582dc57764f8: Already exists
            d2318f6b7a5a: Already exists
            971a7b8b8320: Already exists
            0d862dd52090: Already exists
            dbc5755bcdb5: Pull complete
            Digest: sha256:92730c3e3cbb3a866dfa39ec370d1daaa962ee237005ba1f6e150519b13b19bf
            Status: Downloaded newer image for 192.168.2.129:8085/repo/mytest:v6.0.0
            192.168.2.129:8085/repo/mytest:v6.0.0
            50ae64081cd88e03e4e78e61029b0f053cb693f653204f1840d65f8b2b253d6d
            Start Container Success
            mytest
            [root@bigdata02 harbor_docker]# docker images
            REPOSITORY                       TAG               IMAGE ID       CREATED          SIZE
            192.168.2.129:8085/repo/mytest   v6.0.0            5df1770a2201   21 minutes ago   833MB   --PULL成功
            jenkins/jenkins                  2.401.2-lts       825c3e86c65d   3 weeks ago      471MB
    c.目标服务器准备脚本文件2
        工程mytest -> 配置 -> 构建后操作 -> 参数化构建过程 -> 字符参数 -> 名称:prot
                                                                        默认值:8088
                                                                        描述:容器启动时占用的端口

        工程mytest -> 配置 -> General -> Send build artifacts over SSH -> Name:192.168.2.129
                                                                         Exec command:deploy.sh 192.168.2.129:8085 repo ${JOB_NAME} $tag $port

        工程mytest -> 配置 -> General -> Send build artifacts over SSH -> Name:192.168.2.130
                                                                         Exec command:deploy.sh 192.168.2.129:8085 repo ${JOB_NAME} $tag $port

6.2 jenkinsfile:流水线

00.脚本示例
    // 所有的脚本命令都放在pipeline中
    pipeline {

      // 指定任务在哪个集群节点中执行
      agent any

      // 声明全局变量
      environment {
        key = 'value'
      }

      // 存放所有任务的合集
      stages {
        stage('拉取git仓库代码') {
          steps {
            echo '拉取git仓库代码 - SUCCESS'
          }
        }

        stage('通过maven构建项目') {
          steps {
            echo '通过maven构建项目 - SUCCESS'
          }
        }

        stage('通过SonarQube做代码质量检测') {
          steps {
            echo '通过SonarQube做代码质量检测 - SUCCESS'
          }
        }

        stage('通过Docker制作自定义镜像') {
          steps {
            echo '通过Docker制作自定义镜像 - SUCCESS'
          }
        }

        stage('通过自定义镜像推送到Harbor') {
          steps {
            echo '通过自定义镜像推送到Harbor - SUCCESS'
          }
        }

        stage('通过Publish Over SSH通知目标服务器') {
          steps {
            echo '通过Publish Over SSH通知目标服务器 - SUCCESS'
          }
        }
      }
    }

01.流水线1
    harborUser = 'admin'
    harborPasswd = 'Harbor12345'
    harborAddress = '192.168.2.129:8085'
    harborRepo = 'repo'

    // 拉取git仓库代码
    http://192.168.2.129:8929/troyekk/mytest.git

    // 通过maven构建项目
    /var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests

    // 通过SonarQube做代码质量检测
    /var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/

    // 通过Docker制作自定义镜像
    cp ./target/*.jar ./docker/
    docker build -t ${JOB_NAME}:${tag} ./docker/

    // 通过自定义镜像推送到Harbor
    docker login -u admin -p Harbor12345 192.168.2.129:8085
    docker tag mytest:$tag 192.168.2.129:8085/repo/mytest:$tag
    docker push 192.168.2.129:8085/repo/mytest:$tag

    docker login -u 用户名 -p 密码 harbor地址
    docker tag ${JOB_NAME}:${tag} harbor地址/harbor仓库/${JOB_NAME}:${tag}
    docker push harbor地址/harbor仓库/${JOB_NAME}:${tag}

    docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
    docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
    docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}

    // 通过Publish Over SSH通知目标服务器
    deploy.sh 192.168.2.129:8085 repo mytest v6.0.0 8088

    deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}

02.流水线2
    // 所有的脚本命令都放在pipeline中
    pipeline {

      // 指定任务在哪个集群节点中执行
      agent any

      // 声明全局变量
      environment {
        harborUser = 'admin'
        harborPasswd = 'Harbor12345'
        harborAddress = '192.168.2.129:8085'
        harborRepo = 'repo'
      }

      // 存放所有任务的合集
      stages {
        stage('拉取git仓库代码') {
          steps {
            checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.129:8929/troyekk/mytest.git']])
          }
        }

        stage('通过maven构建项目') {
          steps {
            sh '/var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
          }
        }

        stage('通过SonarQube做代码质量检测') {
          steps {
            sh '/var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/'
          }
        }

        stage('通过Docker制作自定义镜像') {
          steps {
           sh '''
           cp ./target/*.jar ./docker/
           docker build -t ${JOB_NAME}:${tag} ./docker/
           '''
          }
        }

        stage('通过自定义镜像推送到Harbor') {
          steps {
            sh '''
            docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
            docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
            docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
            '''
          }
        }

        stage('通过Publish Over SSH通知目标服务器') {
          steps {
            sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
          }
        }
      }
    }

03.构建后钉钉通知消息
    a.插件
        DingTalk
    b.钉钉创建项目组
        Webhook:https://oapi.dingtalk.com/robot/send?access_token=5a0d9031d33e1a659409d89418b00776c53cb8230c56cdef09f31dc87d48545e

7 方式3:通过kubectl apply -f pipeline.yml启动项目

7.1 kuboard

00.介绍
    Kubernetes 从版本 v1.20 之后,弃用 Docker 这个容器运行时。
    弃用 Docker 这个底层运行时,转而支持符合为 Kubernetes 创建的容器运行接口 Container Runtime Interface (CRI) 的运行时。
    Docker 构建的镜像,将在你的集群的所有运行时中继续工作,一如既往。

01.组件
    Pod
    Container(容器)
    Label(label)(标签)
    Replication Controller(复制控制器)
    Service(enter image description here)(服务)
    Node(节点)
    Kubernetes Master(Kubernetes主节点)

02.容器
    RunC
    Docker
    podman
    Containerted

03.安装Kuboard
    a.检查 centos / hostname
        # 在 master 节点和 worker 节点都要执行
        cat /etc/redhat-release

        # 此处 hostname 的输出将会是该机器在 Kubernetes 集群中的节点名字
        # 不能使用 localhost 作为节点的名字
        hostname

        # 请使用 lscpu 命令,核对 CPU 信息
        # Architecture: x86_64    本安装文档不支持 arm 架构
        # CPU(s):       2         CPU 内核数量不能低于 2
        lscpu
        -----------------------------------------------------------------------------------------------------
        # 修改 hostname
        hostnamectl set-hostname your-new-host-name
        # 查看修改结果
        hostnamectl status
        # 设置 hostname 解析
        echo "127.0.0.1   $(hostname)" >> /etc/hosts
    b.检查网络
        [root@demo-master-a-1 ~]$ ip route show
        default via 172.21.0.1 dev eth0
        169.254.0.0/16 dev eth0 scope link metric 1002
        172.21.0.0/20 dev eth0 proto kernel scope link src 172.21.0.12

        [root@demo-master-a-1 ~]$ ip address
        1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
            link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
            inet 127.0.0.1/8 scope host lo
               valid_lft forever preferred_lft forever
        2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
            link/ether 00:16:3e:12:a4:1b brd ff:ff:ff:ff:ff:ff
            inet 172.17.216.80/20 brd 172.17.223.255 scope global dynamic eth0
               valid_lft 305741654sec preferred_lft 305741654sec
    c.安装docker及kubelet
        # 在 master 节点和 worker 节点都要执行
        # 最后一个参数 1.19.5 用于指定 kubenetes 版本,支持所有 1.19.x 版本的安装
        # 腾讯云 docker hub 镜像
        # export REGISTRY_MIRROR="https://mirror.ccs.tencentyun.com"
        # DaoCloud 镜像
        # export REGISTRY_MIRROR="http://f1361db2.m.daocloud.io"
        # 华为云镜像
        # export REGISTRY_MIRROR="https://05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.com"
        # 阿里云 docker hub 镜像
        export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
        curl -sSL https://kuboard.cn/install-script/v1.19.x/install_kubelet.sh | sh -s 1.19.5
    d.初始化 master 节点
        a.操作
            # 只在 master 节点执行
            # 替换 x.x.x.x 为 master 节点实际 IP(请使用内网 IP)
            # export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
            export MASTER_IP=192.168.2.131
            # 替换 apiserver.demo 为 您想要的 dnsName
            export APISERVER_NAME=apiserver.demo
            # Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
            export POD_SUBNET=10.100.0.1/16
            echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts
            curl -sSL https://kuboard.cn/install-script/v1.19.x/init_master.sh | sh -s 1.19.5
        b.检查 master 初始化结果
            # 只在 master 节点执行

            # 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
            watch kubectl get pod -n kube-system -o wide

            # 查看 master 节点初始化结果
            kubectl get nodes -o wide
    e.初始化 worker节点
        a.在 master 节点上执行
            在 master 节点上执行
            # 只在 master 节点执行
            kubeadm token create --print-join-command
            -------------------------------------------------------------------------------------------------
            可获取kubeadm join 命令及参数,如下所示
            # kubeadm token create 命令的输出
            kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt     --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
        b.针对所有的 worker 节点执行
            # 只在 worker 节点执行
            # 替换 x.x.x.x 为 master 节点的内网 IP
            export MASTER_IP=192.168.2.131
            # 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
            export APISERVER_NAME=apiserver.demo
            echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts

            # 替换为 master 节点上 kubeadm token create 命令的输出
            kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt     --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
        c.检查初始化结果,在 master 节点上执行
            # 只在 master 节点执行
            kubectl get nodes -o wide

04.安装 Kuboard v3
    a.安装
        kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
        # 您也可以使用下面的指令,唯一的区别是,该指令使用华为云的镜像仓库替代 docker hub 分发 Kuboard 所需要的镜像
        # kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3-swr.yaml
    b.等待 Kuboard v3 就绪
        [root@node1 ~]# kubectl get pods -n kuboard
        NAME                               READY   STATUS    RESTARTS   AGE
        kuboard-agent-2-65bc84c86c-r7tc4   1/1     Running   2          28s
        kuboard-agent-78d594567-cgfp4      1/1     Running   2          28s
        kuboard-etcd-fh9rp                 1/1     Running   0          67s
        kuboard-etcd-nrtkr                 1/1     Running   0          67s
        kuboard-etcd-ader3                 1/1     Running   0          67s
        kuboard-v3-645bdffbf6-sbdxb        1/1     Running   0          67s
    c.访问 Kuboard
        http://192.168.2.131:30080/
        admin
        Kuboard123
    d.卸载
        kubectl delete -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
        rm -rf /usr/share/kuboard

7.2 podman

01.Podman介绍
    a.OCI标准
        podman是github的Containers项目的一部分,主要的5个组件如下:
        Podman:Pod和容器镜像管理器                                    --代替docker
        Buildah:容器镜像生成器                                        --代替dockerfile的脚本化执行
        Skopeo:容器镜像检查管理器                                     --处理镜像相关的工作,如检查、复制、签名
        Runc:容器运行器和特性构建器,并传递给Podman和Buildah
        Crun:可选运行时,为Rootless容器提供更大的灵活性、控制和安全性
    b.对比1
                      Podman                                          Docker
        架构          无守护进程,可以在启动容器的用户下运行容器        使用守护进程来创建镜像和运行容器
        安全          允许容器使用Rootless特权                        守护进程拥有Root权限
        运行容器      需要另一个工具来管理服务并支持后台容器的运行      使用守护进程管理和运行容器
        构建镜像      需要容器镜像生成器Buildah的辅助                  可以自己构建容器镜像
        理念          采用模块化的方法,依靠专门的工具来完成特定的任务  一个独立的、强大的工具
        使用          兼容大部分Dockert命令,有专门的docker兼容插件    使用自己的命令
    c.对比2
        由于podman比docker少了一层daemon,因此重启的机制也就不同
        podman相比docker也缺失了一些功能,比如不支持windows,不支持docker-compoese编排工具
        -----------------------------------------------------------------------------------------------------
        dockers在实现CRI的时候,它需要一个守护进程,其次需要以root运行,因此这也带来了安全隐患。
        podman不需要守护程序,也不需要root用户运行,从逻辑架构上,比docker更加合理。
        -----------------------------------------------------------------------------------------------------
        在docker的运行体系中,需要多个daemon才能调用到OCI的实现RunC。
        在容器管理的链路中,Docker Engine的实现就是dockerd daemon,它在linux中需要以root运行,
        dockerd调用containerd,containerd调用containerd-shim,然后才能调用runC。
        顾名思义shim起的作用也就是“垫片”,避免父进程退出影响容器的运行。
        -----------------------------------------------------------------------------------------------------
        podman直接调用OCI runtime(runC),通过common作为容器进程的管理工具,
        但不需要dockerd这种以root身份运行的守护进程。
        在podman体系中,有个称之为common的守护进程,其运行路径通常是/usr/libexec/podman/conmon,
        它是各个容器进程的父进程,每个容器各有一个,common的父则通常是1号进程。
        podman中的common其实相当于docker体系中的containerd-shim。

02.Podman设置
    a.安装与卸载
        a.Centos7
            yum -y install podman                                     --Centos7以上
            systemctl start podman
        b.Debian10
            apt update
            apt upgrade
            apt-get -y install podman                                 --Debian 11以上
            podman --version
            podman info
        c.验证
            podman version
            podman info
        d.卸载
            apt-get remove podman
            apt-get purge podman
            apt-get autoremove
    b.设置国内镜像仓库加速器
        a.备份原配置文件
            cp /etc/containers/registries.conf /etc/containers/registries.conf.bak
        b.使用文本编辑器打开配置文件
            vi /etc/containers/registries.conf
        c.删除原有内容,重新编写文件内容后保存,下面xxxxxxxx是个人阿里云ID
            unqualified-search-registries = ["docker.io"]
            [[registry]]
            prefix = "docker.io"
            location = "xxxxxxxx.mirror.aliyuncs.com"
    c.修改SELinux配置文件,永久关闭SELinux
        a.打开/etc/selinux/config
            vi /etc/selinux/config
        b.将 “SELINUX” 参数设置为:”permissive” 或者 “disabled”
            # enforcing - 表示启用 SELinux 安全策略。
            # permissive - 表示启用 SELinux 安全策略,但不强制验证。如果执行第一步可以正常运行,则建议设置此值。
            # disabled - 关闭 SELinux 安全策略,相当于没有安装 SELinux。
            SELINUX=disabled
        c.重启
            reboot
    d.以安装nginx为例
        a.安装
            podman run --rm -p 80:80 --name nginx nginx:alpine
        b.由于Podman没有守护进程,所以自身无法实现开机自启功能
            a.生成服务
                podman generate systemd nginx > nginx.service
            b.将服务移至启动目录
                chmod +x nginx.service
                mv nginx.service /usr/lib/systemd/system/
            c.启动服务
                systemctl daemon-reload
                systemctl enable nginx.service
                systemctl start nginx.service
                systemctl status nginx.service

03.Podman命令
    a.容器
        podman run         #创建并启动容器
        podman start       #启动容器
        podman ps          #查看容器
        podman stop        #终止容器
        podman restart     #重启容器
        podman attach      #进入容器
        podman exec        #进入容器
        podman export      #导出容器
        podman import      #导入容器快照
        podman rm          #删除容器
        podman logs        #查看日志
    b.镜像
        podman search             #检索镜像
        docke pull                #获取镜像
        podman images             #列出镜像
        podman image Is           #列出镜像
        podman rmi                #删除镜像
        podman image rm           #删除镜像
        podman save               #导出镜像
        podman load               #导入镜像
        podmanfile                #定制镜像(三个)
            podman build              #构建镜像
            podman run              #运行镜像
            podmanfile              #常用指令(四个)
                COPY                    #复制文件
                ADD                     #高级复制
                CMD                     #容器启动命令
                ENV                     #环境变量
                EXPOSE                  #暴露端口

7.3 常用操作1

00.对Kubernetes中的5个操作(Namespace操作、Pod操作、Deployment操作、Service操作、Ingress操作),按照它们的大小进行排序如下:
    Ingress操作:Ingress是Kubernetes中用于配置应用程序的入口点的资源对象。它允许将外部流量路由到集群中的Service,并提供负载均衡、SSL终止等功能。相对于其他操作,Ingress的使用场景相对较少,因此在大小上排在最后。
    Namespace操作:Namespace是用于在Kubernetes中隔离资源的一种机制,它可以将不同的资源划分到不同的逻辑组中,提供更好的资源管理和隔离。因为它是对整个集群的资源组织进行调整,所以在大小上属于较大的范畴。
    Service操作:Service是用于暴露Pods或其他Service的网络端点的资源对象。它通过虚拟IP和负载均衡将流量引导到后端的Pod或Service。Service操作相对于Pod和Deployment来说,规模较小,但在网络通信和流量管理方面起着重要的作用。
    Deployment操作:Deployment是Kubernetes中用于管理Pod副本的资源对象,它允许定义期望的副本数量,并负责维护这些副本的状态。Deployment的操作涉及到整个Pod副本的管理,因此在大小上较为重要。
    Pod操作:Pod是Kubernetes中最基本的调度和部署单元,代表一个或多个容器的运行实例。虽然Pod是Kubernetes中最小的资源对象,但在部署和管理应用程序时起着核心作用。
    请注意,这只是一种相对排序,每个操作在不同的场景下都可能具有不同的重要性和影响。实际上,这些操作通常是相互关联的,需要综合考虑来实现一个完整的Kubernetes应用程序部署和管理。

00.一些常用的操作
    StatefulSet操作:StatefulSet是用于管理有状态应用程序的资源对象。与Deployment不同,StatefulSet保证Pod的唯一标识和稳定的网络标识,适用于有状态的应用程序,如数据库。
    ConfigMap和Secret操作:ConfigMap和Secret分别用于存储配置数据和敏感信息,并可以在Pod中作为环境变量或卷挂载来使用。它们允许将配置信息从应用程序代码中分离出来,方便进行配置管理和安全管理。
    PersistentVolume和PersistentVolumeClaim操作:PersistentVolume和PersistentVolumeClaim用于将持久化存储卷与Pod进行绑定。PersistentVolume是集群中的存储资源,而PersistentVolumeClaim是Pod对存储资源的请求。
    DaemonSet操作:DaemonSet是用于在每个节点上运行一个Pod副本的资源对象,确保在集群中的每个节点上都运行了该Pod。适用于运行系统级别的服务或监控代理。
    Job和CronJob操作:Job和CronJob用于运行一次性任务或定时任务。Job保证任务成功完成,而CronJob定期执行任务。
    ReplicaSet操作:ReplicaSet与Deployment类似,也用于管理Pod副本的资源对象,但在Kubernetes的最新版本中,Deployment已经取代了大部分ReplicaSet的使用。
    HorizontalPodAutoscaler操作:HorizontalPodAutoscaler可以自动调整Pod的副本数量,根据CPU利用率或其他自定义指标,确保应用程序的负载均衡和性能优化。

01.Namespace操作
    a.常见命令1
        kubectl create namespace <namespace-name>                                  --创建一个Namespace
        kubectl get namespaces                                                     --列出所有的Namespace
        kubectl delete namespace <namespace-name>                                  --删除一个Namespace
    b.创建一个Namespace
        a.文件
            [root@bigdata04 ~]# vi namespace-test.yml
            -------------------------------------------------------------------------------------------------
            apiVersion: v1
            kind: Namespace
            metadata:
              name: test
        b.使用
            [root@bigdata04 ~]# kubectl apply -f namespace-test.yml                --创建一个Namespace
            namespace/test created
        c.查看
            [root@bigdata04 ~]# kubectl get namespaces                             --列出所有的Namespace
            NAME              STATUS   AGE
            default           Active   4h6m
            kube-node-lease   Active   4h6m
            kube-public       Active   4h6m
            kube-system       Active   4h6m
            kuboard           Active   3h55m
            test              Active   57s

02.Pod操作
    a.常见命令1
        kubectl create -f <pod-definition.yaml>                                    --创建一个Pod
        kubectl get pods -A                                                        --列出所有Pods
        kubectl get pods -n <namespace-name>                                       --获取特定Namespace的所有Pods
        kubectl describe pod <pod-name>                                            --查看Pod的详细信息
        kubectl delete pod <pod-name>                                              --删除一个Pod
    b.常见命令2
        kubectl get pod <pod-name> -o yaml > pod-definition.yaml                   --导出Pod配置
        kubectl exec -it <pod-name> -- <command>                                   --在Pod内执行命令
        kubectl exec -it <pod-name> -- /bin/sh                                     --进入Pod的交互式终端
        kubectl logs <pod-name>                                                    --查看Pod日志
    c.常见命令3
        kubectl label pod <pod-name> <label-key>=<label-value>                     --添加/删除标签
        kubectl label pod <pod-name> <label-key>-
    d.常见命令4
        kubectl scale deployment <deployment-name> --replicas=<replica-count>      --扩展Pod副本数量
    e.常见命令5
        # 复制文件到Pod
        kubectl cp <local-file> <namespace>/<pod-name>:<path-to-file-inside-pod>
        # 从Pod复制文件到本地
        kubectl cp <namespace>/<pod-name>:<path-to-file-inside-pod> <local-file>
    f.常见命令6
        kubectl get pods -o wide                                                   --获取Pod的IP地址
        kubectl describe pod <pod-name>                                            --获取Pod的事件
        kubectl delete pod <pod-name>                                              --临时重启Pod
        kubectl get pods -w                                                        --观察Pod状态变化
        kubectl get pods -l <label-key>=<label-value>                              --按标签选择Pod
        kubectl get pod <pod-name> -o json | jq .metadata.ownerReferences          --查找Pod的控制器
    g.常用命令7
        a.运行nginx
            [root@bigdata04 ~]# kubectl run nginx --image=nginx:latest
            [root@bigdata04 ~]# kubectl run nginx --image=daocloud.io/library/nginx:1.9.1 -n test
            pod/nginx created
        b.获取特定Namespace的所有Pods
            [root@bigdata04 ~]# kubectl get pod -n default
            [root@bigdata04 ~]# kubectl get pod -n test
            NAME    READY   STATUS              RESTARTS   AGE
            nginx   0/1     ContainerCreating   0          24s
        c.删除启动失败的镜像
            [root@bigdata04 ~]# kubectl delete pod nginx -n test
            pod "nginx" deleted
        d.查看Pod的详细信息
            [root@bigdata04 ~]# kubectl describe pod nginx
            [root@bigdata04 ~]# kubectl describe pod nginx -n test
            Name:         nginx
            Namespace:    test
            Priority:     0
            Node:         bigdata05/192.168.2.132
            Start Time:   Tue, 25 Jul 2023 06:51:16 +0800
            Labels:       run=nginx
            Annotations:  cni.projectcalico.org/podIP: 10.100.27.2/32
                          cni.projectcalico.org/podIPs: 10.100.27.2/32
            Status:       Running
            IP:           10.100.27.2
            IPs:
              IP:  10.100.27.2
        e.访问Pod中的nginx
            [root@bigdata04 ~]# curl 10.100.27.2:80
            <!DOCTYPE html>
            <html>
            <head>
            <title>Welcome to nginx!</title>
            <style>
                body {
                    width: 35em;
                    margin: 0 auto;
                    font-family: Tahoma, Verdana, Arial, sans-serif;
                }
            </style>
            </head>
            <body>
            <h1>Welcome to nginx!</h1>
            <p>If you see this page, the nginx web server is successfully installed and
            working. Further configuration is required.</p>

            <p>For online documentation and support please refer to
            <a href="http://nginx.org/">nginx.org</a>.<br/>
            Commercial support is available at
            <a href="http://nginx.com/">nginx.com</a>.</p>

            <p><em>Thank you for using nginx.</em></p>
            </body>
            </html>
        f.进入Pod中nginx
            [root@bigdata04 ~]# kubectl exec -it nginx -n test -- bash
            root@nginx:/# cd /etc/nginx
            root@nginx:/etc/nginx# ls
            conf.d          koi-utf  mime.types  scgi_params   win-utf
            fastcgi_params  koi-win  nginx.conf  uwsgi_params
        g.查看Pod中Nginx的日志
            [root@bigdata04 ~]# kubectl logs -f nginx -n test
            10.100.243.128 - - [24/Jul/2023:23:01:19 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
    h.常用命令8
        a.创建一个Pod
            [root@bigdata04 ~]# vi pod-nignx.yml
            -------------------------------------------------------------------------------------------------
            apiVersion: v1
            kind: Pod
            metadata:
              name: nginx2
              namespace: test
            spec:
              containers:
              - image: daocloud.io/library/nginx:1.9.1
                name: nginx2
        b.使用
            [root@bigdata04 ~]# kubectl apply -f pod-nignx.yml                     --创建一个Pod
            namespace/test created
        c.获取特定Namespace的所有Pods
            [root@bigdata04 ~]# kubectl get pod -n test
            NAME     READY   STATUS    RESTARTS   AGE
            nginx    1/1     Running   0          26m
            nginx2   1/1     Running   0          71s
    g.常用命令9
        a.Pod运行多容器
            [root@bigdata04 ~]# vi pod-nginx-tomact.yml
            -------------------------------------------------------------------------------------------------
            apiVersion: v1
            kind: Pod
            metadata:
              name: nginx-tomcat
              namespace: test
            spec:
              containers:
              - image: daocloud.io/library/nginx:1.9.1
                name: nginx
              - image: daocloud.io/library/tomcat:8.0.45
                name: tomcat
        b.使用
            [root@bigdata04 ~]# kubectl apply -f pod-nginx-tomact.yml              --创建一个Pod
            pod/nginx-tomcat created
        c.获取特定Namespace的所有Pods
            [root@bigdata04 ~]# kubectl get pod -n test
            NAME           READY   STATUS              RESTARTS   AGE
            nginx-tomcat   0/2     ContainerCreating   0          56s
        d.查看Pod的详细信息
            [root@bigdata04 ~]# kubectl describe pod nginx-tomcat -n test
            Name:         nginx-tomcat
            Namespace:    test
            Priority:     0
            Node:         bigdata05/192.168.2.132
            Start Time:   Tue, 25 Jul 2023 07:27:51 +0800
            Labels:       <none>
            Annotations:  cni.projectcalico.org/podIP: 10.100.27.4/32
                          cni.projectcalico.org/podIPs: 10.100.27.4/32
            Status:       Running
            IP:           10.100.27.4
            IPs:
              IP:  10.100.27.4
        e.访问Pod中的nginx、tomcat
            [root@bigdata04 ~]# curl 10.100.27.4:80
            [root@bigdata04 ~]# curl 10.100.27.4:8080

03.Deployment操作
    a.常见命令1
        kubectl create -f <deployment-definition.yaml>                             --创建一个Deployment
        kubectl get deployments                                                    --列出所有Deployments
        kubectl get deployments -n <namespace-name>                                --获取特定Namespace的所有Deployments
        kubectl describe deployment <deployment-name>                              --查看Deployment的详细信息
        kubectl scale deployment <deployment-name> --replicas=<replica-count>      --扩展或缩减Deployment的副本数量
        kubectl delete deployment <deployment-name>                                --删除一个Deployment
    b.常见命令2
        a.创建
            [root@bigdata04 ~]# kubectl create deployment deploy-nginx -n test --image=daocloud.io/library/nginx:1.9.1
            deployment.apps/deploy-nginx created
        b.查看
            [root@bigdata04 ~]# kubectl get pod -n test                            --查看pod
            NAME                           READY   STATUS    RESTARTS   AGE
            deploy-nginx-9b8d5cd59-nd6kp   1/1     Running   0          50s
            nginx-tomcat                   2/2     Running   0          19m
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get deployments -n test                    --查看deployments
            NAME           READY   UP-TO-DATE   AVAILABLE   AGE
            deploy-nginx   1/1     1            1           98s
        c.删除
            [root@bigdata04 ~]# kubectl delete pod nginx-tomcat -n test            --删除pod
            -----------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl delete deployment deploy-nginx -n test     --删除deployments
            deployment.apps "deploy-nginx" deleted
    c.工作负载
        a.文件
            [root@bigdata04 ~]# vi deployment-nginx.yml
            -------------------------------------------------------------------------------------------------
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              namespace: test
              name: nginx-deployment
              labels:
                app: nginx
            spec:
              replicas: 3
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.14.2
                    ports:
                    - containerPort: 80
        b.使用
            [root@bigdata04 ~]# kubectl apply -f deployment-nginx.yml                  --创建一个deployment
            deployment.apps/nginx-deployment created
        c.查看
            [root@bigdata04 ~]# kubectl get pod -n test                                --查看pod
            NAME                                READY   STATUS              RESTARTS   AGE
            nginx-deployment-66b6c48dd5-jszqq   0/1     ContainerCreating   0          76s
            nginx-deployment-66b6c48dd5-kkhkm   0/1     ContainerCreating   0          76s
            nginx-deployment-66b6c48dd5-vksrx   1/1     Running             0          76s
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get deployments -n test                        --查看deployments
            NAME               READY   UP-TO-DATE   AVAILABLE   AGE
            nginx-deployment   0/3     3            0           55s

04.Service操作1
    a.常见命令1
        kubectl create -f <service-definition.yaml>                                    --创建一个Service
        kubectl get services                                                           --列出所有Services
        kubectl get services -n <namespace-name>                                       --获取特定Namespace的所有Services
        kubectl describe service <service-name>                                        --查看Service的详细信息
        kubectl delete service <service-name>                                          --删除一个Service
    b.实现2个Deployment暴露1个Service
        a.port代表Service,target-port代表nginx
            [root@bigdata04 ~]# kubectl expose deployment nginx-deployment -n test --port=8888 --target-port=80
        b.查看
            [root@bigdata04 ~]# kubectl get namespaces                                 --查看namespace
            NAME              STATUS   AGE
            default           Active   16h
            kube-node-lease   Active   16h
            kube-public       Active   16h
            kube-system       Active   16h
            kuboard           Active   16h
            test              Active   12h
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get service -n test                            --查看service
            NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
            kubernetes         ClusterIP   10.96.0.1      <none>        443/TCP   16h
            nginx-deployment   ClusterIP   10.96.47.113   <none>        80/TCP    90s
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get deployments -n test                        --查看deployments
            NAME               READY   UP-TO-DATE   AVAILABLE   AGE
            nginx-deployment   0/3     3            0           55s
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get pod -n test                                --查看pod
            NAME                                READY   STATUS              RESTARTS   AGE
            nginx-deployment-66b6c48dd5-jszqq   0/1     ContainerCreating   0          76s
            nginx-deployment-66b6c48dd5-kkhkm   0/1     ContainerCreating   0          76s
            nginx-deployment-66b6c48dd5-vksrx   1/1     Running             0          76s
        c.负载均衡
            [root@bigdata04 ~]# curl 10.96.47.113
    c.实现2个Deployment暴露1个Service
        a.port代表Service,target-port代表nginx,type=NodePort表示对外暴露端口
            [root@bigdata04 ~]# kubectl expose deployment nginx-deployment -n test --port=8888 --target-port=80 --type=NodePort
        b.查看
            [root@bigdata04 ~]# kubectl get namespaces                                 --查看namespace
            NAME              STATUS   AGE
            default           Active   16h
            kube-node-lease   Active   16h
            kube-public       Active   16h
            kube-system       Active   16h
            kuboard           Active   16h
            test              Active   12h
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get service -n test                            --查看service
            NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
            nginx-deployment   NodePort    10.96.67.193   <none>        8888:31188/TCP   24s
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get deployments -n test                        --查看deployments
            NAME               READY   UP-TO-DATE   AVAILABLE   AGE
            nginx-deployment   0/3     3            0           55s
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get pod -n test                                --查看pod
            NAME                                READY   STATUS              RESTARTS   AGE
            nginx-deployment-66b6c48dd5-jszqq   0/1     ContainerCreating   0          76s
            nginx-deployment-66b6c48dd5-kkhkm   0/1     ContainerCreating   0          76s
            nginx-deployment-66b6c48dd5-vksrx   1/1     Running             0          76s
        c.访问
            http://192.168.2.131:31118
            -------------------------------------------------------------------------------------------------
            Welcome to nginx!
            If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
            For online documentation and support please refer to nginx.org.
            Commercial support is available at nginx.com.
            Thank you for using nginx.
    d.总结
        a.示例
            [root@bigdata04 ~]# kubectl get service -n test                            --查看service
            NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
            kubernetes         ClusterIP   10.96.0.1      <none>        443/TCP          16h
            nginx-deployment   NodePort    10.96.67.193   <none>        8888:31188/TCP   24s
        b.分析
            ClusterIP 代表 集群内部通信,对内暴露端口
            NodePort  代表 集群外部通信,对外暴露端口

04.Service操作2
    a.文件
        [root@bigdata04 ~]# vi service-nginx.yml
        -------------------------------------------------------------------------------------------------
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          namespace: test
          name: nginx-deployment
          labels:
            app: nginx
        spec:
          replicas: 3
          selector:
            matchLabels:
              app: nginx
          template:
            metadata:
              labels:
                app: nginx
            spec:
              containers:
              - name: nginx
                image: nginx:1.14.2
                ports:
                - containerPort: 80
        ---
        apiVersion: v1
        kind: Service
        metadata:
          namespace: test
          name: nginx-deployment
          labels:
            app: nginx-deployment
        spec:
          selector:
            app: nginx
          ports:
            - port: 8888
              targetPort: 80
          type: NodePort
    b.使用
        [root@bigdata04 ~]# kubectl apply -f service-nginx.yml                         --创建一个Service
        deployment.apps/nginx-deployment created
    c.查看
        [root@bigdata04 ~]# kubectl get namespaces                                     --查看namespace
        NAME              STATUS   AGE
        default           Active   16h
        kube-node-lease   Active   16h
        kube-public       Active   16h
        kube-system       Active   16h
        kuboard           Active   16h
        test              Active   12h
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get service -n test                                --查看service
        NAME               TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
        nginx-deployment   NodePort   10.96.38.189   <none>        8888:32151/TCP   3m18s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get deployments -n test                            --查看deployments
        NAME               READY   UP-TO-DATE   AVAILABLE   AGE
        nginx-deployment   0/3     3            0           55s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get pod -n test                                    --查看pod
        NAME                                READY   STATUS    RESTARTS   AGE
        nginx-deployment-66b6c48dd5-t7wgl   1/1     Running   0          4m23s
        nginx-deployment-66b6c48dd5-tggf8   1/1     Running   0          4m23s
        nginx-deployment-66b6c48dd5-ztvlr   1/1     Running   0          4m23s
    c.删除
        kubectl delete pod nginx-deployment-66b6c48dd5-t7wgl -n test
        kubectl delete deployment nginx-deployment -n test
        kubectl delete services nginx-deployment -n test

05.Ingress操作
    a.常见命令1
        kubectl create -f <ingress-definition.yaml>                                    --创建一个Ingress
        kubectl get ingresses                                                          --列出所有Ingresses
        kubectl get ingresses -n <namespace-name>                                      --获取特定Namespace的所有Ingresses
        kubectl describe ingress <ingress-name>                                        --查看Ingress的详细信息
        kubectl delete ingress <ingress-name>                                          --删除一个Ingress
    b.常用命令2
        a.文件
            [root@bigdata04 ~]# vi ingress-nginx.yml
            -------------------------------------------------------------------------------------------------
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              namespace: test
              name: nginx-deployment
              labels:
                app: nginx
            spec:
              replicas: 3
              selector:
                matchLabels:
                  app: nginx
              template:
                metadata:
                  labels:
                    app: nginx
                spec:
                  containers:
                  - name: nginx
                    image: nginx:1.14.2
                    ports:
                    - containerPort: 80
            ---
            apiVersion: v1
            kind: Service
            metadata:
              namespace: test
              name: nginx-deployment
              labels:
                app: nginx-deployment
            spec:
              selector:
                app: nginx
              ports:
                - port: 8888
                  targetPort: 80
              type: NodePort
            ---
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
              namespace: test
              name: nginx-ingress
            spec:
              ingressClassName: ingress
              rules:
                - host: myslayers.nginx.com
                  http:
                    paths:
                      - path: /
                        pathType: Prefix
                        backend:
                          service:
                            name: nginx-deployment
                            port:
                              number: 8888
        b.使用
            [root@bigdata04 ~]# kubectl apply -f ingress-nginx.yml                     --创建一个ingress
            deployment.apps/nginx-deployment created
        c.查看
            [root@bigdata04 ~]# kubectl get namespaces                                 --查看namespace
            NAME              STATUS   AGE
            default           Active   16h
            kube-node-lease   Active   16h
            kube-public       Active   16h
            kube-system       Active   16h
            kuboard           Active   16h
            test              Active   12h
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 k8s]# kubectl get ingresses -n test                        --查看ingresses
            NAME            CLASS     HOSTS                 ADDRESS         PORTS   AGE
            nginx-ingress   ingress   myslayers.nginx.com   192.168.2.132   80      107s
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get service -n test                            --查看service
            NAME               TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
            nginx-deployment   NodePort   10.96.38.189   <none>        8888:32151/TCP   25m
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get deployments -n test                        --查看deployments
            NAME               READY   UP-TO-DATE   AVAILABLE   AGE
            nginx-deployment   3/3     3            3           55s
            -------------------------------------------------------------------------------------------------
            [root@bigdata04 ~]# kubectl get pod -n test                                --查看pod
            NAME                                READY   STATUS    RESTARTS   AGE
            nginx-deployment-66b6c48dd5-t7wgl   1/1     Running   0          4m23s
            nginx-deployment-66b6c48dd5-tggf8   1/1     Running   0          4m23s
            nginx-deployment-66b6c48dd5-ztvlr   1/1     Running   0          4m23s

7.4 常用操作2

01.namespace-test.yml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: test

02.pod-nignx.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx2
      namespace: test
    spec:
      containers:
      - image: daocloud.io/library/nginx:1.9.1
        name: nginx2

02.pod-nginx-tomact.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-tomcat
      namespace: test
    spec:
      containers:
      - image: daocloud.io/library/nginx:1.9.1
        name: nginx
      - image: daocloud.io/library/tomcat:8.0.45
        name: tomcat

03.deployment-nginx.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80

04.service-nginx.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      selector:
        app: nginx
      ports:
        - port: 8888
          targetPort: 80
      type: NodePort

05.ingress-nginx.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      selector:
        app: nginx
      ports:
        - port: 8888
          targetPort: 80
      type: NodePort
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      namespace: test
      name: nginx-ingress
    spec:
      ingressClassName: ingress
      rules:
        - host: myslayers.nginx.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: nginx-deployment
                    port:
                      number: 8888

7.5 k8s启动pipeline.yml

01.pipeline.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: test
      name: mytest
      labels:
        app: mytest
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: mytest
      template:
        metadata:
          labels:
            app: mytest
        spec:
          containers:
            - name: mytest
              image: 192.168.2.129:8085/repo/mytest:v1.0.0
              imagePullPolicy: Always
              ports:
                - containerPort: 8088
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: test
      name: mytest
      labels:
        app: mytest
    spec:
      selector:
        app: mytest
      ports:
        - port: 8088
          targetPort: 8088
      type: NodePort
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      namespace: test
      name: mytest
    spec:
      ingressClassName: ingress
      rules:
        - host: myslayers.mytest.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: mytest
                    port:
                      number: 8088

02.使用
    [root@bigdata04 k8s]# kubectl apply -f pipeline.yml
    deployment.apps/mytest created
    service/mytest created
    ingress.networking.k8s.io/mytest created

03.配置harbor私服信息
    a.Kuboard
        名称空间(test) -> 配置中心 -> 密文 -> docker server      http://192.168.2.129:8085/
                                           -> docker username    admin
                                           -> docker password    Harbor12345
    b.配置
        vi /etc/docker/daemon.json
        {
            "data-root":"/data/docker",
            "registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
            "insecure-registries" : ["192.168.2.129:8085"]
        }
        -----------------------------------------------------------------------------------------------------
        systemctl daemon-reload                                          --重新加载daemon.json文件
        systemctl restart docker.service                                 --重启docker服务
        docker info                                                      --验证
    c.测试
        docker login 192.168.2.129:8085/ -u admin -p Harbor12345

04.访问
    a.查看
        [root@bigdata04 ~]# kubectl get namespaces                                 --查看namespace
        NAME              STATUS   AGE
        default           Active   16h
        kube-node-lease   Active   16h
        kube-public       Active   16h
        kube-system       Active   16h
        kuboard           Active   16h
        test              Active   12h
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 k8s]# kubectl get ingresses -n test                        --查看ingresses
        NAME     CLASS     HOSTS                  ADDRESS         PORTS   AGE
        mytest   ingress   myslayers.mytest.com   192.168.2.132   80      3m59s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get service -n test                            --查看service
        NAME     TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
        mytest   NodePort   10.96.187.37   <none>        8088:32150/TCP   6m47s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get deployments -n test                        --查看deployments
        NAME     READY   UP-TO-DATE   AVAILABLE   AGE
        mytest   0/2     2            0           7m3s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get pod -n test                                --查看pod
        NAME                      READY   STATUS             RESTARTS   AGE
        mytest-5bc5884fbf-jhd4r   0/1     InvalidImageName   0          7m32s
        mytest-5bc5884fbf-rvh2j   0/1     InvalidImageName   0          7m32s
    b.访问
        http://bigdata04:32150/test
        http://bigdata05:32150/test
        http://myslayers.mytest.com:32150/test
        ---------------------------------------------------------------------------------------------------------
        [root@bigdata04 k8s]# curl 192.168.2.132:32150/test
        Jenkin ----- v1.0.0
        [root@bigdata04 k8s]# curl 192.168.2.131:32150/test
        Jenkin ----- v1.0.0
        [root@bigdata04 k8s]# curl myslayers.mytest.com:32150/test
        Jenkin ----- v1.0.0

7.6 k8s整合到jenkins启动pipeline.yml

01.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
    a.目标服务器
        jenkins -> Dashboard -> 系统管理 -> 系统配置 -> SSH Servers -> SSH Server Name        192.168.2.131
                                                                   -> Hostname               192.168.2.131
                                                                   -> Username               root
                                                                   -> Use Password           123456
                                                                   -> Remote Directory       /data/mytest_docker/
    b.流水线语法:将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
        sshPublisher:Send build artifacts over SSH -> SSH Server Name:192.168.2.131
                                                   -> Transfer Set Source files:pipeline.yml
    c.Jenkinsfile
        将如下内容

        // 方式一:deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
        //     stage('通过Publish Over SSH通知目标服务器') {
        //       steps {
        //         sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
        //       }
        //     }

        替换为

        // 方式二:
        //       1.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
        //       2.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
            stage('将yml文仵传到k8s-master') {
              steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.131', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
              }
            }

02.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
    a.将Jenkis(192.168.2.129)中的id_rsa.pub,发送给k8s-master(192.168.2.131)中的authorized_keys
        a.SSH免密钥登陆
            a.生成密钥
                ssh-keygen -t rsa
            b.发送私钥(本机)
                ssh-copy-id localhost
            c.发送公钥(其他计算机)
                ssh-copy-id bigdata02
            d.测试免密钥登陆
                ssh bigdata02
        b.Jenkis(192.168.2.129)
            [root@bigdata02 ~]# docker exec -it jenkins bash
            jenkins@d1ba4ac42552:/$ cd ~
            jenkins@d1ba4ac42552:~$ cd .ssh
            jenkins@d1ba4ac42552:~/.ssh$ cat id_rsa.pub
            ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDW0S54Ip2KSEjDc9Vh7PAXcBe4QOIn2m0XQ/pmaPrglNHSCtwIEWdMJrJPqxI5o7nEdL8LCTrCn8neat5u7c7lu2fmZamaEdW0su9tSKw1BDVGhjV5LfVb21W4psK1x21/DQgoZqSKxyKAYMImxzpqSNimUniOtpBst8+V9oAOJzMb7HI/M7Ei+v/1eLNPDQo3ovChvKR5kIbflQVjT96t1eO5tBsYlIDlFP9uh36++bdA5z3DL5URt88i87g1qHINuKXhxGwdsjMuIVCsqd6BWrAbEUczB2quaceiZ5xMo0gAcgQj+4kULzsFROUYqLzIq9DcwzKZv9G5jzg0j/Yl/8qtvG4EE5GXtC4Gy31KxMxtV1snFW5gyPONpPulVlwcBiVEvOjJAeFYd0HNkES4W0MPMgBAY/0kqzWF2PkmXN8IeXSIsA00PZW5kxE7JJM/j9rEcWakkuXg9x31MsERpo1xQ7zVUrl7j/GqGTSkXKCM98imGRPueC5/NIgxnz8= jenkins@d1ba4ac42552
        c.k8s-master(192.168.2.131)
            [root@bigdata04 .ssh]# touch authorized_keys
            [root@bigdata04 .ssh]# vi authorized_keys
            ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDW0S54Ip2KSEjDc9Vh7PAXcBe4QOIn2m0XQ/pmaPrglNHSCtwIEWdMJrJPqxI5o7nEdL8LCTrCn8neat5u7c7lu2fmZamaEdW0su9tSKw1BDVGhjV5LfVb21W4psK1x21/DQgoZqSKxyKAYMImxzpqSNimUniOtpBst8+V9oAOJzMb7HI/M7Ei+v/1eLNPDQo3ovChvKR5kIbflQVjT96t1eO5tBsYlIDlFP9uh36++bdA5z3DL5URt88i87g1qHINuKXhxGwdsjMuIVCsqd6BWrAbEUczB2quaceiZ5xMo0gAcgQj+4kULzsFROUYqLzIq9DcwzKZv9G5jzg0j/Yl/8qtvG4EE5GXtC4Gy31KxMxtV1snFW5gyPONpPulVlwcBiVEvOjJAeFYd0HNkES4W0MPMgBAY/0kqzWF2PkmXN8IeXSIsA00PZW5kxE7JJM/j9rEcWakkuXg9x31MsERpo1xQ7zVUrl7j/GqGTSkXKCM98imGRPueC5/NIgxnz8= jenkins@d1ba4ac42552
            [root@bigdata04 .ssh]#
    b.流水线语法
        sh:Shell Script -> Shell Script -> ssh [email protected] kubectl apply -f pipeline.yml
        sh:Shell Script -> Shell Script -> ssh [email protected] kubectl rollout restart deployment mytest -n test
    c.Jenkinsfile
        将如下内容

        // 方式一:deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
        //     stage('通过Publish Over SSH通知目标服务器') {
        //       steps {
        //         sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
        //       }
        //     }

        替换为
        // 方式二:
        //       1.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
        //       2.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
            stage('将yml文仵传到k8s-master') {
              steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.131', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
              }
            }

            stage('远程执行k8s-master的kubectl命令') {
             steps {
              sh '''
              ssh [email protected] kubectl apply -f /data/mytest_docker/pipeline.yml
              ssh [email protected] kubectl rollout restart deployment mytest -n test
              '''
             }
            }

03.完整的Jenkinsfile
    // 所有的脚本命令都放在pipeline中
    pipeline {

      // 指定任务在哪个集群节点中执行
      agent any

      // 声明全局变量
      environment {
        harborUser = 'admin'
        harborPasswd = 'Harbor12345'
        harborAddress = '192.168.2.129:8085'
        harborRepo = 'repo'
      }

      // 存放所有任务的合集
      stages {
        stage('拉取git仓库代码') {
          steps {
            checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.129:8929/troyekk/mytest.git']])
          }
        }

        stage('通过maven构建项目') {
          steps {
            sh '/var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
          }
        }

        stage('通过SonarQube做代码质量检测') {
          steps {
            sh '/var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/'
          }
        }

        stage('通过Docker制作自定义镜像') {
          steps {
           sh '''
           cp ./target/*.jar ./docker/
           docker build -t ${JOB_NAME}:${tag} ./docker/
           '''
          }
        }

        stage('通过自定义镜像推送到Harbor') {
          steps {
            sh '''
            docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
            docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
            docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
            '''
          }
        }

    // 方式一:deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
    //     stage('通过Publish Over SSH通知目标服务器') {
    //       steps {
    //         sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
    //       }
    //     }

    // 方式二:
    //       1.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
    //       2.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
        stage('将yml文仵传到k8s-master') {
          steps {
            sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.131', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
          }
        }

        stage('远程执行k8s-master的kubectl命令') {
         steps {
          sh '''
          ssh [email protected] kubectl apply -f /data/mytest_docker/pipeline.yml
          ssh [email protected] kubectl rollout restart deployment mytest -n test
          '''
         }
        }
    }

04.完整的pipeline.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: test
      name: mytest
      labels:
        app: mytest
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: mytest
      template:
        metadata:
          labels:
            app: mytest
        spec:
          containers:
            - name: mytest
              image: 192.168.2.129:8085/repo/mytest:v3.0.0
              imagePullPolicy: Always
              ports:
                - containerPort: 8088
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: test
      name: mytest
      labels:
        app: mytest
    spec:
      selector:
        app: mytest
      ports:
        - port: 8088
          targetPort: 8088
      type: NodePort
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      namespace: test
      name: mytest
    spec:
      ingressClassName: ingress
      rules:
        - host: myslayers.mytest.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: mytest
                    port:
                      number: 8088

05.访问
    a.查看
        [root@bigdata04 ~]# kubectl get namespaces                                 --查看namespace
        NAME              STATUS   AGE
        default           Active   16h
        kube-node-lease   Active   16h
        kube-public       Active   16h
        kube-system       Active   16h
        kuboard           Active   16h
        test              Active   12h
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 k8s]# kubectl get ingresses -n test                        --查看ingresses
        NAME     CLASS     HOSTS                  ADDRESS         PORTS   AGE
        mytest   ingress   myslayers.mytest.com   192.168.2.132   80      3m59s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get service -n test                            --查看service
        NAME     TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
        mytest   NodePort   10.96.187.37   <none>        8088:32150/TCP   6m47s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get deployments -n test                        --查看deployments
        NAME     READY   UP-TO-DATE   AVAILABLE   AGE
        mytest   0/2     2            0           7m3s
        -------------------------------------------------------------------------------------------------
        [root@bigdata04 ~]# kubectl get pod -n test                                --查看pod
        NAME                      READY   STATUS             RESTARTS   AGE
        mytest-5bc5884fbf-jhd4r   0/1     InvalidImageName   0          7m32s
        mytest-5bc5884fbf-rvh2j   0/1     InvalidImageName   0          7m32s
    b.访问
        http://bigdata04:32150/test
        http://bigdata05:32150/test
        http://myslayers.mytest.com:32150/test
        ---------------------------------------------------------------------------------------------------------
        [root@bigdata04 k8s]# curl 192.168.2.132:32150/test
        Jenkin ----- v1.0.0
        [root@bigdata04 k8s]# curl 192.168.2.131:32150/test
        Jenkin ----- v1.0.0
        [root@bigdata04 k8s]# curl myslayers.mytest.com:32150/test
        Jenkin ----- v1.0.0