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.说明
        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

00.常用配置
    a.常用1
        Vultr
        RackNerd
        甲骨文,永久
        微软云,1年
        亚马逊,3个月一换
        谷歌云,3个月一换
        谷歌One全家桶:Gmail、Drive、Docs、Sheets、Slides、Calendar、Meet、Chat、Sites、Forms
    b.常用2
        解绑 =/= 停用 =/= 释放 =/= 冻结
        阿里(海外):云服务器(标准ECS)、轻量应用服务器(简化ECS)、COS对象存储
        腾讯(海外):云服务器(标准CVM)、轻量应用服务器(简化ECS)、OSS对象存储
    c.常用3
        dokploy:容器管理+trafiek反向代理
        Heroku:限制(免费账户有550小时/月的限制,30分钟不活动会休眠)、部署方式(Git 推送或 Docker)
        Google App Engine:限制(每天有一定的免费配额)、部署方式(gcloud CLI 或 Maven 插件)
        Oracle Cloud Free Tier:特点(提供两个免费的 VM,永久免费)、部署方式(SSH 或 Oracle Cloud CLI)
        IBM Cloud Foundry:特点(支持多种编程语言和框架)、限制(免费账户有一定的资源限制)
        OpenShift Online:特点(基于Kubernetes,适合容器化应用)、限制(免费版功能受限)、部署方式(Git 或 Docker 镜像)
        AWS Free Tier:特点(提供多种服务的免费额度)、限制(有些服务只在第一年免费)、部署方式(多样,包括 Elastic Beanstalk, EC2 等)
        Render:特点(现代化平台,易于使用)、限制(免费计划有一定的使用限制)、部署方式(Git 或 Docker)
        Railway:特点(快速部署,开发者友好)、限制(免费计划有每月使用时间限制)、部署方式(Git 或 Docker)
    d.阿里云备案
        在阿里云备案必须拥有阿里云中国内地节点服务器
        事实上,不只是云服务器,阿里云很多云产品均支持备案
        网站域名想要在阿里云备案,需要有一台中国大陆地域的云服务器,并且购买时长大于等于3个月

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 devops

00.年度订阅
    a.Lenny's Newsletter
        一年175刀,价值1286.25人民币,送一堆软件年订阅,随便一个单独订阅都回本
        https://www.lennysnewsletter.com/p/an-unbelievable-offer-now-get-one
        -----------------------------------------------------------------------------------------------------
        Cursor:一年的 Pro 计划(价值 240 美元)
        Bolt:一年的 Pro 计划(价值 240 美元)
        Lovable:一年的入门计划(价值 240 美元)
        Replit:一年核心计划(价值 240 美元)
        v0:一年的高级计划(价值 240 美元)
        Granola:为您和您的团队提供一年的商业计划 - 最多 100 个席位(价值 10,000 美元以上)
        Notion:为您和您的团队提供一年的 Plus 计划(外加无限 AI)—最多 10 个席位(价值 2,000 美元以上)
        Linear:一年的商业计划——两个席位(价值 336 美元)
        Superhuman:一年的入门计划(价值 300 美元)
        Perplexity:一年的 Pro 计划(价值 240 美元)
    b.ClawCloud
        ClawCloud 推出了永久免费容器,最高可获取4核心8G内存,推荐区域日本、新加坡。
        不需要信用卡,需要 Github 注册日期大于 180 天,每个月都送 5 美金额度。

01.网站部署
    a.阿里云
        a.配置
            名称:iZ2ze1rjl28spy91pf927wZ
            地域:华北2(北京)
            核心:2核2GB
            带宽:3Mbps
            系统:CentOS 7.9 64位
            公网IP:8.140.194.149
            公网密码:xxxxxxxxx
            创建时间:2026年7月31日 23:59:59
            到期时间:2024年7月31日 18:09:00
            云服务器ECS:应用管理 -> 1panel运维面板社区版
            提示:修改密码可执行命令:1pctl update password
            -------------------------------------------------------------------------------------------------
            国内的带宽大概20块钱一个月1M,
            不过这个200M也不是稳定200M,是共享池,但是最低有10M
        b.重置密码
            https://ecs.console.aliyun.com/ -> 简捷版本 -> 重置前,建议停止实例,采用【离线重置密码】
        c.创建密钥对
            https://ecs.console.aliyun.com/ -> 标准版本 -> 实例 -> 更多操作 -> 绑定密钥对 -> 生成halavah.pem(SSH密钥认证)
        d.更改系统
            https://ecs.console.aliyun.com/ -> 标准版本 -> 实例 -> 更多操作 -> 云盘与镜像:更换操作系统
        e.安装1Panel
            1-65535代表全部端口
            方式1(成功):计算巢
            方式2(失败):1Panel命令,报错:此Linux发行版(centos7)已终止使用,此脚本不再支持。

02.部署情况
    a.管理面板
        a.1Panel
            地址:http://8.140.194.149:28575/6e84b9f9aa
            用户:troyekk
            密码:qwER159263
        b.BaoTa
            地址:http://8.140.194.149:8888/4023615
            用户:troyekk
            密码:qwER159263
    b.数据库
        a.MySQL
            地址:http://8.140.194.149:3306/
            用户:halavah
            密码:xhXDsEhjWyHn4Adh
        b.PostgreSQL
            地址:http://8.140.194.149:5432/
            用户:halavah
            密码:BB6K2pzsRYkBG7fE
        c.Redis
            地址:http://8.140.194.149:6379/
            密码:5WB6GdZnYy5GT3yb
        d.Mongo
            端口:27017
            用户名:mongo_EXnk8b
            用户密码:mongo_AApFMA
    c.常用服务
        a.DDNS-GO
            地址:http://8.140.194.149:9876/
            用户:troyekk
            密码:qwER159263
            支持:阿里云、腾讯云、DnsPod、Cloudflare、华为云、Callback
            支持:百度云、Porkbun、GoDaddy、Namecheap、NameSilo、Vercel
            支持:Dynadot、火山引擎
        b.Frps
            服务端口:7000
            Dashboard端口:7500
            用户名:admin
            密码:admin_MrDsz5
            密钥:token123456
            映射:82、3100、9994
            示例:http://8.140.194.149:82/
    d.常用服务
        a.One API
            地址:http://8.140.194.149:3000/
            用户:troyekk
            密码:qwER159263
        b.new-api
            地址:http://8.140.194.149:3000/
            用户:root
            密码:qwER159263
            用户:troyekk
            密码:qwER159263
            -------------------------------------------------------------------------------------------------
            # 使用 SQLite 的部署命令:
            docker run --name new-api -d --restart always -p 3000:3000 -e TZ=Asia/Shanghai -v /home/ubuntu/data/new-api:/data calciumion/new-api:latest
            # 使用 MySQL 的部署命令,在上面的基础上添加 `-e SQL_DSN="root:123456@tcp(localhost:3306)/oneapi"`,请自行修改数据库连接参数。
            # 例如:
            docker run --name new-api -d --restart always -p 3000:3000 -e SQL_DSN="root:123456@tcp(localhost:3306)/oneapi" -e TZ=Asia/Shanghai -v /home/ubuntu/data/new-api:/data calciumion/new-api:latest
            -------------------------------------------------------------------------------------------------
            最新版Docker镜像:calciumion/new-api:latest
            默认账号root 密码123456
            更新指令:docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR
        c.bitwarden
            地址:http://8.140.194.149:40031/
            用户:troyekk
            密码:qwER159263

1.5 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.6 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.7 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 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】
        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 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://hub-mirror.c.163.com",
                "https://mirror.baidubce.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 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 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.外部访问容器



    b.容器互联

2.5 dockerfile

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

01.Dockerfile:构建镜像的蓝图
    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.构建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.6 compose

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

01.Docker Compose:多容器应用的指挥家
    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 镜像。

02.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

03.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 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.8 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 container

3.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

3.2 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)

3.3 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)

3.4 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;

3.5 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';

3.6 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

3.7 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)

3.8 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)

3.9 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)

3.10 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                                                   --测试

3.11 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

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

4.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

4.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

4.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/

4.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 {
                    // 其他事件
                }
            }
        }

5 方式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)])
          }
        }
      }
    }

5.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

5.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

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

6.1 k8s

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

6.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                  #暴露端口

6.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

6.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

6.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

6.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