Showing preview only (5,193K chars total). Download the full file or copy to clipboard to get everything.
Repository: burningmyself/burningmyself.github.io
Branch: master
Commit: 0ee36298a35f
Files: 177
Total size: 3.6 MB
Directory structure:
gitextract_h3qke_bo/
├── .gitignore
├── CNAME
├── README.md
├── docs/
│ ├── CNAME
│ ├── cloud/
│ │ ├── apprelease.md
│ │ ├── compute.md
│ │ ├── containerlinux.md
│ │ ├── docker/
│ │ │ ├── docker_compose.md
│ │ │ ├── docker_container.md
│ │ │ ├── docker_container_enterprice.md
│ │ │ ├── docker_date.md
│ │ │ ├── docker_devops.md
│ │ │ ├── docker_file.md
│ │ │ ├── docker_image.md
│ │ │ ├── docker_image_fast.md
│ │ │ ├── docker_native.md
│ │ │ ├── docker_network.md
│ │ │ ├── docker_nginx.md
│ │ │ └── docker_swarm.md
│ │ ├── kubernetes/
│ │ │ ├── kubernetes_ack.md
│ │ │ ├── kubernetes_calico.md
│ │ │ ├── kubernetes_cluster.md
│ │ │ ├── kubernetes_cluster_serve.md
│ │ │ ├── kubernetes_configMap_secret.md
│ │ │ ├── kubernetes_core.md
│ │ │ ├── kubernetes_deploy_golang.md
│ │ │ ├── kubernetes_deploy_java.md
│ │ │ ├── kubernetes_deploy_python.md
│ │ │ ├── kubernetes_devops.md
│ │ │ ├── kubernetes_flannel.md
│ │ │ ├── kubernetes_flink.md
│ │ │ ├── kubernetes_gitops.md
│ │ │ ├── kubernetes_harbor.md
│ │ │ ├── kubernetes_hdfs.md
│ │ │ ├── kubernetes_helm.md
│ │ │ ├── kubernetes_helm_prometheus.md
│ │ │ ├── kubernetes_hight.md
│ │ │ ├── kubernetes_hight_bin1.md
│ │ │ ├── kubernetes_hight_bin2.md
│ │ │ ├── kubernetes_hybridnet.md
│ │ │ ├── kubernetes_introduce.md
│ │ │ ├── kubernetes_ipv4_and_ipv6.md
│ │ │ ├── kubernetes_kafka.md
│ │ │ ├── kubernetes_karmada.md
│ │ │ ├── kubernetes_kubeconfig.md
│ │ │ ├── kubernetes_kubesphere.md
│ │ │ ├── kubernetes_kubesphere_devops.md
│ │ │ ├── kubernetes_kurator.md
│ │ │ ├── kubernetes_kustomize.md
│ │ │ ├── kubernetes_logs_collect.md
│ │ │ ├── kubernetes_master.md
│ │ │ ├── kubernetes_nginx_ingress_controller.md
│ │ │ ├── kubernetes_openfass.md
│ │ │ ├── kubernetes_rancher.md
│ │ │ ├── kubernetes_rke.md
│ │ │ ├── kubernetes_rokectmq.md
│ │ │ ├── kubernetes_safety.md
│ │ │ ├── kubernetes_sealos.md
│ │ │ ├── kubernetes_spark.md
│ │ │ ├── kubernetes_storage_ceph.md
│ │ │ ├── kubernetes_storage_volume.md
│ │ │ ├── kubernetes_traefik.md
│ │ │ ├── kubernetes_ui.md
│ │ │ ├── kubernetes_velero.md
│ │ │ ├── kubernetes_way.md
│ │ │ └── kubernetes_zookeeper.md
│ │ ├── kubernetes.md
│ │ ├── native.md
│ │ └── virtual.md
│ ├── dart/
│ │ └── syntax.md
│ ├── docker/
│ │ ├── docker-compose.md
│ │ ├── docker-jenkins.md
│ │ ├── docker-phabricator.md
│ │ ├── docker.md
│ │ └── docker_core.md
│ ├── emotion/
│ │ ├── emotion.md
│ │ ├── eq.md
│ │ ├── lifetime.md
│ │ ├── livefail.md
│ │ ├── lookbook.md
│ │ ├── losecome.md
│ │ ├── onepath.md
│ │ ├── selfdiscipline.md
│ │ ├── threeheart.md
│ │ ├── twopath.md
│ │ └── workheard.md
│ ├── exp/
│ │ ├── ai.md
│ │ ├── cl.md
│ │ ├── code-principle.md
│ │ ├── cto.md
│ │ ├── devops.md
│ │ ├── four_deep_learning.md
│ │ ├── learnweetout.md
│ │ ├── micro-service.md
│ │ ├── pt.md
│ │ ├── raft-gossip.md
│ │ ├── techbig.md
│ │ └── tl.md
│ ├── framework/
│ │ ├── agility.md
│ │ ├── algorithm-ten.md
│ │ ├── data_middle.md
│ │ ├── fgb.md
│ │ ├── fwork.md
│ │ └── split.md
│ ├── go/
│ │ └── go_base.md
│ ├── index.md
│ ├── java/
│ │ ├── bio-nio.md
│ │ ├── feature.md
│ │ ├── java-simple.md
│ │ ├── java-string.md
│ │ ├── java-utils.md
│ │ ├── java-validator.md
│ │ ├── javavm.md
│ │ ├── load-class.md
│ │ ├── orm.md
│ │ ├── rocketmq/
│ │ │ └── rmq-1.md
│ │ ├── spring-cloud.md
│ │ ├── springAnnotation.md
│ │ └── springdesign.md
│ ├── js/
│ │ ├── baidu-tongji.js
│ │ ├── extra.js
│ │ └── google.js
│ ├── kubernetes/
│ │ ├── k8s_controller_manager.md
│ │ ├── k8s_etcd.md
│ │ ├── k8s_fw_rule_and_object_design.md
│ │ └── k8s_kube_APIServer.md
│ ├── linux/
│ │ ├── linux.md
│ │ ├── often.md
│ │ └── ope.md
│ ├── micro/
│ │ ├── ddd.md
│ │ ├── design.md
│ │ ├── distrimsg.md
│ │ ├── fbs-lock.md
│ │ ├── kafka.md
│ │ ├── redis_cluster.md
│ │ └── spring-cloud-micro.md
│ ├── net/
│ │ ├── c_core_safety.md
│ │ ├── c_core_study_route.md
│ │ ├── c_docker.md
│ │ ├── c_sharp.md
│ │ └── c_sqlserver_nginx.md
│ ├── php/
│ │ └── kj.md
│ ├── python/
│ │ ├── fabric.md
│ │ ├── feature.md
│ │ ├── str_joint.md
│ │ └── syntax_rule.md
│ ├── sql/
│ │ ├── data_split.md
│ │ ├── mybatis.md
│ │ ├── mysql_backups.md
│ │ ├── mysql_index.md
│ │ ├── mysql_log.md
│ │ ├── mysql_pxc.md
│ │ ├── mysql_use.md
│ │ ├── mysql_yh.md
│ │ ├── mysql_yh17.md
│ │ └── sql_server_master.md
│ ├── tool/
│ │ ├── cat-monitoring.md
│ │ ├── cicd.md
│ │ ├── git.md
│ │ ├── gitbook.md
│ │ ├── gitcmr.md
│ │ ├── gitflow.md
│ │ ├── gitquestion.md
│ │ ├── gitstudy.md
│ │ ├── gitusual.md
│ │ ├── markdown.md
│ │ ├── minio.md
│ │ └── mkdocs.md
│ └── web/
│ ├── ali_js_style.md
│ ├── es6.md
│ ├── javascript.md
│ ├── js_tool_method.md
│ ├── node.js.md
│ ├── react.md
│ ├── react_interview.md
│ └── vue_cp_react.md
└── mkdocs.yml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
/site
/.obsidian
/docs/csdn.md
================================================
FILE: CNAME
================================================
burningmyself.cn
================================================
FILE: README.md
================================================
# 个人博客
---
本仓库下存放个人博客的源文件。持续更新,欢迎 star。
如果大家觉得那里写的不合适的可以给我提 Issue
[Github](https://github.com/burningmyself)
[Gitee](https://gitee.com/burningmyself)





## 捐赠
如果你觉得这写文章能帮助到了你,你可以帮作者买一杯果汁表示鼓励

[Paypal Me](https://paypal.me/yangfubing)
## 目录
* [介绍](docs/index.md)
* [README.md](README.md)
* [Docker]
* [Docker介绍使用](docs/docker/docker.md)
* [Docker 核心技术](docs/docker/docker_core.md)
* [docker和docker-compose配置常用环境](docs/docker/docker-compose.md)
* [Docker部署Jenkins](docs/docker/docker-jenkins.md)
* [Docker部署Phabricator](docs/docker/docker-phabricator.md)
* [K8s]
* [Kubernetes架构原则和对象设计](docs/kubernetes/k8s_fw_rule_and_object_design.md)
* [Kubernetes控制平面组件etcd](docs/kubernetes/k8s_etcd.md)
* [深入理解Kube-APIServer](docs/kubernetes/k8s_kube_APIServer.md)
* [kubernetes控制平面组件](docs/kubernetes/k8s_controller_manager.md)
* [经验]
* [集群和负载均衡](docs/exp/cl.md)
* [DevOps是什么](docs/exp/devops.md)
* [微服务架构技术栈选型手册](docs/exp/micro-service.md)
* [Raft算法和Gossip协议](docs/exp/raft-gossip.md)
* [人工智能](docs/exp/ai.md)
* [代码原则](docs/exp/code-principle.md)
* [如何成为技术大牛](docs/exp/techbig.md)
* [程序员如何技术成长](docs/exp/learnweetout.md)
* [产品与技术](docs/exp/pt.md)
* [深度学习框架](docs/exp/four_deep_learning.md)
* [在阿里做了5年技术Leader,我总结出这些套路!](docs/exp/tl.md)
* [CTO 技能图谱](docs/exp/cto.md)
* [Java]
* [Java 新特性](docs/java/feature.md)
* [Java 类加载机制](docs/java/load-class.md)
* [Orm的优缺点](docs/java/orm.md)
* [BIO与NIO](docs/java/bio-nio.md)
* [RocketMq下载与安装](docs/java/rocketmq/rmq-1.md)
* [Spring常用注解](docs/java/springAnnotation.md)
* [Java 虚拟机](docs/java/javavm.md)
* [Spring 常用设计](docs/java/springdesign.md)
* [Spring Cloud](docs/java/spring-cloud.md)
* [Java Simple](docs/java/java-simple.md)
* [Java Validator](docs/java/java-validator.md)
* [Java String](docs/java/java-string.md)
* [Java Utils](docs/java/java-utils.md)
* [Linux]
* [Linux 学习笔记](docs/linux/linux.md)
* [Linux常用命令](docs/linux/often.md)
* [实用的Linux 命令](docs/linux/ope.md)
* [微服务]
* [分布式锁](docs/micro/fbs-lock.md)
* [微服务设计](docs/micro/design.md)
* [分布式系统与消息的投递](docs/micro/distrimsg.md)
* [基于DDD的微服务设计和开发实战](docs/micro/ddd.md)
* [Kafka架构原理](docs/micro/kafka.md)
* [Redis Cluster原理](docs/micro/redis_cluster.md)
* [分布式架构](docs/micro/spring-cloud-micro.md)
* [.NET]
* [C#新特性语法](docs/net/c_sharp.md)
* [.Net Core Docker 部署](docs/net/c_docker.md)
* [Docker容器化部署ASP.NET Core](docs/net/c_sqlserver_nginx.md)
* [让你的ASP.NET Core应用程序更安全](docs/net/c_core_safety.md)
* [ASP.NET Core开发者指南](docs/net/c_core_study_route.md)
* [PHP]
* [框架](docs/php/kj.md)
* [Python]
* [Python新特性](docs/python/feature.md)
* [Python的字符操作](docs/python/str_joint.md)
* [Python语法技巧](docs/python/syntax_rule.md)
* [远程部署神器 Fabric](docs/python/fabric.md)
* [Go]
* [Go基础语法](docs/go/go_base.md)
* [SQL]
* [MySQL 优化指南](docs/sql/mysql_yh.md)
* [MySQL优化](docs/sql/mysql_yh17.md)
* [MySQL 日志](docs/sql/mysql_log.md)
* [MySQL 索引](docs/sql/mysql_index.md)
* [MySQL PXC集群](docs/sql/mysql_pxc.md)
* [MySQL MySQL数据库应用](docs/sql/mysql_use.md)
* [MySql 备份](docs/sql/mysql_backups.md)
* [Sql Server 主从备份](docs/sql/sql_server_master.md)
* [数据库之互联网常用分库分表方案](docs/sql/data_split.md)
* [Mybatis使用心德](docs/sql/mybatis.md)
* [TOOL]
* [Git命令](docs/tool/git.md)
* [Git命令动画展示](docs/tool/gitusual.md)
* [GitBook](docs/tool/gitbook.md)
* [GitFlow](docs/tool/gitflow.md)
* [Git问题处理](docs/tool/gitquestion.md)
* [Git提交日志规范](docs/tool/gitcmr.md)
* [MarkDown](docs/tool/markdown.md)
* [CI/CD](docs/tool/cicd.md)
* [mkdocs简单使用](docs/tool/mkdocs.md)
* [Git的黑魔法](docs/tool/gitstudy.md)
* [MinIO 搭建使用](docs/tool/minio.md)
* [Cat分布式监控](docs/tool.cat-monitoring.md)
* [前端]
* [阿里js样式](docs/web/ali_js_style.md)
* [ES6语法](docs/web/es6.md)
* [Node.js](docs/web/node.js.md)
* [React 开发者指南](docs/web/react.md)
* [Dart语法学习](docs/dart/syntax.md)
* [React 面试](docs/web/react_interview.md)
* [Js 工具函数](docs/web/js_tool_method.md)
* [vue与react比较](docs/web/vue_cp_react.md)
* [JavaScript 基础](docs/web/javascript.md)
* [构架]
* [构架拆分](docs/framework/split.md)
* [分布式、高并发、多线程](docs/framework/fgb.md)
* [如何理解敏捷开发](docs/framework/agility.md)
* [走向架构师必备的技能](docs/framework/fwork.md)
* [数据中台的思考与总结](docs/framework/data_middle.md)
* [必学的 10 大算法](docs/framework/algorithm-ten.md)
* [云架构]
* [云原生](docs/cloud/native.md)
* [虚拟化技术](docs/cloud/virtual.md)
* [云计算](docs/cloud/compute.md)
* [应用部署容器化演进](docs/cloud/apprelease.md)
* [容器技术所涉及Linux内核关键技术](docs/cloud/containerlinux.md)
* [容器管理工具Docker生态架构及部署](docs/cloud/docker/docker_native.md)
* [使用容器运行Nginx应用及Docker命令](docs/cloud/docker/docker_nginx.md)
* [Docker容器镜像](docs/cloud/docker/docker_image.md)
* [Docker容器镜像加速器及本地容器镜像仓库](docs/cloud/docker/docker_image_fast.md)
* [Docker容器化部署企业级应用集群](docs/cloud/docker/docker_container_enterprice.md)
* [Dockerfile精讲及新型容器镜像构建技术](docs/cloud/docker/docker_file.md)
* [Docker容器网络与通信原理深度解析](docs/cloud/docker/docker_network.md)
* [Docker容器数据持久化存储机制](docs/cloud/docker/docker_date.md)
* [Docker容器服务编排利器Docker Compose应用实战](docs/cloud/docker/docker_compose.md)
* [Docker主机集群化方案 Docker Swarm](docs/cloud/docker/docker_swarm.md)
* [基于Docker容器DevOps应用方案 企业业务代码发布系统](docs/cloud/docker/docker_devops.md)
* [轻量级或工业级容器管理工具](docs/cloud/docker/docker_container.md)
* [kubeadm极速部署Kubernetes](docs/cloud/kubernetes.md)
* [kubernetes介绍与集群架构](docs/cloud/kubernetes/kubernetes_introduce.md)
* [Kubernetes集群部署方式说明](docs/cloud/kubernetes/kubernetes_way.md)
* [kubeadm部署单Master节点kubernetes集群](docs/cloud/kubernetes/kubernetes_master.md)
* [kubeadm部署高可用kubernetes集群](docs/cloud/kubernetes/kubernetes_hight.md)
* [使用RKE构建企业生产级Kubernetes集群](docs/cloud/kubernetes/kubernetes_rke.md)
* [Kubernetes高可用集群二进制部署(Runtime Docker)](docs/cloud/kubernetes/kubernetes_hight_bin1.md)
* [Kubernetes高可用集群二进制部署(Runtime Containerd)](docs/cloud/kubernetes/kubernetes_hight_bin2.md)
* [Kubernetes集群UI及主机资源监控](docs/cloud/kubernetes/kubernetes_ui.md)
* [使用sealos部署kubernetes集群并实现集群管理](docs/cloud/kubernetes/kubernetes_sealos.md)
* [kubernetes集群命令语法](docs/cloud/kubernetes/kubernetes_cluster.md)
* [Kubernetes核心概念](docs/cloud/kubernetes/kubernetes_core.md)
* [Kubernetes集群 服务暴露 Nginx Ingress Controller](docs/cloud/kubernetes/kubernetes_nginx_ingress_controller.md)
* [Kubernetes集群 服务暴露 Traefik](docs/cloud/kubernetes/kubernetes_traefik.md)
* [Kubernetes配置与密钥管理 ConfigMap&Secret](docs/cloud/kubernetes/kubernetes_configMap_secret.md)
* [Kubernetes集群使用容器镜像仓库Harbor](docs/cloud/kubernetes/kubernetes_harbor.md)
* [Kubernetes集群安全管理](docs/cloud/kubernetes/kubernetes_safety.md)
* [kubernetes持久化存储卷](docs/cloud/kubernetes/kubernetes_storage_volume.md)
* [kubernetes存储解决方案Ceph](docs/cloud/kubernetes/kubernetes_storage_ceph.md)
* [Kubernetes集群公共服务](docs/cloud/kubernetes/kubernetes_cluster_serve.md)
* [kubernetes集群java项目上云部署](docs/cloud/kubernetes/kubernetes_deploy_java.md)
* [kubernetes集群Python项目上云部署](docs/cloud/kubernetes/kubernetes_deploy_python.md)
* [Kubernetes集群golang项目上云部署](docs/cloud/kubernetes/kubernetes_deploy_golang.md)
* [helm部署prometheus监控系统及应用](docs/cloud/kubernetes/kubernetes_helm_prometheus.md)
* [kubernetes日志收集方案ELK](docs/cloud/kubernetes/kubernetes_logs_collect.md)
* [企业级中间件上云部署zookeeper](docs/cloud/kubernetes/kubernetes_zookeeper.md)
* [kubernetes云原生中间件上云部署kafka](docs/cloud/kubernetes/kubernetes_kafka.md)
* [rocketmq部署控](docs/cloud/kubernetes/kubernetes_rokectmq.md)
* [Kubernetes集群包管理解决方案 Helm](docs/cloud/kubernetes/kubernetes_helm.md)
* [Kubernetes原生配置管理利器 kustomize](docs/cloud/kubernetes/kubernetes_kustomize.md)
* [kubernetes集群网络解决方案 flannel](docs/cloud/kubernetes/kubernetes_flannel.md)
* [kubernetes集群网络解决方案 calico](docs/cloud/kubernetes/kubernetes_calico.md)
* [kubernetes集群 underlay 网络方案 hybridnet](docs/cloud/kubernetes/kubernetes_hybridnet.md)
* [kubernetes版本双栈协议(IPv4&IPv6)集群部署](docs/cloud/kubernetes/kubernetes_ipv4_and_ipv6.md)
* [Rancher容器云管理平台监控](docs/cloud/kubernetes/kubernetes_rancher.md)
* [使用kubeconfig管理多集群方法控](docs/cloud/kubernetes/kubernetes_kubeconfig.md)
* [karmada实现k8s集群联邦](docs/cloud/kubernetes/kubernetes_karamada.md)
* [安装kubesphere使用](docs/cloud/kubernetes/kubernetes_kubesphere.md)
* [阿里云容器服务ACK](docs/cloud/kubernetes/kubernetes_ack.md)
* [基于kubernetes集群构建大中型企业CICD应用平台](docs/cloud/kubernetes/kubernetes_devops.md)
* [基于KubeSphere实现DevOps](docs/cloud/kubernetes/kubernetes_kubesphere_devops.md.md)
* [云原生多云持续交付GitOps](docs/cloud/kubernetes/kubernetes_gitops.md)
* [kubernetes集群备份与恢复管理利器Velero](docs/cloud/kubernetes/kubernetes_velero.md)
* [kubernetes集群舰队管理Kurator](docs/cloud/kubernetes/kubernetes_kurator.md)
* [Serverless之OpenFaaS函数即服务](docs/cloud/kubernetes/kubernetes_openfass.md)
* [Flink基于Kubernetes部署](docs/cloud/kubernetes/kubernetes_flink.md)
* [大数据HDFS分布式文件系统搭建](docs/cloud/kubernetes/kubernetes_hdfs.md)
* [Spark与Kubernetes整合](docs/cloud/kubernetes/kubernetes_spark.md)
* [源监控](docs/cloud/kubernetes/kubernetes_ui.md)
* [情感]
* [情商](docs/emotion/eq.md)
* [工作心得](docs/emotion/workheard.md)
* [看书](docs/emotion/lookbook.md)
* [自律](docs/emotion/selfdiscipline.md)
* [为什么活着失败](docs/emotion/livefail.md)
* [情绪管理](docs/emotion/emotion.md)
* [所有的失去,都会以另一种方式归来](docs/emotion/losecome.md)
* [人生有这三种好心态](docs/emotion/threeheart.md)
* [余生,学会一个人走,不管有没有人陪](docs/emotion/onepath.md)
* [往后余生还很精彩,别被熬夜拖垮了](docs/emotion/twopath.md)
* [心态好的人,一辈子都好](docs/emotion/lifetime.md)
================================================
FILE: docs/CNAME
================================================
burningmyself.cn
================================================
FILE: docs/cloud/apprelease.md
================================================
# 应用(Application)部署容器化演进之路
# 一、应用程序部署痛点
## 1.1 应用程序部署流程
**举例:部署一个JAVA编程语言开发的Web应用,以War包放入Tomcat方式部署。**
- 部署过程如下:
- 服务器配置运行环境:JAVA代码运行环境,例如JDK或JRE
- 服务器上安装Tomcat web中间件,用于运行War包
- 把JAVA Web对应的War包放置于Tomcat对应目录
- 在服务器上启动Tomcat应用
- 可选:涉及数据库(MySQL)或缓存系统(Redis)等都需要逐一部署。
## 1.2 应用程序扩缩容
- 涉及多台服务器部署相同的上述环境
- 痛点:上述环境部署要重新实施一遍,较浪费人力与物力成本
## 1.3 应用程序多环境部署
- 环境:本地测试环境、预发布环境、生产环境
- 在本地测试环境运行没有问题,但在预发布环境中出现了问题,甚至上面2种环境都没有问题,到了生产环境就有问题了。
- 需求:一次成功,可到处运行。
# 二、 计算资源应用演进过程
## 2.1 使用物理服务器痛点

- 从物理服务器自身管理角度
- 物理服务器环境部署人力成本大,特别是在自动化手段不足的情况下,依靠人肉运维的方式解决。
- 当物理服务器出现宕机后,服务器重启时间过长,短则1-2分钟,长则3-5分钟,有背于服务器在线时长达到99.999999999%标准的要求
- 物理服务器在应用程序运行期间硬件出现故障,解决较麻烦
- 物理服务器计算资源不能有效调度使用,无法发挥其充足资源的优势
- 从物理服务器部署应用程序角度
- 物理服务器环境部署浪费时间,没有自动化运维手段,时间是成倍增加的
- 在物理服务器上进行应用程序配置变更,需要重新实施前述步骤
## 2.2 使用虚拟机优点与缺点

### 2.2.1 使用虚拟机优秀点
- 从虚拟机本身管理角度
- 虚拟机较物理服务器轻量,可借助虚拟机模板实现虚拟机快捷生成及应用
- 虚拟机中部署应用与物理服务器一样可控性强,且当虚拟机出现故障时,可直接使用新的虚拟机代替
- 在物理服务器中使用虚拟机可高效使用物理服务器的资源
- 虚拟机与物理服务器一样可达到良好的应用程序运行环境的隔离
- 从在虚拟机中部署应用程序角度
- 在虚拟机中部署应用,容易扩容及缩容实现
- 与物理服务器相比较,当部署应用程序的虚拟机出现宕机时,可以快速启动,时间通常可达秒级,10秒或20秒即可启动,应用程序可以继续提供服务
- 应用程序迁移方便
### 2.2.2 使用虚拟机缺点
- 虚拟机管理软件本身占用物理服务器计算资源较多,例如:VMware Workstation Pro就会占用物理服务器大量资源,所以一般在企业应用中使用KVM虚拟机较多。
- 虚拟机底层硬件消耗物理服务器资源较大,例如:虚拟机操作系统硬盘,会直接占用大量物理服务器硬盘空间
- 相较于容器技术,虚拟机启动时间过长,容器启动可按毫秒级计算
- 虚拟机对物理服务器硬件资源调用添加了调链条,存在浪费时间的现象,所以虚拟机性能弱于物理服务器
- 由于应用程序是直接部署在虚拟机硬盘上,应用程序迁移时,需要连同虚拟机硬盘中的操作系统一同迁移,会导致迁移文件过大,浪费更多的存储空间及时间消耗过长
## 2.3 使用容器的优点与缺点

### 2.3.1 使用容器的优点
- 不需要为容器安装操作系统,可以节约大量时间
- 不需要通过手动的方式在容器中部署应用程序的运行环境,直接部署应用就可以了
- 不需要管理容器网络,以自动调用的方式访问容器中应用提供的服务
- 方便分享与构建应用容器,一次构建,到处运行
- 毫秒级启动
- 容器可直接使用物理服务器硬件资源,物理服务器硬件资源利用率高,性能较好。
### 2.3.2 使用容器的缺点
对于对使用物理服务器、虚拟机已成为习惯的小伙伴来说,容器化可控性不强,最直观的就是对容器管理访问,总想按物理服务器或虚拟机的方式去管理它,其实容器与物理服务器、虚拟机管理方式上有着本质的区别的,最好不要管理。
# 三、 What is a Container?
## 3.1 容器定义

- 虚拟机
- 采用虚拟化技术手段实现物理服务器计算资源打包的方式,为应用程序提供类物理服务器运行环境
- 能够实现应用程序与应用程序之间的隔离
- 使用自动化技术部署应用程序及应用程序迁移较方便
- 可横向扩展
- 容器
- 容器是轻量级物理服务器计算资源的打包方式,即轻量级虚拟机,为应用程序提供类虚拟机运行环境。
- 可在物理服务器中实现高密度部署
- 容器与虚拟机对比
| 对比属性 | 容器(Container) | 虚拟机(VM) |
| ---------------------- | ----------------- | ------------------ |
| 隔离性 | 基于进程隔离 | 提供资源的完全隔离 |
| 启动时间 | 毫秒级或秒级 | 秒级或分钟级 |
| 内核 | 共用宿主机内核 | 使用独立内核 |
| 占用资源 | MB级 | GB级 |
| 系统支持容量(同级别) | 支持上千个容器 | 几十台虚拟机 |
## 3.2 容器功能
- 安装容器管理工具,例如Docker,Containerd等,把应用以容器化的方式运行
- 应用在自己的容器中运行,实现应用程序间隔离
- 应用程序运行的容器可以生成应用程序模板文件,即容器镜像(Image),其不可变,即为云原生代表技术基础设施不可变,且可以在其它的物理服务器中运行。
## 3.3 容器解决了什么问题
- 快速交付和部署应用 (镜像与容器)
- 资源的高效利用和隔离 (在物理机上实现高密度部署)
- 便捷迁移和扩缩容(一次构建,多处运行)
# 四、使用容器步骤
- 安装容器管理工具
- Docker (Docker公司)
- Containerd (2017年docker捐给CNCF云原生计算基金会)
- Pouch (阿里云)
- 搜索/下载容器镜像(Image)
- 使用容器镜像生成容器(容器镜像中的应用程序启动)
- 终端用户(互联网用户或其它应用程序)访问
- 迁移部署(可直接把正在运行的容器打包成新的容器镜像,在其它主机上运行即可。)
================================================
FILE: docs/cloud/compute.md
================================================
# 云计算
# 一、计算资源使用方式
## 1.1 主机资源使用方式
在云计算出现之前,常用的主机资源使用方式有:
- 自己购买物理机
- IDC托管物理机
- IDC租用物理机
- 虚拟机
- 虚拟主机
## 1.2 传统资源管理方式
### 1.2.1 资源方面
- 初期投入/后期维护成本高
- 后期资源闲置浪费
### 1.2.2 人力方面
- 纯手工操作,自动化能力差
- 技术水平限制,资源分配不合理
### 1.2.3 最终效果
- 人力物力成本大
- 资源利用率低
# 二、为什么要用云计算
## 2.1 对提供商而言
- 海量资源动态管理
- 资源灵活调配
- 资源高效率使用
- 技术团队高效使用
## 2.2 对客户而言
- 使用方式多:通过网络访问,服务无处不在
- 投入成本低:按需使用的自助服务,资源可以弹性伸缩
# 三、云计算历史
2006年 Google提出"云计算"概念
2009年 美日韩将其纳入政府议程
2010年 中国将其纳入战略性产业,云计算开始在中国进入迅速发展期
2013年 政府工信部发布基于云计算的政务平台设计指南
2015年 云计算脱离争论不休和宣扬阶段,开始进入落地实施阶段
# 四、云计算定义
## 4.1 从表现形式定义
- 底层由物理硬件构建出一个环境,在这个环境上运行一个操作系统,对终端用户而言,当我们需要用到一个操作系统或应用实现特殊功能时,它只需要向CloudOS提出申请而就能够立即申请获取一个对应的请求环境,这个环境我们可以随时终止,开启等功能。
- 对于用户而言,无需关心它所需要的计算能力从哪里来,有别于传统使用计算机操作系统的状况(看得见、摸得着)
## 4.2 从具体应用定义
- 云计算是一种资源交付的模式,即打包资源给客户使用。
- 它的特点是:基于网络、按需付费、弹性拓展。
- 云服务提供商基于有效的网络通信对所有资源进行统一管理,客户对使用的计算资源按需付费,计算资源使用过程中支持弹性拓展,客户只需投入很少的管理工作就可以高效率的使用计算资源。
# 五、云计算实现方式

## 5.1 传统/私有方式
优点:所有事情都亲自做,可控
缺点:用户成本比较高,要求自身技术水平高
典型软件:传统物理主机
## 5.2 Iaas
IaaS(基础设施即服务)
- 优点:底层硬件到操作系统,都不需要用户操心,省事,可以集中精力做业务项目。
- 缺点:服务商提供的东西,非自己自由定制,所以不可控
- 典型软件:OpenStack,CloudStack
## 5.3 PaaS
PaaS(平台即服务)
Management 是 云计算实现的一种方式,因为包含众多组件,所以也有人称之为Cloud OS
- 优点:我不会运维,我只会开发,底层到运行环境,都不需要用户操心,省事,可以集中精力做应用项目
- 缺点:服务商提供的东西,定制太强,不灵活,只适用于特殊的应用项目,
- 典型软件:Docker、Rocket、Openshift...
## 5.4 SaaS
SaaS(软件即服务)
- 优点:所有东西都由服务商提供,自己只需要花钱使用就行了,对于广大(大中小)企业来说,SaaS是采用先进技术实施信息化的最好途径。例如:企业邮箱服务,财务软件云服务
- 缺点:对客户来说,所有东西都不可控,安全不安全,看情况
# 六、云计算应用分类

## 6.1 公有云
- 普遍性
- 用户按需使用,成本低廉,管理方面。
- 用户的数据保存在公有云的提供商那里,从技术上来讲,数据安全是没有办法保证的,这能从业务层面上来看待。
- 比如:银行不用公有云
- 举例:亚马逊、阿里云、openstack
## 6.2 私有云
- 专用性
- 所有资源都自己提供,安全有保障
- 技术/人力/业务成本高昂,资源利用效率低。
- 举例:vmware、企业云。。。
## 6.3 混合云
- 协调性
- 核心业务用私有云,临时需求/轻量级业务需求使用公有云
- 成本的最优使用效率
# 七、虚拟化与云计算


## 7.1 虚拟化
- 虚拟化是一种技术,它的目的在于提高资源的使用率,并将底层硬件和上层的应用软件进行隔离,使得上层软件及应用计算变得更加弹性可控。最终达到有限成本的高价值。
- 默认情况下,虚拟化技术默认并不对外提供使用抽象的上层应用软件服务组件,一个没有被服务化的虚拟化环境只能被称为"资源池",只有内部管理人员才可以操作。
## 7.2 云计算
云计算是以虚拟化技术为核心技术和基础,面向服务架构(SOA)的一种实现,将虚拟化环境"资源池"隐藏起来,将其上层 应用软件形成丰富的云管理接口,达到所有人自由使用所有资源的一种现象,它是一种资源使用模式的变革。
> 虚拟化是一种技术,云计算是一种计算资源交付模式。
================================================
FILE: docs/cloud/containerlinux.md
================================================
# 容器技术所涉及Linux内核关键技术
# 一、容器技术前世今生
## 1.1 1979年 — chroot
- 容器技术的概念可以追溯到1979年的UNIX chroot。
- 它是一套“UNIX操作系统”系统,旨在将其root目录及其它子目录变更至文件系统内的新位置,且只接受特定进程的访问。
- 这项功能的设计目的在于为每个进程提供一套隔离化磁盘空间。
- 1982年其被添加至BSD当中。
## 1.2 2000年 — FreeBSD Jails
- FreeBSD Jails是由Derrick T. Woolworth于2000年在FreeBSD研发协会中构建而成的早期容器技术之一。
- 这是一套“操作系统”系统,与chroot的定位类似,不过其中包含有其它进程沙箱机制以对文件系统、用户及网络等资源进行隔离。
- 通过这种方式,它能够为每个Jail、定制化软件安装包乃至配置方案等提供一个对应的IP地址。
## 1.3 2001年 — Linux VServer
- Linux VServer属于另一种jail机制,其能够被用于保护计算机系统之上各分区资源的安全(包括文件系统、CPU时间、网络地址以及内存等)。
- 每个分区被称为一套安全背景(security context),而其中的虚拟化系统则被称为一套虚拟私有服务器。
## 1.4 2004年 — Solaris容器
- Solaris容器诞生之时面向x86与SPARC系统架构,其最初亮相于2004年2月的Solaris 10 Build 51 beta当中,随后于2005年正式登陆Solaris 10的完整版本。
- Solaris容器相当于将系统资源控制与由分区提供的边界加以结合。各分区立足于单一操作系统实例之内以完全隔离的虚拟服务器形式运行。
## 1.5 2005年 — OpenVZ
- OpenVZ与Solaris容器非常相似,且使用安装有补丁的Linux内核以实现虚拟化、隔离能力、资源管理以及检查点交付。
- 每套OpenVZ容器拥有一套隔离化文件系统、用户与用户群组、一套进程树、网络、设备以及IPC对象。
## 1.6 2006年 — Process容器
- Process容器于2006年由谷歌公司推出,旨在对一整套进程集合中的资源使用量(包括CPU、内存、磁盘I/O以及网络等等)加以限制、分配与隔离。
- 此后其被更名为Control Groups(即控制组),从而避免其中的“容器”字眼与Linux内核2.6.24中的另一术语出现冲突。这表明了谷歌公司率先重视容器技术的敏锐眼光以及为其做出的突出贡献。
## 1.7 2007年 — Control Groups
Control Groups也就是谷歌实现的cgroups,其于2007年被添加至Linux内核当中。
## 1.8 2008年 — LXC
- LXC指代的是Linux Containers
- 是第一套完整的Linux容器管理实现方案。
- 其功能通过cgroups以及Linux namespaces实现。
- LXC通过liblxc库进行交付,并提供可与Python3、Python2、Lua、Go、Ruby以及Haskell等语言相对接的API。
- 相较于其它容器技术,LXC能够在无需任何额外补丁的前提下运行在原版Linux内核之上。
## 1.9 2011年 — Warden
- Warden由CloudFoundry公司于2011年所建立,其利用LXC作为初始阶段,随后又将其替换为自家实现方案。
- 与LXC不同,Warden并不会与Linux紧密耦合。相反,其能够运行在任意能够提供多种隔离环境方式的操作系统之上。Warden以后台进程方式运行并提供API以实现容器管理。
## 1.10 2013年 — LMCTFY
- Lmctfy代表的是“Let Me Contain That For You(帮你实现容器化)”。它其实属于谷歌容器技术堆栈的开源版本,负责提供Linux应用程序容器。谷歌公司在该项目的起步阶段宣称其能够提供值得信赖的性能表现、高资源利用率、共享资源机制、充裕的发展空间以及趋近于零的额外资源消耗。
- 2013年10月lmctfy的首个版本正式推出,谷歌公司在2015年决定将lmctfy的核心概念与抽象机制转化为libcontainer。在失去了主干之后,如今lmctfy已经失去一切积极的发展势头。
Libcontainer项目最初由Docker公司建立,如今已经被归入开放容器基金会的管辖范畴。
## 1.11 2013年-Docker
- 在2013年Docker刚发布的时候,它是一款基于LXC的开源容器管理引擎。
- 把LXC复杂的容器创建与使用方式简化为Docker自己的一套命令体系。
- 随着Docker的不断发展,它开始有了更为远大的目标,那就是反向定义容器的实现标准,将底层实现都抽象化到Libcontainer的接口。这就意味着,底层容器的实现方式变成了一种可变的方案,无论是使用namespace、cgroups技术抑或是使用systemd等其他方案,只要实现了Libcontainer定义的一组接口,Docker都可以运行。这也为Docker实现全面的跨平台带来了可能。
# 二、NameSpace
## 2.1 NameSpace介绍
- 很多编程语言都包含了命名空间的概念,我们可以认为命名空间是一种封装,封装本身实际上实现了代码的隔离
- 在操作系统中命名空间命名空间提供的是系统资源的隔离,其中系统资源包括了:进程、网络、文件系统......
- 实际上linux系统实现命名空间主要目的之一就是为了实现轻量级虚拟化服务,也就是我们说的容器,在同一个命名空间下的进程可以感知彼此的变化,而对其他命名空间的进程一无所知,这样就可以让容器中的进程产生一个错觉,仿佛它自己置身于一个独立的系统环境当中,以此达到独立和隔离的目的。
## 2.2 Linux系统中NameSpace分类
| 命名空间 | 描述 | 作用 | 备注 |
| :----------: | :--------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: |
| 进程命名空间 | 隔离进程ID | Linux通过命名空间管理进程号,同一个进程,在不同的命名空间进程号不同 | 进程命名空间是一个父子结构,子空间对于父空间可见 |
| 网络命名空间 | 隔离网络设备、协议栈、端口等 | 通过网络命名空间,实现网络隔离 | docker采用虚拟网络设备,将不同命名空间的网络设备连接到一起 |
| IPC命名空间 | 隔离进程间通信 | 进程间交互方法 | PID命名空间和IPC命名空间可以组合起来用,同一个IPC名字空间内的进程可以彼此看见,允许进行交互,不同空间进程无法交互 |
| 挂载命名空间 | 隔离挂载点 | 隔离文件目录 | 进程运行时可以将挂载点与系统分离,使用这个功能时,我们可以达到 chroot 的功能,而在安全性方面比 chroot 更高 |
| UTS命名空间 | 隔离Hostname和NIS域名 | 让容器拥有独立的主机名和域名,从而让容器看起来像个独立的主机 | 目的是独立出主机名和网络信息服务(NIS) |
| 用户命名空间 | 隔离用户和group ID | 每个容器内上的用户跟宿主主机上不在一个命名空间 | 同进程 ID 一样,用户 ID 和组 ID 在命名空间内外是不一样的,并且在不同命名空间内可以存在相同的 ID |
## 2.3 NameSpace应用案例
> 以net namespace为例
- 在 Linux 中,网络命名空间可以被认为是隔离的拥有单独网络栈(网卡、路由转发表、iptables)的环境。网络命名空间经常用来隔离网络设备和服务,只有拥有同样网络命名空间的设备,才能看到彼此。
- 从逻辑上说,网络命名空间是网络栈的副本,拥有自己的网络设备、路由选择表、邻接表、Netfilter表、网络套接字、网络procfs条目、网络sysfs条目和其他网络资源。
- 从系统的角度来看,当通过clone()系统调用创建新进程时,传递标志CLONE_NEWNET将在新进程中创建一个全新的网络命名空间。
- 从用户的角度来看,我们只需使用工具ip(package is iproute2)来创建一个新的持久网络命名空间。

### 2.3.1 创建net命名空间
~~~powershell
创建名称为msb的网络命名空间
# ip netns add msb
~~~
~~~powershell
查看已创建的网络命名空间
# ip netns ls
msb
~~~
### 2.3.2 删除net命名空间
~~~powershell
删除已创建的网络命名空间
# ip netns delete msb
~~~
### 2.3.3 在net命名空间中执行命令
~~~powershell
在网络命名空间中执行bash命令,如果想退出,需要使用exit
# ip netns exec msb bash
~~~
### 2.3.4 在net命令空间中执行查看网络连接(网卡)命令
~~~powershell
在网络命名空间中查看网络命名空间中的网卡信息
# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
~~~
~~~powershell
在Linux主机系统中查看
# ip netns exec msb ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
~~~
### 2.3.5 退出当前的net命名空间
~~~powershell
退出已进入的网络命名空间
# exit
exit
~~~
### 2.3.6 在net命名空间中执行多条命令
~~~powershell
在网络命名空间中查看路由表
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
~~~
~~~powershell
在网络命名空间中查看防火墙规则
# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
~~~
### 2.3.7 创建虚拟网卡
> 同时创建一对虚拟网卡
~~~powershell
创建虚拟网卡对
# ip link add veth0 type veth peer name veth1
~~~
~~~powershell
在物理机上查看
# ip a s
......
10: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether de:44:f8:b7:12:65 brd ff:ff:ff:ff:ff:ff
11: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 46:5e:89:8c:cb:b3 brd ff:ff:ff:ff:ff:ff
~~~
### 2.3.8 迁移虚拟网卡到命名空间中
>这两个网卡还都属于“default”或“global”命名空间,和物理网卡一样。把其中一个网卡转移到命名空间msb中。
~~~powershell
把创建的veth1网卡添加到msb网络命名空间中
# ip link set veth1 netns msb
~~~
~~~powershell
在Linux系统命令行查看网络命名空间中的网络
# ip netns exec msb ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
10: veth1@if11: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether de:44:f8:b7:12:65 brd ff:ff:ff:ff:ff:ff link-netnsid 0
~~~
### 2.3.9 命名空间中迁出虚拟网卡
~~~powershell
在Linux系统命令行把虚拟网卡veth1从网络命名空间删除
# ip netns exec msb ip link delete veth1
~~~
~~~powershell
在Linux系统命令行查看结果
# ip netns exec msb ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
~~~
### 2.3.10 配置虚拟网卡IP地址
~~~powershell
再次创建虚拟网卡,添加到msb网络命名空间,并设置IP地址
# ip link add veth0 type veth peer name veth1
# ip link set veth1 netns msb
# ip netns exec msb ip addr add 192.168.50.2/24 dev veth1
~~~
~~~powershell
在Linux系统命令行查看网络状态
# ip netns exec msb ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: veth1@if13: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether fe:20:ac:a8:13:4c brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.50.2/24 scope global veth1
valid_lft forever preferred_lft forever
~~~
~~~powershell
启动虚拟网卡,veth1与lo全部要启动
# ip netns exec msb ip link set veth1 up
# ip netns exec msb ip link set lo up
~~~
~~~powershell
为物理机veth0添加IP地址
# ip a s
......
15: veth0@if14: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group defau
lt qlen 1000
link/ether 2e:b4:40:c8:73:dc brd ff:ff:ff:ff:ff:ff link-netnsid 0
~~~
~~~powershell
# ip addr add 192.168.50.3/24 dev veth0
# ip a s veth0
15: veth0@if14: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 2e:b4:40:c8:73:dc brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.50.3/24 scope global veth0
valid_lft forever preferred_lft forever
~~~
~~~powershell
# ip link set veth0 up
~~~
~~~powershell
在宿主机上ping msb中的veth1
# ping 192.168.50.2
PING 192.168.50.2 (192.168.50.2) 56(84) bytes of data.
64 bytes from 192.168.50.2: icmp_seq=1 ttl=64 time=0.102 ms
64 bytes from 192.168.50.2: icmp_seq=2 ttl=64 time=0.068 ms
64 bytes from 192.168.50.2: icmp_seq=3 ttl=64 time=0.068 ms
~~~
~~~powershell
在msb中的veth1 ping 宿主机上veth0
# ip netns exec msb ping 192.168.50.3
PING 192.168.50.3 (192.168.50.3) 56(84) bytes of data.
64 bytes from 192.168.50.3: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 192.168.50.3: icmp_seq=2 ttl=64 time=0.031 ms
64 bytes from 192.168.50.3: icmp_seq=3 ttl=64 time=0.029 ms
~~~
~~~powershell
如果需要访问本机的其它网段,可手动添加如下默认路由条目。
# ip netns exec msb ip route add default via 192.168.50.3
~~~
> 关于如何ping通外网主机,可设置路由转发完成。
# 三、CGroups
## 3.1 CGroups介绍
- Control groups(cgroups) 控制组
- linux内核提供的可以限制、记录、隔离进程组所使用的物理资源的机制。为容器而生,没有cgroups就没有今天的容器技术。

## 3.2 CGroups功能
- 资源限制(Resource Limitation):cgroups 可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出 OOM(Out of Memory)。
- 优先级分配(Prioritization):通过分配的 CPU 时间片数量及硬盘 IO 带宽大小,实际上就相当于控制了进程运行的优先级。
- 资源统计(Accounting): cgroups 可以统计系统的资源使用量,如 CPU 使用时长、内存用量等等,这个功能非常适用于计费。
- 进程控制(Control):cgroups 可以对进程组执行挂起、恢复等操作。
## 3.3 CGroups应用案例
### 3.3.1 安装及开启服务
~~~shell
[root@localhost ~]# yum -y install libcgroup
[root@localhost ~]# systemctl start cgconfig.service
[root@localhost ~]# systemctl enable cgconfig.service
~~~
### 3.3.2 限制进程使用CPU
#### 3.3.2.1 查看cpu shares
~~~powershell
查看资源限制子系统
[root@localhost ~]# lssubsys
cpuset
cpu,cpuacct
memory
devices
freezer
net_cls,net_prio
blkio
perf_event
hugetlb
pids
查看子系统配置文件所在位置
[root@localhost ~]# ls /sys/fs/cgroup/
blkio cpuacct cpuset freezer memory net_cls,net_prio perf_event systemd
cpu cpu,cpuacct devices hugetlb net_cls net_prio pids
[root@localhost ~]# ls /sys/fs/cgroup/cpu
cgroup.clone_children cpuacct.stat cpu.cfs_quota_us cpu.stat
cgroup.event_control cpuacct.usage cpu.rt_period_us notify_on_release
cgroup.procs cpuacct.usage_percpu cpu.rt_runtime_us release_agent
cgroup.sane_behavior cpu.cfs_period_us cpu.shares tasks
查看CPU时间分片,用于保证分组所得到的CPU分片总量。
[root@localhost ~]# cat /sys/fs/cgroup/cpu/cpu.shares
1024
~~~
#### 3.3.2.2 使用CPU子系统创建2个group分组
~~~shell
[root@localhost ~]# vim /etc/cgconfig.conf
group lesscpu {
cpu{
cpu.shares=200;
}
}
group morecpu {
cpu{
cpu.shares=800;
}
}
[root@localhost ~]# systemctl restart cgconfig
~~~
准备一个脚本
~~~powershell
#!/bin/bash
a=1
while true
do
a=$[$a+1]
done
~~~
将将要运行的应用程序分配到指定分组(**请使用单CPU机器,三个终端验证**)
~~~shell
终端1# cgexec -g cpu:lesscpu sh /tmp/1.sh
终端2# cgexec -g cpu:morecpu sh /tmp/1.sh
终端3# top
~~~
**PS: 如果主机有多CPU,为了验证效果,可以进行如下操作**
~~~shell
# lscpu
# echo 0 > /sys/devices/system/cpu/cpu0/online
# echo 1 > /sys/devices/system/cpu/cpu1/online
~~~
================================================
FILE: docs/cloud/docker/docker_compose.md
================================================
# Docker容器服务编排利器 Docker Compose应用实战
# 一、使用Docker Compose必要性及定义
用容器运行一个服务,需要使用`docker run`命令。但如果我要运行多个服务呢?
假设我要运行一个web服务,还要运行一个db服务,那么是用一个容器运行,还是用多个容器运行呢?
一个容器运行多个服务会造成镜像的复杂度提高,**docker倾向于一个容器运行一个应用**。
那么复杂的架构就会需要很多的容器,并且需要它们之间有关联(容器之间的依赖和连接)就更复杂了。
这个复杂的问题需要解决,这就涉及到了**==容器编排==**的问题了。
- Compose
- 编排
- 是对多个容器进行启动和管理的方法
- 例如:LNMT,先启动MySQL,再启动Tomcat,最后启动Nginx
- 服务架构的演进
- 单体服务架构
- 分布式服务架构
- 微服务架构
- 超微服务架构
- 容器编排工具
- docker machine
- 在虚拟机中部署docker容器引擎的工具
- docker compose
- 是一个用于定义和运行多容器Docker的应用程序工具
- docker swarm
- 是Docker Host主机批量管理及资源调度管理工具
- mesos+marathon
- mesos 对计算机计算资源进行管理和调度
- marathon 服务发现及负载均衡的功能
- kubernetes
- google开源的容器编排工具
# 二、Docker Compose应用参考资料
- 网址
- https://docs.docker.com/compose/

- yaml格式
- https://yaml.org/
# 三、Docker Compose应用最佳实践步骤
## 3.1 概念
- 工程(project)
- 服务 (Service)
- 容器 (Container)
## 3.2 步骤
1.定义应用的Dockerfile文件,为了anywhere进行构建。
2.使用docker-compose.yaml定义一套服务,这套服务可以一起在一个隔离环境中运行。
3.使用docker-compose up就可以启动整套服务。
# 四、Docker Compose安装




~~~powershell
# wget https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64
~~~
~~~powershell
# mv docker-compose-linux-x86_64 /usr/bin/docker-compose
~~~
~~~powershell
# chmod +x /usr/bin/docker-compose
~~~
~~~powershell
# docker-compose version
Docker Compose version v2.2.3
~~~
# 五、Docker Compose应用案例
> 运行Python语言开发的网站
## 5.1 网站文件准备
~~~powershell
# mkdir flaskproject
[root@localhost ~]# cd flaskproject/
[root@localhost flaskproject]#
~~~
~~~powershell
[root@localhost flaskproject]# vim app.py
[root@localhost flaskproject]# cat app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
~~~
~~~powershell
[root@localhost flaskproject]# vim requirements.txt
[root@localhost flaskproject]# cat requirements.txt
flask
redis
~~~
## 5.2 Dockerfile文件准备
~~~powershell
[root@localhost flaskproject]# vim Dockerfile
[root@localhost flaskproject]# cat Dockerfile
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
~~~
## 5.3 Compose文件准备
~~~powershell
[root@localhost flaskproject]# vim docker-compose.yaml
[root@localhost flaskproject]# cat docker-compose.yaml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
~~~
## 5.4 使用docker-compose up启动容器
~~~powershell
[root@localhost flaskproject]# ls
app.py docker-compose.yaml Dockerfile requirements.txt
~~~
~~~powershell
[root@localhost flaskproject]# docker-compose up
~~~
~~~powershell
输出:
[+] Running 7/7
⠿ redis Pulled 15.8s
⠿ 59bf1c3509f3 Pull complete 2.9s
⠿ 719adce26c52 Pull complete 3.0s
⠿ b8f35e378c31 Pull complete 5.8s
⠿ d034517f789c Pull complete 6.5s
⠿ 3772d4d76753 Pull complete 6.6s
⠿ 211a7f52febb Pull complete 6.8s
Sending build context to Docker daemon 714B
Step 1/9 : FROM python:3.7-alpine
3.7-alpine: Pulling from library/python
59bf1c3509f3: Already exists
07a400e93df3: Already exists
bdabb07397e1: Already exists
cd0af01c7b70: Already exists
d0f18e022200: Already exists
Digest: sha256:5a776e3b5336827faf7a1c3a191b73b5b2eef4cdcfe8b94f59b79cb749a2b5d8
Status: Downloaded newer image for python:3.7-alpine
---> e72b511ad78e
Step 2/9 : WORKDIR /code
---> Running in 2b9d07bef719
Removing intermediate container 2b9d07bef719
---> 7d39e96fadf1
Step 3/9 : ENV FLASK_APP app.py
---> Running in 9bcb28bd632a
Removing intermediate container 9bcb28bd632a
---> 79f656a616d5
Step 4/9 : ENV FLASK_RUN_HOST 0.0.0.0
---> Running in 8470c2dbd6c2
Removing intermediate container 8470c2dbd6c2
---> e212ba688fcd
Step 5/9 : RUN apk add --no-cache gcc musl-dev linux-headers
---> Running in 6e9ca0766bc8
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/x86_64/APKINDEX.tar.gz
(1/13) Installing libgcc (10.3.1_git20211027-r0)
(2/13) Installing libstdc++ (10.3.1_git20211027-r0)
(3/13) Installing binutils (2.37-r3)
(4/13) Installing libgomp (10.3.1_git20211027-r0)
(5/13) Installing libatomic (10.3.1_git20211027-r0)
(6/13) Installing libgphobos (10.3.1_git20211027-r0)
(7/13) Installing gmp (6.2.1-r1)
(8/13) Installing isl22 (0.22-r0)
(9/13) Installing mpfr4 (4.1.0-r0)
(10/13) Installing mpc1 (1.2.1-r0)
(11/13) Installing gcc (10.3.1_git20211027-r0)
(12/13) Installing linux-headers (5.10.41-r0)
(13/13) Installing musl-dev (1.2.2-r7)
Executing busybox-1.34.1-r3.trigger
OK: 143 MiB in 49 packages
Removing intermediate container 6e9ca0766bc8
---> 273d4f04dfbc
Step 6/9 : COPY requirements.txt requirements.txt
---> daf51c54e8ba
Step 7/9 : RUN pip install -r requirements.txt
---> Running in 2aa2d30c5311
Collecting flask
Downloading Flask-2.0.3-py3-none-any.whl (95 kB)
Collecting redis
Downloading redis-4.1.3-py3-none-any.whl (173 kB)
Collecting Jinja2>=3.0
Downloading Jinja2-3.0.3-py3-none-any.whl (133 kB)
Collecting itsdangerous>=2.0
Downloading itsdangerous-2.0.1-py3-none-any.whl (18 kB)
Collecting click>=7.1.2
Downloading click-8.0.3-py3-none-any.whl (97 kB)
Collecting Werkzeug>=2.0
Downloading Werkzeug-2.0.3-py3-none-any.whl (289 kB)
Collecting deprecated>=1.2.3
Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB)
Collecting packaging>=20.4
Downloading packaging-21.3-py3-none-any.whl (40 kB)
Collecting importlib-metadata>=1.0
Downloading importlib_metadata-4.11.1-py3-none-any.whl (17 kB)
Collecting wrapt<2,>=1.10
Downloading wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl (78 kB)
Collecting typing-extensions>=3.6.4
Downloading typing_extensions-4.1.1-py3-none-any.whl (26 kB)
Collecting zipp>=0.5
Downloading zipp-3.7.0-py3-none-any.whl (5.3 kB)
Collecting MarkupSafe>=2.0
Downloading MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl (30 kB)
Collecting pyparsing!=3.0.5,>=2.0.2
Downloading pyparsing-3.0.7-py3-none-any.whl (98 kB)
Installing collected packages: zipp, typing-extensions, wrapt, pyparsing, MarkupSafe, importlib-metadata, Werkzeug, packaging, Jinja2, itsdangerous, deprecated, click, redis, flask
Successfully installed Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.3 click-8.0.3 deprecated-1.2.13 flask-2.0.3 importlib-metadata-4.11.1 itsdangerous-2.0.1 packaging-21.3 pyparsing-3.0.7 redis-4.1.3 typing-extensions-4.1.1 wrapt-1.13.3 zipp-3.7.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.2.4; however, version 22.0.3 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
Removing intermediate container 2aa2d30c5311
---> dd8f52b132f8
Step 8/9 : COPY . .
---> b36938a26cf5
Step 9/9 : CMD ["flask", "run"]
---> Running in 260cbfa02959
Removing intermediate container 260cbfa02959
---> fa04dfec6ff2
Successfully built fa04dfec6ff2
Successfully tagged flaskproject_web:latest
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 3/3
⠿ Network flaskproject_default Created 0.1s
⠿ Container flaskproject-redis-1 Created 0.1s
⠿ Container flaskproject-web-1 Created 0.1s
Attaching to flaskproject-redis-1, flaskproject-web-1
flaskproject-redis-1 | 1:C 15 Feb 2022 14:14:21.696 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
flaskproject-redis-1 | 1:C 15 Feb 2022 14:14:21.696 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
flaskproject-redis-1 | 1:C 15 Feb 2022 14:14:21.696 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
flaskproject-redis-1 | 1:M 15 Feb 2022 14:14:21.697 * monotonic clock: POSIX clock_gettime
flaskproject-redis-1 | 1:M 15 Feb 2022 14:14:21.698 * Running mode=standalone, port=6379.
flaskproject-redis-1 | 1:M 15 Feb 2022 14:14:21.698 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
flaskproject-redis-1 | 1:M 15 Feb 2022 14:14:21.698 # Server initialized
flaskproject-redis-1 | 1:M 15 Feb 2022 14:14:21.698 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
flaskproject-redis-1 | 1:M 15 Feb 2022 14:14:21.698 * Ready to accept connections
flaskproject-web-1 | * Serving Flask app 'app.py' (lazy loading)
flaskproject-web-1 | * Environment: production
flaskproject-web-1 | WARNING: This is a development server. Do not use it in a production deployment.
flaskproject-web-1 | Use a production WSGI server instead.
flaskproject-web-1 | * Debug mode: off
flaskproject-web-1 | * Running on all addresses.
flaskproject-web-1 | WARNING: This is a development server. Do not use it in a production deployment.
flaskproject-web-1 | * Running on http://172.18.0.2:5000/ (Press CTRL+C to quit)
~~~
## 5.5 访问

================================================
FILE: docs/cloud/docker/docker_container.md
================================================
# 轻量级或工业级容器管理工具 Containerd
# 一、Containerd介绍
## 1.0 前言
- 早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。和原先包含在Docker Engine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容器运行时管理的所有需求。
- containerd并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如Swarm, Kubernetes, Mesos等容器编排系统。
- containerd以Daemon的形式运行在系统上,通过暴露底层的gRPC API,上层系统可以通过这些API管理机器上的容器。
- 每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。
- 对于容器编排服务来说,运行时只需要使用containerd+runC,更加轻量,容易管理。
- 独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。


## 1.1 Containerd前世今生
2013年docker公司在推出docker产品后,由于其对全球技术产生了一定的影响力,Google公司明显感觉到自己公司内部所使用的Brog系统江湖地位受到的威胁,希望Docker公司能够与自己联合打造一款开源的容器运行时作为Docker核心依赖,但Docker公司拒绝了;接着Google公司联合RedHat、IBM等公司说服Docker公司把其容器核心技术libcontainer捐给中立社区(OCI,Open Container Intiative),并更名为runC。
为了进一步遏制Docker在未来技术市场影响力,避免在容器市场上Docker一家独大,Google公司带领导RedHat、IBM等成立了CNCF(Cloud Native Computing Fundation)基金会,即云原生计算基金会。CNCF的目标很明确,既然在容器应用领域无法与Docker相抗衡,那就做Google更有经验的技术市场------大规模容器编排应用场景,Google公司把自己内部使用的Brog系统开源------Kubernetes,也就是我们今天所说的云原生技术生态。
2016年Docker公司推出了Docker Swarm,意在一统Docker生态,让Docker既可以实现容器应用管理,也可以实现大规模容器编排,经过近1年左右时间的市场验证后,发现在容器编排方面无法独立抗衡kubernetes,所以Docker公司于2017年正式宣布原生支持Kubernetes,至此,Docker在大规模容器编排应用市场败下阵来,但是Docker依然不甘心失败,把Docker核心依赖Containerd捐给了CNCF,依此说明Docker依旧是一个PaaS平台。
2020年CNCF基金会宣布Kubernetes 1.20版本将不再仅支持Docker容器管理工具,此事的起因主要也与Docker捐给CNCF基金会的Containerd有关,早期为了实现Kubernetes能够使用Docker实现容器管理,专门在Kubernetes组件中集成一个shim(垫片)技术,用来将Kubernetes容器运行时接口(CRI,Container Runntime Interface)调用翻译成Docker的API,这样就可以很好地使用Docker了,但是随着Kubernetes在全球技术市场的广泛应用,有更多的容器管理工具的出现,它们都想能够借助于Kubernetes被用户所使用,所以就提出标准化容器运行时接口,只要适配了这个接口就可以集成到Kubernetes生态当中,所以Kubernetes取消了对shim的维护,并且由于Containerd技术的成功,可以实现无缝对接Kubernetes,所以接下来Kubernetes容器运行时的主角是Containerd。
## 1.2 Containerd架构
### 1.2.1 架构图
Containerd设计的目的是为了嵌入到Kubernetes中使用,它是一个工业级的容器运行时,不提供给开发人员和终端用户直接使用,这样就避免了与Docker产生竞争,但事实上,Containerd已经实现大多数容器管理功能,例如:容器生命周期管理、容器镜像传输和管理、容器存储与网络管理等。

- Containerd 采用标准的 C/S 架构
- 服务端通过 GRPC 协议提供稳定的 API
- 客户端通过调用服务端的 API 进行高级的操作
-
为了实现解耦,Containerd 将不同的职责划分给不同的组件,每个组件就相当于一个子系统(subsystem)。连接不同子系统的组件被称为模块。
- Containerd 两大子系统为:
- Bundle : 在 Containerd 中,Bundle 包含了配置、元数据和根文件系统数据,你可以理解为容器的文件系统。而 Bundle 子系统允许用户从镜像中提取和打包 Bundles。
- Runtime : Runtime 子系统用来执行 Bundles,比如创建容器。
其中,每一个子系统的行为都由一个或多个模块协作完成(架构图中的 Core 部分)。每一种类型的模块都以插件的形式集成到 Containerd 中,而且插件之间是相互依赖的。
例如,上图中的每一个长虚线的方框都表示一种类型的插件,包括 Service Plugin、Metadata Plugin、GC Plugin、Runtime Plugin 等,其中 Service Plugin 又会依赖 Metadata Plugin、GC Plugin 和 Runtime Plugin。每一个小方框都表示一个细分的插件,例如 Metadata Plugin 依赖 Containers Plugin、Content Plugin 等。
### 1.2.2 常用插件
- **Content Plugin** : 提供对镜像中可寻址内容的访问,所有不可变的内容都被存储在这里。
- **Snapshot Plugin** : 用来管理容器镜像的文件系统快照。镜像中的每一个 layer 都会被解压成文件系统快照,类似于 Docker 中的 `graphdriver`。
- **Metrics** : 暴露各个组件的监控指标。

### 1.2.3 架构缩略图
Containerd 被分为三个大块:`Storage`、`Metadata` 和 `Runtime`

### 1.2.4 与其它容器运行时工具性能对比
这是使用 bucketbench 对 Docker、crio 和 Containerd 的性能测试结果,包括启动、停止和删除容器,以比较它们所耗的时间:

结论: Containerd 在各个方面都表现良好,总体性能优于 `Docker` 和 `crio` 。
# 二、Containerd安装
> 课程操作系统环境为centos7u6
## 2.1 YUM方式安装
### 2.1.1 获取YUM源
~~~powershell
获取阿里云YUM源
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
~~~
~~~powershell
查看YUM源中Containerd软件
# yum list | grep containerd
containerd.io.x86_64 1.4.12-3.1.el7 docker-ce-stable
~~~
### 2.1.2 使用yum命令安装
~~~powershell
安装Containerd.io软件,即可安装Containerd
# yum -y install containerd.io
~~~
### 2.1.3 验证安装及启动服务
~~~powershell
使用rpm -qa命令查看是否安装
# rpm -qa | grep containerd
containerd.io-1.4.12-3.1.el7.x86_64
~~~
~~~powershell
设置containerd服务启动及开机自启动
# systemctl enable containerd
# systemctl start containerd
~~~
~~~powershell
查看containerd服务启动状态
# systemctl status containerd
● containerd.service - containerd container runtime
Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
Active: active (running) since 五 2022-02-18 11:38:30 CST; 9s ago 此行第二列及第三列表示其正在运行状态
Docs: https://containerd.io
Process: 59437 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 59439 (containerd)
Tasks: 7
Memory: 19.5M
CGroup: /system.slice/containerd.service
└─59439 /usr/bin/containerd
......
~~~
### 2.1.4 验证可用性
~~~powershell
安装Containerd时ctr命令亦可使用,ctr命令主要用于管理容器及容器镜像等。
使用ctr命令查看Containerd客户端及服务端相关信息。
# ctr version
Client:
Version: 1.4.12
Revision: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
Go version: go1.16.10
Server:
Version: 1.4.12
Revision: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
UUID: 3c4b142d-d91d-44a5-aae2-9673785d4b2c
~~~
## 2.2 二进制方式安装
Containerd有两种安装包:
* 第一种是`containerd-xxx`,这种包用于单机测试没问题,不包含runC,需要提前安装。
* 第二种是`cri-containerd-cni-xxxx`,包含runc和k8s里的所需要的相关文件。k8s集群里需要用到此包。虽然包含runC,但是依赖系统中的seccomp(安全计算模式,是一种限制容器调用系统资源的模式。)
### 2.2.1 获取安装包




~~~powershell
下载Containerd安装包
# wget https://github.com/containerd/containerd/releases/download/v1.6.0/cri-containerd-cni-1.6.0-linux-amd64.tar.gz
~~~
### 2.2.2 安装并测试可用性
#### 2.2.2.1 安装containerd
~~~powershell
查看已获取的安装包
# ls
cri-containerd-cni-1.6.0-linux-amd64.tar.gz
~~~
~~~powershell
解压已下载的软件包
# tar xf cri-containerd-cni-1.6.0-linux-amd64.tar.gz
~~~
~~~powershell
查看解压后目录
# ls
etc opt usr
~~~
~~~powershell
查看etc目录,主要为containerd服务管理配置文件及cni虚拟网卡配置文件
# ls etc
cni crictl.yaml systemd
# ls etc/systemd/
system
# ls etc/systemd/system/
containerd.service
查看opt目录,主要为gce环境中使用containerd配置文件及cni插件
# ls opt
cni containerd
# ls opt/containerd/
cluster
# ls opt/containerd/cluster/
gce version
# ls opt/containerd/cluster/gce
cloud-init cni.template configure.sh env
查看usr目录,主要为containerd运行时文件,包含runc
# ls usr
local
# ls usr/local/
bin sbin
# ls usr/local/bin
containerd containerd-shim containerd-shim-runc-v1 containerd-shim-runc-v2 containerd-stress crictl critest ctd-decoder ctr
# ls usr/local/sbin
runc
~~~
#### 2.2.2.2 查看containerd安装位置
~~~powershell
查看containerd.service文件,了解containerd文件安装位置
# cat etc/systemd/system/containerd.service
# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd 查看此位置,把containerd二进制文件放置于此处即可完成安装。
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
~~~
#### 2.2.2.3 复制containerd运行时文件至系统
~~~powershell
查看宿主机/usr/local/bin目录,里面没有任何内容。
# ls /usr/local/bin/
查看解压后usr/local/bin目录,里面包含containerd运行时文件
# ls usr/
local
# ls usr/local/
bin sbin
# ls usr/local/bin/
containerd containerd-shim containerd-shim-runc-v1 containerd-shim-runc-v2 containerd-stress crictl critest ctd-decoder ctr
复制containerd文件至/usr/local/bin目录中,本次可仅复制containerd一个文件也可复制全部文件。
# cp usr/local/bin/containerd /usr/local/bin/
# ls /usr/local/bin/
containerd
~~~
#### 2.2.2.4 添加containerd.service文件至系统
~~~powershell
查看解压后的etc/system目录
# ls etc
cni crictl.yaml systemd
# ls etc/systemd/
system
# ls etc/systemd/system/
containerd.service
复制containerd服务管理配置文件至/usr/lib/systemd/system/目录中
# cp etc/systemd/system/containerd.service /usr/lib/systemd/system/containerd.service
查看复制后结果
# ls /usr/lib/systemd/system/containerd.service
/usr/lib/systemd/system/containerd.service
~~~
#### 2.2.2.5 查看containerd使用帮助
~~~powershell
# containerd --help
NAME:
containerd -
__ _ __
_________ ____ / /_____ _(_)___ ___ _________/ /
/ ___/ __ \/ __ \/ __/ __ `/ / __ \/ _ \/ ___/ __ /
/ /__/ /_/ / / / / /_/ /_/ / / / / / __/ / / /_/ /
\___/\____/_/ /_/\__/\__,_/_/_/ /_/\___/_/ \__,_/
high performance container runtime
USAGE:
containerd [global options] command [command options] [arguments...]
VERSION:
v1.6.0
DESCRIPTION:
containerd is a high performance container runtime whose daemon can be started
by using this command. If none of the *config*, *publish*, or *help* commands
are specified, the default action of the **containerd** command is to start the
containerd daemon in the foreground.
A default configuration is used if no TOML configuration is specified or located
at the default file location. The *containerd config* command can be used to
generate the default configuration for containerd. The output of that command
can be used and modified as necessary as a custom configuration.
COMMANDS:
config information on the containerd config
publish binary to publish events to containerd
oci-hook provides a base for OCI runtime hooks to allow arguments to be injected.
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--config value, -c value path to the configuration file (default: "/etc/containerd/config.toml")
--log-level value, -l value set the logging level [trace, debug, info, warn, error, fatal, panic]
--address value, -a value address for containerd's GRPC server
--root value containerd root directory
--state value containerd state directory
--help, -h show help
--version, -v print the version
~~~
#### 2.2.2.6 生成containerd模块配置文件
##### 2.2.2.6.1 生成默认模块配置文件
Containerd 的默认配置文件为 `/etc/containerd/config.toml`,可以使用`containerd config default > /etc/containerd/config.toml`命令创建一份模块配置文件
~~~powershell
创建配置文件目录
# mkdir /etc/containerd
~~~
~~~powershell
生成配置文件
# containerd config default > /etc/containerd/config.toml
~~~
~~~powershell
查看配置文件
# cat /etc/containerd/config.toml
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
temp = ""
version = 2
[cgroup]
path = ""
[debug]
address = ""
format = ""
gid = 0
level = ""
uid = 0
[grpc]
address = "/run/containerd/containerd.sock"
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
tcp_address = ""
tcp_tls_ca = ""
tcp_tls_cert = ""
tcp_tls_key = ""
uid = 0
[metrics]
address = ""
grpc_histogram = false
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
device_ownership_from_security_context = false
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
enable_selinux = false
enable_tls_streaming = false
enable_unprivileged_icmp = false
enable_unprivileged_ports = false
ignore_image_defined_volumes = false
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
sandbox_image = "k8s.gcr.io/pause:3.6" 由于网络原因,此处被替换
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
conf_template = ""
ip_pref = ""
max_conf_num = 1
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
disable_snapshot_annotations = true
discard_unpacked_layers = false
ignore_rdt_not_enabled_errors = false
no_pivot = false
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = false
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
[plugins."io.containerd.grpc.v1.cri".image_decryption]
key_model = "node"
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins."io.containerd.internal.v1.opt"]
path = "/opt/containerd"
[plugins."io.containerd.internal.v1.restart"]
interval = "10s"
[plugins."io.containerd.internal.v1.tracing"]
sampling_ratio = 1.0
service_name = "containerd"
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "shared"
[plugins."io.containerd.monitor.v1.cgroups"]
no_prometheus = false
[plugins."io.containerd.runtime.v1.linux"]
no_shim = false
runtime = "runc"
runtime_root = ""
shim = "containerd-shim"
shim_debug = false
[plugins."io.containerd.runtime.v2.task"]
platforms = ["linux/amd64"]
sched_core = false
[plugins."io.containerd.service.v1.diff-service"]
default = ["walking"]
[plugins."io.containerd.service.v1.tasks-service"]
rdt_config_file = ""
[plugins."io.containerd.snapshotter.v1.aufs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.btrfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.devmapper"]
async_remove = false
base_image_size = ""
discard_blocks = false
fs_options = ""
fs_type = ""
pool_name = ""
root_path = ""
[plugins."io.containerd.snapshotter.v1.native"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.overlayfs"]
root_path = ""
upperdir_label = false
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = ""
[plugins."io.containerd.tracing.processor.v1.otlp"]
endpoint = ""
insecure = false
protocol = ""
[proxy_plugins]
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
[timeouts]
"io.containerd.timeout.bolt.open" = "0s"
"io.containerd.timeout.shim.cleanup" = "5s"
"io.containerd.timeout.shim.load" = "5s"
"io.containerd.timeout.shim.shutdown" = "3s"
"io.containerd.timeout.task.state" = "2s"
[ttrpc]
address = ""
gid = 0
uid = 0
~~~
##### 2.2.2.6.2 替换默认配置文件
但上述配置文件后期改动的地方较多,这里直接换成可单机使用也可k8s环境使用的配置文件并配置好镜像加速器。
~~~powershell
# vim /etc/containerd/config.toml
# cat /etc/containerd/config.toml
root = "/var/lib/containerd"
state = "/run/containerd"
oom_score = -999
[grpc]
address = "/run/containerd/containerd.sock"
uid = 0
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
[debug]
address = ""
uid = 0
gid = 0
level = ""
[metrics]
address = ""
grpc_histogram = false
[cgroup]
path = ""
[plugins]
[plugins.cgroups]
no_prometheus = false
[plugins.cri]
stream_server_address = "127.0.0.1"
stream_server_port = "0"
enable_selinux = false
sandbox_image = "easzlab/pause-amd64:3.2"
stats_collect_period = 10
systemd_cgroup = false
enable_tls_streaming = false
max_container_log_line_size = 16384
[plugins.cri.containerd]
snapshotter = "overlayfs"
no_pivot = false
[plugins.cri.containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = ""
runtime_root = ""
[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = ""
runtime_engine = ""
runtime_root = ""
[plugins.cri.cni]
bin_dir = "/opt/kube/bin"
conf_dir = "/etc/cni/net.d"
conf_template = "/etc/cni/net.d/10-default.conf"
[plugins.cri.registry]
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."docker.io"]
endpoint = [
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
]
[plugins.cri.registry.mirrors."gcr.io"]
endpoint = [
"https://gcr.mirrors.ustc.edu.cn"
]
[plugins.cri.registry.mirrors."k8s.gcr.io"]
endpoint = [
"https://gcr.mirrors.ustc.edu.cn/google-containers/"
]
[plugins.cri.registry.mirrors."quay.io"]
endpoint = [
"https://quay.mirrors.ustc.edu.cn"
]
[plugins.cri.registry.mirrors."harbor.kubemsb.com"] 此处添加了本地容器镜像仓库 Harbor,做为本地容器镜像仓库。
endpoint = [
"http://harbor.kubemsb.com"
]
[plugins.cri.x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins.diff-service]
default = ["walking"]
[plugins.linux]
shim = "containerd-shim"
runtime = "runc"
runtime_root = ""
no_shim = false
shim_debug = false
[plugins.opt]
path = "/opt/containerd"
[plugins.restart]
interval = "10s"
[plugins.scheduler]
pause_threshold = 0.02
deletion_threshold = 0
mutation_threshold = 100
schedule_delay = "0s"
startup_delay = "100ms"
~~~
#### 2.2.2.7 启动containerd服务并设置开机自启动
~~~powershell
# systemctl enable containerd
Created symlink from /etc/systemd/system/multi-user.target.wants/containerd.service to /usr/lib/systemd/system/containerd.service.
# systemctl start containerd
~~~
~~~powershell
# systemctl status containerd
● containerd.service - containerd container runtime
Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
Active: active (running) since 五 2022-02-18 13:02:37 CST; 7s ago
Docs: https://containerd.io
Process: 60383 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 60384 (containerd)
Tasks: 8
Memory: 20.0M
CGroup: /system.slice/containerd.service
└─60384 /usr/local/bin/containerd
......
~~~
#### 2.2.2.8 复制ctr命令至系统
~~~powershell
# ls usr/local/bin/
containerd containerd-shim containerd-shim-runc-v1 containerd-shim-runc-v2 containerd-stress crictl critest ctd-decoder ctr
# cp usr/local/bin/ctr /usr/bin/
~~~
#### 2.2.2.9 查看已安装containerd服务版本
~~~powershell
# ctr version
Client:
Version: v1.6.0
Revision: 39259a8f35919a0d02c9ecc2871ddd6ccf6a7c6e
Go version: go1.17.2
Server:
Version: v1.6.0
Revision: 39259a8f35919a0d02c9ecc2871ddd6ccf6a7c6e
UUID: c1972cbe-884a-41b0-867f-f8a58c168e6d
~~~
#### 2.2.2.10 安装runC
> 由于二进制包中提供的runC默认需要系统中安装seccomp支持,需要单独安装,且不同版本runC对seccomp版本要求一致,所以建议单独下载runC 二进制包进行安装,里面包含了seccomp模块支持。
##### 2.2.2.10.1 获取runC




~~~powershell
使用wget下载
# wget https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.amd64
~~~
##### 2.2.2.10.2 安装runC并验证安装结果
~~~powershell
查看已下载文件
# ls
runc.amd64
~~~
~~~powershell
安装runC
# mv runc.amd64 /usr/sbin/runc
~~~
~~~powershell
为runC添加可执行权限
# chmod +x /usr/sbin/runc
~~~
~~~powershell
使用runc命令验证是否安装成功
# runc -v
runc version 1.1.0
commit: v1.1.0-0-g067aaf85
spec: 1.0.2-dev
go: go1.17.6
libseccomp: 2.5.3
~~~
# 三、Containerd容器镜像管理
## 3.1 Containerd容器镜像管理命令
* docker使用docker images命令管理镜像
* 单机containerd使用ctr images命令管理镜像,containerd本身的CLI
* k8s中containerd使用crictl images命令管理镜像,Kubernetes社区的专用CLI工具
~~~powershell
获取命令帮助
# ctr --help
NAME:
ctr -
__
_____/ /______
/ ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
containerd CLI
USAGE:
ctr [global options] command [command options] [arguments...]
VERSION:
v1.6.0
DESCRIPTION:
ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.
COMMANDS:
plugins, plugin provides information about containerd plugins
version print the client and server versions
containers, c, container manage containers
content manage content
events, event display containerd events
images, image, i manage images
leases manage leases
namespaces, namespace, ns manage namespaces
pprof provide golang pprof outputs for containerd
run run a container
snapshots, snapshot manage snapshots
tasks, t, task manage tasks
install install a new package
oci OCI tools
shim interact with a shim directly
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--debug enable debug output in logs
--address value, -a value address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
--timeout value total timeout for ctr commands (default: 0s)
--connect-timeout value timeout for connecting to containerd (default: 0s)
--namespace value, -n value namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
--help, -h show help
--version, -v print the version
~~~
~~~powershell
获取命令帮助
# ctr images
NAME:
ctr images - manage images
USAGE:
ctr images command [command options] [arguments...]
COMMANDS:
check check existing images to ensure all content is available locally
export export images
import import images
list, ls list images known to containerd
mount mount an image to a target path
unmount unmount the image from the target
pull pull an image from a remote
push push an image to a remote
delete, del, remove, rm remove one or more images by reference
tag tag an image
label set and clear labels for an image
convert convert an image
OPTIONS:
--help, -h show help
~~~
## 3.2 查看镜像
~~~powershell
# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
~~~
## 3.3 下载镜像
containerd支持oci标准的镜像,所以可以直接使用docker官方或dockerfile构建的镜像
~~~powershell
# ctr images pull --all-platforms docker.io/library/nginx:alpine
docker.io/library/nginx:alpine: resolved |++++++++++++++++++++++++++++++++++++++|
docker.io/library/nginx:alpine: resolved |++++++++++++++++++++++++++++++++++++++|
index-sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3: done |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:050385609d832fae11b007fbbfba77d0bba12bf72bc0dca0ac03e09b1998580f: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:f2303c6c88653b9a6739d50f611c170b9d97d161c6432409c680f6b46a5f112f: done |++++++++++++++++++++++++++++++++++++++|
config-sha256:bef258acf10dc257d641c47c3a600c92f87be4b4ce4a5e4752b3eade7533dcd9: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:8d6ba530f6489d12676d7f61628427d067243ba4a3a512c3e28813b977cb3b0e: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:5288d7ad7a7f84bdd19c1e8f0abb8684b5338f3da86fe9ae1d7f0e9bc2de6595: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:39e51c61c033442d00c40a30b2a9ed01f40205875fbd8664c50b4dc3e99ad5cf: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ee6f71c6f4a82b2afd01f92bdf6be0079364d03020e8a2c569062e1c06d3822b: done |++++++++++++++++++++++++++++++++++++++|
elapsed: 11.0s total: 8.7 Mi (809.5 KiB/s)
unpacking linux/amd64 sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3...
done: 1.860946163s
~~~
~~~powershell
说明:
这里ctr命令pull镜像时,不能直接把镜像名字写成`nginx:alpine`
~~~
~~~powershell
查看已下载容器镜像
# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 9.7 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
~~~
| REF | TYPE | DIGEST |
| ------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------ |
| docker.io/library/nginx:alpine | application/vnd.docker.distribution.manifest.list.v2+json | sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 |
| SIZE | PLATFORMS | LABELS |
| ------- | ------------------------------------------------------------ | ------ |
| 9.7 MiB | linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x | - |
~~~powershell
指定平台下载容器镜像
# ctr images pull --platform linux/amd64 docker.io/library/nginx:alpine
~~~
## 3.4 镜像挂载
> 方便查看镜像中包含的内容。
~~~powershell
把已下载的容器镜像挂载至当前文件系统
# ctr images mount docker.io/library/nginx:alpine /mnt
sha256:af2fcce448e2e4451a5f4796a9bf9cb5c9b5f88e0d6d10029cada42fb9d268ac
/mnt
[root@localhost ~]# ls /mnt
bin dev docker-entrypoint.d docker-entrypoint.sh etc home lib media mnt opt proc root run sbin srv sys tmp usr var
~~~
~~~powershell
卸载
# umount /mnt
~~~
## 3.5 镜像导出
~~~powershell
把容器镜像导出
# ctr i export --all-platforms nginx.img docker.io/library/nginx:alpine
~~~
~~~powershell
说明
--all-platforms,导出所有平台镜像,本版本为1.6版本,1.4版本不需要添加此选项。
~~~
~~~powershell
查看已导出容器镜像
# ls
nginx.img
# ls -lh
总用量 196M
-rw-r--r-- 1 root root 73M 2月 18 14:48 nginx.img
~~~
## 3.6 镜像删除
~~~powershell
删除指定容器镜像
# ctr image rm docker.io/library/nginx:alpine
docker.io/library/nginx:alpine
再次查看容器镜像
[root@192 ~]# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
~~~
## 3.7 镜像导入
~~~powershell
导入容器镜像
# ctr images import nginx.img
unpacking docker.io/library/nginx:alpine (sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3)...done
~~~
## 3.8 修改镜像tag
~~~powershell
# ctr images tag docker.io/library/nginx:alpine nginx:alpine
nginx:alpine
~~~
~~~powershell
说明:
把docker.io/library/nginx:alpine 修改为 nginx:alpine
~~~
~~~powershell
查看修改后的容器镜像
# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 9.7 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 9.7 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
~~~
~~~powershell
修改后对容器镜像做检查比对
# ctr images check
REF TYPE DIGEST STATUS SIZE UNPACKED
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 complete (7/7) 9.7 MiB/9.7 MiB true
nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 complete (7/7) 9.7 MiB/9.7 MiB true
~~~
# 四、Containerd容器管理
## 4.1 获取命令帮助
### 4.1.1 获取ctr命令帮助
~~~powershell
[root@localhost ~]# ctr --help
NAME:
ctr -
__
_____/ /______
/ ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
containerd CLI
USAGE:
ctr [global options] command [command options] [arguments...]
VERSION:
v1.6.0
DESCRIPTION:
ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.
COMMANDS:
plugins, plugin provides information about containerd plugins
version print the client and server versions
containers, c, container manage containers
content manage content
events, event display containerd events
images, image, i manage images
leases manage leases
namespaces, namespace, ns manage namespaces
pprof provide golang pprof outputs for containerd
run run a container
snapshots, snapshot manage snapshots
tasks, t, task manage tasks
install install a new package
oci OCI tools
shim interact with a shim directly
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--debug enable debug output in logs
--address value, -a value address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
--timeout value total timeout for ctr commands (default: 0s)
--connect-timeout value timeout for connecting to containerd (default: 0s)
--namespace value, -n value namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
--help, -h show help
--version, -v print the version
~~~
### 4.1.2 获取创建静态容器命令帮助
~~~powershell
# ctr container --help
NAME:
ctr containers - manage containers
USAGE:
ctr containers command [command options] [arguments...]
COMMANDS:
create create container
delete, del, remove, rm delete one or more existing containers
info get info about a container
list, ls list containers
label set and clear labels for a container
checkpoint checkpoint a container
restore restore a container from checkpoint
OPTIONS:
--help, -h show help
~~~
~~~powershell
说明:
使用`ctr container create `命令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。这个 container 对象只是包含了运行一个容器所需的资源及配置的数据结构,例如: namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程(本案例为nginx)还没有启动。需要使用`ctr tasks`命令才能获取一个动态容器。
~~~
### 4.1.3 获取动态容器命令帮助
~~~powershell
# ctr run --help
NAME:
ctr run - run a container
USAGE:
ctr run [command options] [flags] Image|RootFS ID [COMMAND] [ARG...]
OPTIONS:
--rm remove the container after running
--null-io send all IO to /dev/null
--log-uri value log uri
--detach, -d detach from the task after it has started execution
--fifo-dir value directory used for storing IO FIFOs
--cgroup value cgroup path (To disable use of cgroup, set to "" explicitly)
--platform value run image for specific platform
--cni enable cni networking for the container
--runc-binary value specify runc-compatible binary
--runc-root value specify runc-compatible root
--runc-systemd-cgroup start runc with systemd cgroup manager
--uidmap container-uid:host-uid:length run inside a user namespace with the specified UID mapping range; specified with the format container-uid:host-uid:length
--gidmap container-gid:host-gid:length run inside a user namespace with the specified GID mapping range; specified with the format container-gid:host-gid:length
--remap-labels provide the user namespace ID remapping to the snapshotter via label options; requires snapshotter support
--cpus value set the CFS cpu quota (default: 0)
--cpu-shares value set the cpu shares (default: 1024)
--snapshotter value snapshotter name. Empty value stands for the default value. [$CONTAINERD_SNAPSHOTTER]
--snapshotter-label value labels added to the new snapshot for this container.
--config value, -c value path to the runtime-specific spec config file
--cwd value specify the working directory of the process
--env value specify additional container environment variables (e.g. FOO=bar)
--env-file value specify additional container environment variables in a file(e.g. FOO=bar, one per line)
--label value specify additional labels (e.g. foo=bar)
--mount value specify additional container mount (e.g. type=bind,src=/tmp,dst=/host,options=rbind:ro)
--net-host enable host networking for the container
--privileged run privileged container
--read-only set the containers filesystem as readonly
--runtime value runtime name (default: "io.containerd.runc.v2")
--runtime-config-path value optional runtime config path
--tty, -t allocate a TTY for the container
--with-ns value specify existing Linux namespaces to join at container runtime (format '<nstype>:<path>')
--pid-file value file path to write the task's pid
--gpus value add gpus to the container
--allow-new-privs turn off OCI spec's NoNewPrivileges feature flag
--memory-limit value memory limit (in bytes) for the container (default: 0)
--device value file path to a device to add to the container; or a path to a directory tree of devices to add to the container
--cap-add value add Linux capabilities (Set capabilities with 'CAP_' prefix)
--cap-drop value drop Linux capabilities (Set capabilities with 'CAP_' prefix)
--seccomp enable the default seccomp profile
--seccomp-profile value file path to custom seccomp profile. seccomp must be set to true, before using seccomp-profile
--apparmor-default-profile value enable AppArmor with the default profile with the specified name, e.g. "cri-containerd.apparmor.d"
--apparmor-profile value enable AppArmor with an existing custom profile
--rdt-class value name of the RDT class to associate the container with. Specifies a Class of Service (CLOS) for cache and memory bandwidth management.
--rootfs use custom rootfs that is not managed by containerd snapshotter
--no-pivot disable use of pivot-root (linux only)
--cpu-quota value Limit CPU CFS quota (default: -1)
--cpu-period value Limit CPU CFS period (default: 0)
--rootfs-propagation value set the propagation of the container rootfs
~~~
~~~powershell
说明:
使用`ctr run`命令可以创建一个静态容器并使其运行。一步到位运行容器。
~~~
## 4.2 查看容器
container表示静态容器,可用c缩写代表container
~~~powershell
# ctr container ls
CONTAINER IMAGE RUNTIME
~~~
或
~~~powershell
# ctr c ls
CONTAINER IMAGE RUNTIME
~~~
## 4.3 查看任务
task表示容器里跑的进程, 可用t缩写代表task
~~~powershell
# ctr task ls
TASK PID STATUS
~~~
或
~~~powershell
# ctr t ls
TASK PID STATUS
~~~
## 4.4 创建静态容器
~~~powershell
# ctr c create docker.io/library/nginx:alpine nginx1
~~~
~~~powershell
# ctr container ls
CONTAINER IMAGE RUNTIME
nginx1 docker.io/library/nginx:alpine io.containerd.runc.v2
~~~
~~~powershell
查看容器详细信息
# ctr container info nginx1
~~~
## 4.5 静态容器启动为动态容器
~~~powershell
复制containerd连接runC垫片工具至系统
# ls usr/local/bin/
containerd containerd-shim containerd-shim-runc-v1 containerd-shim-runc-v2 containerd-stress crictl critest ctd-decoder ctr
[root@localhost ~]# cp usr/local/bin/containerd-shim-runc-v2 /usr/bin/
~~~
~~~powershell
启动task,即表时在容器中运行了进程,即为动态容器。
# ctr task start -d nginx1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
~~~
~~~powershell
说明:
-d表示daemon或者后台的意思,否则会卡住终端
~~~
~~~powershell
查看容器所在宿主机进程,是以宿主机进程的方式存在的。
# ctr task ls
TASK PID STATUS
nginx1 3395 RUNNING
~~~
~~~powershell
查看容器的进程(都是物理机的进程)
# ctr task ps nginx1
PID INFO
3395 -
3434 -
~~~
~~~powershell
物理机查看到相应的进程
# ps -ef | grep 3395
root 3395 3375 0 19:16 ? 00:00:00 nginx: master process nginx -g daemon off;
101 3434 3395 0 19:16 ? 00:00:00 nginx: worker process
~~~
## 4.6 进入容器操作
~~~powershell
# ctr task exec --exec-id 1 nginx1 /bin/sh
ifconfig 查看网卡信息
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
curl 127.0.0.1 访问本地提供的web服务
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>
100 615 100 615 0 0 429k 0 --:--:-- --:--:-- --:--:-- 600k
~~~
~~~powershell
说明:
为exec进程设定一个id,可以随意输入,只要保证唯一即可,也可使用$RANDOM变量。
~~~
## 4.7 直接运行一个动态容器
~~~powershell
# ctr run -d --net-host docker.io/library/nginx:alpine nginx2
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
~~~
~~~powershell
说明:
* -d 代表dameon,后台运行
* --net-host 代表容器的IP就是宿主机的IP(相当于docker里的host类型网络)
~~~
~~~powershell
查看已运行容器
# ctr container ls
CONTAINER IMAGE RUNTIME
nginx2 docker.io/library/nginx:alpine io.containerd.runc.v2
~~~
~~~powershell
查看已运行容器中运行的进程,既tasks
# ctr tasks ls
TASK PID STATUS
nginx2 4061 RUNNING
~~~
~~~powershell
进入容器
# ctr task exec --exec-id 1 -t nginx2 /bin/sh
~~~
~~~powershell
/ # ifconfig
ens33 Link encap:Ethernet HWaddr 00:0C:29:B1:B6:1D
inet addr:192.168.10.164 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::2b33:40ed:9311:8812/64 Scope:Link
inet6 addr: fe80::adf4:a8bc:a1c:a9f7/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:55360 errors:0 dropped:0 overruns:0 frame:0
TX packets:30526 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:53511295 (51.0 MiB) TX bytes:2735050 (2.6 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:68 errors:0 dropped:0 overruns:0 frame:0
TX packets:68 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5916 (5.7 KiB) TX bytes:5916 (5.7 KiB)
virbr0 Link encap:Ethernet HWaddr 52:54:00:E9:51:82
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
~~~
~~~powershell
为容器中运行的网站添加网站文件
/ # echo "nginx2" > /usr/share/nginx/html/index.html
/ # exit
~~~
~~~powershell
在宿主机上访问网站
[root@localhost ~]# curl 192.168.10.164
nginx2
~~~
## 4.8 暂停容器
~~~powershell
查看容器状态
# ctr tasks ls
TASK PID STATUS
nginx2 4061 RUNNING
~~~
~~~powershell
暂停容器
# ctr tasks pause nginx2
~~~
~~~powershell
再次查看容器状态,看到其状态为PAUSED,表示停止。
# ctr tasks ls
TASK PID STATUS
nginx2 4061 PAUSED
~~~
~~~powershell
[root@localhost ~]# curl http://192.168.10.164
在宿主机访问,发现不可以访问到网站
~~~
## 4.9 恢复容器
~~~powershell
使用resume命令恢复容器
# ctr tasks resume nginx2
~~~
~~~powershell
查看恢复后状态
# ctr tasks ls
TASK PID STATUS
nginx2 4061 RUNNING
~~~
~~~powershell
在宿主机上访问容器中提供的服务
# curl http://192.168.10.164
nginx2
~~~
## 4.10 停止容器
~~~powershell
# ctr tasks --help
NAME:
ctr tasks - manage tasks
USAGE:
ctr tasks command [command options] [arguments...]
COMMANDS:
attach attach to the IO of a running container
checkpoint checkpoint a container
delete, del, remove, rm delete one or more tasks
exec execute additional processes in an existing container
list, ls list tasks
kill signal a container (default: SIGTERM)
pause pause an existing container
ps list processes for container
resume resume a paused container
start start a container that has been created
metrics, metric get a single data point of metrics for a task with the built-in Linux runtime
OPTIONS:
--help, -h show help
~~~
~~~powershell
使用kill命令停止容器中运行的进程,既为停止容器
# ctr tasks kill nginx2
~~~
~~~powershell
查看容器停止后状态,STATUS为STOPPED
# ctr tasks ls
TASK PID STATUS
nginx1 3395 RUNNING
nginx2 4061 STOPPED
~~~
## 4.11 删除容器
~~~powershell
# ctr tasks delete nginx2
必须先停止tasks或先删除task,再删除容器
~~~
~~~powershell
查看静态容器,确认其还存在于系统中
# ctr container ls
CONTAINER IMAGE RUNTIME
nginx2 docker.io/library/nginx:alpine io.containerd.runc.v2
~~~
~~~powershell
删除容器
# ctr container delete nginx2
~~~
# 五、Containerd使用私有容器镜像仓库 Harbor
## 5.1 Harbor准备


## 5.2 配置Containerd使用Harbor仓库
### 5.2.1 Harbor主机名解析
> 在所有安装containerd宿主机上添加此配置信息。
~~~powershell
# vim /etc/hosts
# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.165 harbor.kubemsb.com
~~~
~~~powershell
说明
* 192.168.10.165是harbor的IP
* harbor.kubemsb.com建议用FQDN形式,如果用类似harbor这种短名,后面下载镜像会出问题
~~~
### 5.2.2 修改Containerd配置文件
~~~powershell
此配置文件已提前替换过,仅修改本地容器镜像仓库地址即可。
# vim /etc/containerd/config.toml
# cat /etc/containerd/config.toml
root = "/var/lib/containerd"
state = "/run/containerd"
oom_score = -999
[grpc]
address = "/run/containerd/containerd.sock"
uid = 0
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
[debug]
address = ""
uid = 0
gid = 0
level = ""
[metrics]
address = ""
grpc_histogram = false
[cgroup]
path = ""
[plugins]
[plugins.cgroups]
no_prometheus = false
[plugins.cri]
stream_server_address = "127.0.0.1"
stream_server_port = "0"
enable_selinux = false
sandbox_image = "easzlab/pause-amd64:3.2"
stats_collect_period = 10
systemd_cgroup = false
enable_tls_streaming = false
max_container_log_line_size = 16384
[plugins.cri.containerd]
snapshotter = "overlayfs"
no_pivot = false
[plugins.cri.containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = ""
runtime_root = ""
[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = ""
runtime_engine = ""
runtime_root = ""
[plugins.cri.cni]
bin_dir = "/opt/kube/bin"
conf_dir = "/etc/cni/net.d"
conf_template = "/etc/cni/net.d/10-default.conf"
[plugins.cri.registry]
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."docker.io"]
endpoint = [
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
]
[plugins.cri.registry.mirrors."gcr.io"]
endpoint = [
"https://gcr.mirrors.ustc.edu.cn"
]
[plugins.cri.registry.mirrors."k8s.gcr.io"]
endpoint = [
"https://gcr.mirrors.ustc.edu.cn/google-containers/"
]
[plugins.cri.registry.mirrors."quay.io"]
endpoint = [
"https://quay.mirrors.ustc.edu.cn"
]
[plugins.cri.registry.mirrors."harbor.kubemsb.com"] 在此处添加,在镜像加速器下面添加这一段
endpoint = [
"http://harbor.kubemsb.com"
]
[plugins.cri.x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins.diff-service]
default = ["walking"]
[plugins.linux]
shim = "containerd-shim"
runtime = "runc"
runtime_root = ""
no_shim = false
shim_debug = false
[plugins.opt]
path = "/opt/containerd"
[plugins.restart]
interval = "10s"
[plugins.scheduler]
pause_threshold = 0.02
deletion_threshold = 0
mutation_threshold = 100
schedule_delay = "0s"
startup_delay = "100ms"
~~~
~~~powershell
重启containerd,以便于重新加载配置文件。
# systemctl restart containerd
~~~
### 5.2.3 ctr下载镜像
~~~powershell
下载容器镜像
# ctr images pull --platform linux/amd64 docker.io/library/nginx:latest
~~~
~~~powershell
说明:
* --platform linux/amd64 指定系统平台,也可以使用--all-platforms指定所有平台镜像。
~~~
~~~powershell
输出:
docker.io/library/nginx:latest: resolved |++++++++++++++++++++++++++++++++++++++|
index-sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767: done |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:bb129a712c2431ecce4af8dde831e980373b26368233ef0f3b2bae9e9ec515ee: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:b559bad762bec166fd028483dd2a03f086d363ee827d8c98b7268112c508665a: done |++++++++++++++++++++++++++++++++++++++|
config-sha256:c316d5a335a5cf324b0dc83b3da82d7608724769f6454f6d9a621f3ec2534a5a: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:5eb5b503b37671af16371272f9c5313a3e82f1d0756e14506704489ad9900803: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:1ae07ab881bd848493ad54c2ba32017f94d1d8dbfd0ba41b618f17e80f834a0f: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:78091884b7bea0fa918527207924e9993bcc21bf7f1c9687da40042ceca31ac9: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:091c283c6a66ad0edd2ab84cb10edacc00a1a7bc5277f5365c0d5c5457a75aff: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:55de5851019b8f65ed6e28120c6300e35e556689d021e4b3411c7f4e90a9704b: done |++++++++++++++++++++++++++++++++++++++|
elapsed: 20.0s total: 53.2 M (2.7 MiB/s)
unpacking linux/amd64 sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767...
done: 3.028652226s
~~~
~~~powershell
查看已下载容器镜像
# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/nginx:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 54.1 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x -
~~~
### 5.2.4 ctr上传镜像
>上传到Harbor library公有项目
~~~powershell
重新生成新的tag
# ctr images tag docker.io/library/nginx:latest harbor.kubemsb.com/library/nginx:latest
harbor.kubemsb.com/library/nginx:latest
~~~
~~~powershell
查看已生成容器镜像
# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/nginx:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 54.1 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x -
harbor.kubemsb.com/library/nginx:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 54.1 MiB linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x -
~~~
~~~powershell
推送容器镜像至Harbor
# ctr images push --platform linux/amd64 --plain-http -u admin:Harbor12345 harbor.kubemsb.com/library/nginx:latest
~~~
~~~powershell
说明:
* 先tag再push
* 因为我们harbor是http协议,不是https协议,所以需要加上`--plain-http`
* `--user admin:Harbor12345`指定harbor的用户名与密码
~~~
~~~powershell
输出:
manifest-sha256:0fd68ec4b64b8dbb2bef1f1a5de9d47b658afd3635dc9c45bf0cbeac46e72101: done |++++++++++++++++++++++++++++++++++++++|
config-sha256:dd025cdfe837e1c6395365870a491cf16bae668218edb07d85c626928a60e478: done |++++++++++++++++++++++++++++++++++++++|
elapsed: 0.5 s total: 9.3 Ki (18.1 KiB/s)
~~~

~~~powershell
下载已上传容器镜像
# ctr images pull --plain-http harbor.kubemsb.com/library/nginx:latest
~~~
# 六、Containerd NameSpace管理
> containerd中namespace的作用为:隔离运行的容器,可以实现运行多个容器。
~~~powershell
查看命令帮助
# ctr namespace --help
NAME:
ctr namespaces - manage namespaces
USAGE:
ctr namespaces command [command options] [arguments...]
COMMANDS:
create, c create a new namespace
list, ls list namespaces
remove, rm remove one or more namespaces
label set and clear labels for a namespace
OPTIONS:
--help, -h show help
~~~
~~~powershell
列出已有namespace
# ctr namespace ls
NAME LABELS
default
k8s.io
~~~
~~~powershell
创建namespace
# ctr namespace create kubemsb
[root@localhost ~]# ctr namespace ls
NAME LABELS
default
k8s.io
kubemsb 此命名空间为新添加的
~~~
~~~powershell
删除namespace
# ctr namespace rm kubemsb
kubemsb
再次查看是否删除
[root@localhost ~]# ctr namespace ls
NAME LABELS
default
k8s.io
~~~
~~~powershell
查看指定namespace中是否有用户进程在运行
# ctr -n kubemsb tasks ls
TASK PID STATUS
~~~
~~~powershell
在指定namespace中下载容器镜像
# ctr -n kubemsb images pull docker.io/library/nginx:latest
~~~
~~~powershell
在指定namespace中创建静态容器
# ctr -n kubemsb container create docker.io/library/nginx:latest nginxapp
~~~
~~~powershell
查看在指定namespace中创建的容器
# ctr -n kubemsb container ls
CONTAINER IMAGE RUNTIME
nginxapp docker.io/library/nginx:latest io.containerd.runc.v2
~~~
# 七、Containerd Network管理
> 默认Containerd管理的容器仅有lo网络,无法访问容器之外的网络,可以为其添加网络插件,使用容器可以连接外网。CNI(Container Network Interface)
## 7.1 创建CNI网络
| [*containernetworking*/*cni*](https://github.com/containernetworking/cni) | [ CNI v1.0.1](https://github.com/containernetworking/cni/releases/tag/v1.0.1) |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| [*containernetworking*/*plugins*](https://github.com/containernetworking/plugins) | [ CNI Plugins v1.0.1](https://github.com/containernetworking/plugins/releases/tag/v1.0.1) |
### 7.1.1 获取CNI工具源码




~~~powershell
使用wget下载cni工具源码包
# wget https://github.com/containernetworking/cni/archive/refs/tags/v1.0.1.tar.gz
~~~
~~~powershell
查看已下载cni工具源码包
# ls
v1.0.1.tar.gz
解压已下载cni工具源码包
# tar xf v1.0.1.tar.gz
查看解压后已下载cni工具源码包
# ls
cni-1.0.1
重命名已下载cni工具源码包目录
# mv cni-1.0.1 cni
查看重新命名后目录
# ls
cni
查看cni工具目录中包含的文件
# ls cni
cnitool CONTRIBUTING.md DCO go.mod GOVERNANCE.md LICENSE MAINTAINERS plugins RELEASING.md scripts test.sh
CODE-OF-CONDUCT.md CONVENTIONS.md Documentation go.sum libcni logo.png pkg README.md ROADMAP.md SPEC.md
~~~
### 7.1.2 获取CNI Plugins(CNI插件)




~~~powershell
使用wget下载cni插件工具源码包
# wget https://github.com/containernetworking/plugins/releases/download/v1.0.1/cni-plugins-linux-amd64-v1.0.1.tgz
~~~
~~~powershell
查看已下载cni插件工具源码包
# ls
cni-plugins-linux-amd64-v1.0.1.tgz
cni
创建cni插件工具解压目录
# mkdir /home/cni-plugins
解压cni插件工具至上述创建的目录中
# tar xf cni-plugins-linux-amd64-v1.0.1.tgz -C /home/cni-plugins
查看解压后目录
# ls cni-plugins
bandwidth bridge dhcp firewall host-device host-local ipvlan loopback macvlan portmap ptp sbr static tuning vlan vrf
~~~
### 7.1.3 准备CNI网络配置文件
> 准备容器网络配置文件,用于为容器提供网关、IP地址等。
~~~powershell
创建名为mynet的网络,其中包含名为cni0的网桥
# vim /etc/cni/net.d/10-mynet.conf
# cat /etc/cni/net.d/10-mynet.conf
{
"cniVersion": "1.0.0",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.66.0.0/16",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}
~~~
~~~powershell
# vim /etc/cni/net.d/99-loopback.conf
# cat /etc/cni/net.d/99-loopback.conf
{
"cniVerion": "1.0.0",
"name": "lo",
"type": "loopback"
}
~~~
### 7.1.4 生成CNI网络
~~~powershell
获取epel源
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
安装jq
# yum -y install jq
~~~
~~~powershell
进入cni工具目录
# cd cni
[root@localhost cni]# ls
cnitool CONTRIBUTING.md DCO go.mod GOVERNANCE.md LICENSE MAINTAINERS plugins RELEASING.md scripts test.sh
CODE-OF-CONDUCT.md CONVENTIONS.md Documentation go.sum libcni logo.png pkg README.md ROADMAP.md SPEC.md
必须在scripts目录中执行,需要依赖exec-plugins.sh文件,再次进入scripts目录
[root@localhost cni]# cd scripts/
查看执行脚本文件
[root@localhost scripts]# ls
docker-run.sh exec-plugins.sh priv-net-run.sh release.sh
执行脚本文件,基于/etc/cni/net.d/目录中的*.conf配置文件生成容器网络
[root@localhost scripts]# CNI_PATH=/home/cni-plugins ./priv-net-run.sh echo "Hello World"
Hello World
~~~
~~~powershell
在宿主机上查看是否生成容器网络名为cni0的网桥
# ip a s
......
5: cni0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 36:af:7a:4a:d6:12 brd ff:ff:ff:ff:ff:ff
inet 10.66.0.1/16 brd 10.66.255.255 scope global cni0
valid_lft forever preferred_lft forever
inet6 fe80::34af:7aff:fe4a:d612/64 scope link
valid_lft forever preferred_lft forever
~~~
~~~powershell
在宿主机上查看其路由表情况
# ip route
default via 192.168.10.2 dev ens33 proto dhcp metric 100
10.66.0.0/16 dev cni0 proto kernel scope link src 10.66.0.1
192.168.10.0/24 dev ens33 proto kernel scope link src 192.168.10.164 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
~~~
## 7.2 为Containerd容器配置网络功能
### 7.2.1 创建一个容器
~~~powershell
# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
# ctr images pull docker.io/library/busybox:latest
# ctr run -d docker.io/library/busybox:latest busybox
# ctr container ls
CONTAINER IMAGE RUNTIME
busybox docker.io/library/busybox:latest io.containerd.runc.v2
# ctr tasks ls
TASK PID STATUS
busybox 8377 RUNNING
~~~
### 7.2.2 进入容器查看其网络情况
~~~powershell
# ctr tasks exec --exec-id $RANDOM -t busybox sh
/ # ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
~~~
### 7.2.3 获取容器进程ID及其网络命名空间
~~~powershell
在宿主机中完成指定容器进程ID获取
# pid=$(ctr tasks ls | grep busybox | awk '{print $2}')
# echo $pid
8377
~~~
~~~powershell
在宿主机中完成指定容器网络命名空间路径获取
# netnspath=/proc/$pid/ns/net
# echo $netnspath
/proc/8377/ns/net
~~~
### 7.2.4 为指定容器添加网络配置
~~~powershell
确认执行脚本文件时所在的目录
[root@localhost scripts]# pwd
/home/cni/scripts
~~~
~~~powershell
执行脚本文件为容器添加网络配置
[root@localhost scripts]# CNI_PATH=/home/cni-plugins ./exec-plugins.sh add $pid $netnspath
~~~
~~~powershell
进入容器确认是否添加网卡信息
# ctr tasks exec --exec-id $RANDOM -t busybox sh
/ # ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether a2:35:b7:e0:60:0a brd ff:ff:ff:ff:ff:ff
inet 10.66.0.3/16 brd 10.66.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a035:b7ff:fee0:600a/64 scope link
valid_lft forever preferred_lft forever
在容器中ping容器宿主机IP地址
/ # ping -c 2 192.168.10.164
PING 192.168.10.164 (192.168.10.164): 56 data bytes
64 bytes from 192.168.10.164: seq=0 ttl=64 time=0.132 ms
64 bytes from 192.168.10.164: seq=1 ttl=64 time=0.044 ms
--- 192.168.10.164 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.044/0.088/0.132 ms
在容器中ping宿主机所在网络的网关IP地址
/ # ping -c 2 192.168.10.2
PING 192.168.10.2 (192.168.10.2): 56 data bytes
64 bytes from 192.168.10.2: seq=0 ttl=127 time=0.338 ms
64 bytes from 192.168.10.2: seq=1 ttl=127 time=0.280 ms
--- 192.168.10.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.280/0.309/0.338 ms
在容器中ping宿主机所在网络中的其它主机IP地址
/ # ping -c 2 192.168.10.165
PING 192.168.10.165 (192.168.10.165): 56 data bytes
64 bytes from 192.168.10.165: seq=0 ttl=63 time=0.422 ms
64 bytes from 192.168.10.165: seq=1 ttl=63 time=0.908 ms
--- 192.168.10.165 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.422/0.665/0.908 ms
~~~
~~~powershell
在容器中开启httpd服务
/ # echo "containerd net web test" > /tmp/index.html
/ # httpd -h /tmp
/ # wget -O - -q 127.0.0.1
containerd net web test
/ # exit
~~~
~~~powershell
在宿主机访问容器提供的httpd服务
[root@localhost scripts]# curl http://10.66.0.3
containerd net web test
~~~
# 八、Containerd容器数据持久化存储
> 实现把宿主机目录挂载至Containerd容器中,实现容器数据持久化存储
~~~powershell
# ctr container create docker.io/library/busybox:latest busybox3 --mount type=bind,src=/tmp,dst=/hostdir,options=rbind:rw
~~~
~~~powershell
说明:
创建一个静态容器,实现宿主机目录与容器挂载
src=/tmp 为宿主机目录
dst=/hostdir 为容器中目录
~~~
~~~powershell
运行用户进程
# ctr tasks start -d busybox3 bash
~~~
~~~powershell
进入容器,查看是否挂载成功
# ctr tasks exec --exec-id $RANDOM -t busybox3 sh
/ # ls /hostdir
VMwareDnD
systemd-private-cf1fe70805214c80867e7eb62dff5be7-bolt.service-MWV1Ju
systemd-private-cf1fe70805214c80867e7eb62dff5be7-chronyd.service-6B6j8p
systemd-private-cf1fe70805214c80867e7eb62dff5be7-colord.service-6fI31A
systemd-private-cf1fe70805214c80867e7eb62dff5be7-cups.service-tuK4zI
systemd-private-cf1fe70805214c80867e7eb62dff5be7-rtkit-daemon.service-vhP67o
tracker-extract-files.0
vmware-root_703-3988031936
vmware-root_704-2990744159
vmware-root_713-4290166671
向容器中挂载目录中添加文件
/ # echo "hello world" > /hostdir/test.txt
退出容器
/ # exit
在宿主机上查看被容器挂载的目录中是否添加了新的文件,已添加表明被容器挂载成功,并可以读写此目录中内容。
[root@localhost ~]# cat /tmp/test.txt
hello world
~~~
# 九、与其它Containerd容器共享命名空间
> 当需要与其它Containerd管理的容器共享命名空间时,可使用如下方法。
~~~powershell
# ctr tasks ls
TASK PID STATUS
busybox3 13778 RUNNING
busybox 8377 RUNNING
busybox1 12469 RUNNING
~~~
~~~powershell
# ctr container create --with-ns "pid:/proc/13778/ns/pid" docker.io/library/busybox:latest busybox4
[root@localhost ~]# ctr tasks start -d busybox4 bash
[root@localhost ~]# ctr tasks exec --exec-id $RANDOM -t busybox3 sh
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 sh
20 root 0:00 sh
26 root 0:00 sh
32 root 0:00 ps aux
~~~
# 十、Docker集成Containerd实现容器管理
目前Containerd主要任务还在于解决容器运行时的问题,对于其周边生态还不完善,所以可以借助Docker结合Containerd来实现Docker完整的功能应用。
~~~powershell
准备Docker安装YUM源
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
~~~
~~~powershell
安装Docker-ce
# yum -y install docker-ce
~~~
~~~powershell
修改Docker服务文件,以便使用已安装的containerd。
# vim /etc/systemd/system/multi-user.target.wants/docker.service
修改前:
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 此处
ExecReload=/bin/kill -s HUP $MAINPID
修改后:
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --containerd /run/containerd/containerd.sock --debug 此处
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
~~~
~~~powershell
设置docker daemon启动并设置其开机自启动
# systemctl daemon-reload
# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
# systemctl start docker
~~~
~~~powershell
查看其启动后进程
# ps aux | grep docker
root 16270 0.0 3.1 1155116 63320 ? Ssl 12:09 0:00 /usr/bin/dockerd --containerd /run/containerd/containerd.sock --debug
~~~
~~~powershell
使用docker运行容器
# docker run -d nginx:latest
......
219a9c6727bcd162d0a4868746c513a277276a110f47e15368b4229988003c13
~~~
~~~powershell
使用docker ps命令查看正在运行的容器
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
219a9c6727bc nginx:latest "/docker-entrypoint.…" 14 seconds ago Up 13 seconds 80/tcp happy_tu
~~~
~~~powershell
使用ctr查看是否添加一个新的namespace,本案例中发现添加一个moby命名空间,即为docker使用的命名空间。
# ctr namespace ls
NAME LABELS
default
k8s.io
kubemsb
moby
~~~
~~~powershell
查看moby命名空间,发现使用docker run运行的容器包含在其中。
# ctr -n moby container ls
CONTAINER IMAGE RUNTIME
219a9c6727bcd162d0a4868746c513a277276a110f47e15368b4229988003c13 - io.containerd.runc.v2
~~~
~~~powershell
使用ctr能够查看到一个正在运行的容器,既表示docker run运行的容器是被containerd管理的。
# ctr -n moby tasks ls
TASK PID STATUS
219a9c6727bcd162d0a4868746c513a277276a110f47e15368b4229988003c13 16719 RUNNING
~~~
~~~powershell
使用docker stop停止且使用docker rm删除容器后再观察,发现容器被删除。
# docker stop 219;docker rm 219
219
219
# ctr -n moby container ls
CONTAINER IMAGE RUNTIME
# ctr -n moby tasks ls
TASK PID STATUS
~~~
================================================
FILE: docs/cloud/docker/docker_container_enterprice.md
================================================
# Docker容器化部署企业级应用集群
# 一、Docker容器化部署企业级应用
## 1.1 使用Docker容器化部署企业级应用必要性
- 有利于快速实现企业级应用部署
- 有利于快速实现企业级应用恢复
## 1.2 使用Docker容器化部署企业级应用参考资料

# 二、使用Docker容器实现Nginx部署
## 2.1 获取参考资料



## 2.2 运行Nginx应用容器
> 不在docker host暴露端口
~~~powershell
# docker run -d --name nginx-server -v /opt/nginx-server:/usr/share/nginx/html:ro nginx
664cd1bbda4ad2a71cbd09f0c6baa9b34db80db2d69496670a960be07b9521cb
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
664cd1bbda4a nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 80/tcp nginx-server
~~~
~~~powershell
# docker inspect 664 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
~~~
~~~powershell
# curl http://172.17.0.3
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.21.6</center>
</body>
</html>
~~~
~~~powershell
# ls /opt
nginx-server
# echo "nginx is working" > /opt/nginx-server/index.html
~~~
~~~powershell
# curl http://172.17.0.3
nginx is working
~~~
## 2.3 运行Nginx应用容器
>在docker host暴露80端口
~~~powershell
# docker run -d -p 80:80 --name nginx-server-port -v /opt/nginx-server-port:/usr/share/nginx/html:ro nginx
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
74dddf51983d nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp nginx-server-port
~~~
~~~powershell
# ls /opt
nginx-server nginx-server-port
~~~
~~~powershell
# echo "nginx is running" > /opt/nginx-server-port/index.html
~~~
**在宿主机上访问**

~~~powershell
# docker top nginx-server-port
UID PID PPID C STIME TTY TIME CMD
root 22195 22163 0 15:08 ? 00:00:00 nginx: master process nginx -g daemon off;
101 22387 22195 0 15:08 ? 00:00:00 nginx: worker process
~~~
## 2.4 运行Nginx应用容器
> 挂载配置文件,需要创建一个nginx容器,把配置文件复制出来修改后使用。
~~~powershell
# docker cp nginxwebcontainername:/etc/nginx/nginx.conf /opt/nginxcon/
修改后即可使用
~~~
~~~powershell
# ls /opt/nginxcon/nginx.conf
/opt/nginxcon/nginx.conf
~~~
~~~powershell
# docker run -d \
-p 82:80 --name nginx-server-conf \
-v /opt/nginx-server-conf:/usr/share/nginx/html:ro \
-v /opt/nginxcon/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx
76251ec44e5049445399303944fc96eb8161ccb49e27b673b99cb2492009523c
~~~
~~~powershell
# docker top nginx-server-conf
UID PID PPID C STIME TTY TIME CMD
root 25005 24972 0 15:38 ? 00:00:00 nginx: master process nginx -g daemon off;
101 25178 25005 0 15:38 ? 00:00:00 nginx: worker process
101 25179 25005 0 15:38 ? 00:00:00 nginx: worker process
~~~
# 三、使用Docker容器实现Tomcat部署
## 3.1 获取参考资料



## 3.2 运行tomcat应用容器
### 3.2.1 不暴露端口运行
~~~powershell
# docker run -d --rm tomcat:9.0
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c20a0e781246 tomcat:9.0 "catalina.sh run" 27 seconds ago Up 25 seconds 8080/tcp heuristic_cori
~~~
### 3.2.2 暴露端口运行
~~~powershell
# docker run -d -p 8080:8080 --rm tomcat:9.0
2fcf5762314373c824928490b871138a01a94abedd7e6814ad5f361d09fbe1de
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2fcf57623143 tomcat:9.0 "catalina.sh run" 3 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp eloquent_chatelet
~~~
**在宿主机访问**

~~~powershell
# docker exec 2fc ls /usr/local/tomcat/webapps
里面为空,所以可以添加网站文件。
~~~
### 3.2.3 暴露端口及添加网站文件
~~~powershell
# docker run -d -p 8081:8080 -v /opt/tomcat-server:/usr/local/tomcat/webapps/ROOT tomcat:9.0
f456e705d48fc603b7243a435f0edd6284558c194e105d87befff2dccddc0b63
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f456e705d48f tomcat:9.0 "catalina.sh run" 3 seconds ago Up 2 seconds 0.0.0.0:8081->8080/tcp, :::8081->8080/tcp cool_germain
~~~
~~~powershell
# echo "tomcat running" > /opt/tomcat-server/index.html
~~~
**在宿主机访问**

# 四、使用Docker容器实现MySQL部署
## 4.1 单节点MySQL部署



~~~powershell
# docker run -p 3306:3306 \
--name mysql \
-v /opt/mysql/log:/var/log/mysql \
-v /opt/mysql/data:/var/lib/mysql \
-v /opt/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d \
mysql:5.7
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d16ca21cf31 mysql:5.7 "docker-entrypoint.s…" 32 seconds ago Up 30 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
~~~
~~~powershell
通过容器中客户端访问
# docker exec -it mysql mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.37 MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
~~~
~~~powershell
在docker host上访问
# yum -y install mariadb
# mysql -h 192.168.255.157 -uroot -proot -P 3306
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.37 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
~~~
## 4.2 MySQL主从复制集群部署
### 4.2.1 MySQL主节点部署
~~~powershell
# docker run -p 3306:3306 \
--name mysql-master \
-v /opt/mysql-master/log:/var/log/mysql \
-v /opt/mysql-master/data:/var/lib/mysql \
-v /opt/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2dbbed8e35c7 mysql:5.7 "docker-entrypoint.s…" 58 seconds ago Up 57 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-master
~~~
### 4.2.2 MySQL主节点配置
~~~powershell
# vim /opt/mysql-master/conf/my.cnf
# cat /opt/mysql-master/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
server_id=1
log-bin=mysql-bin
read-only=0
binlog-do-db=kubemsb_test
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
~~~
### 4.2.3 MySQL从节点部署
~~~powershell
# docker run -p 3307:3306 \
--name mysql-slave \
-v /opt/mysql-slave/log:/var/log/mysql \
-v /opt/mysql-slave/data:/var/lib/mysql \
-v /opt/mysql-slave/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d
--link mysql-master:mysql-master
mysql:5.7
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
caf7bf3fc68f mysql:5.7 "docker-entrypoint.s…" 8 seconds ago Up 6 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp mysql-slave
~~~
### 4.2.4 MySQL从节点配置
~~~powershell
# vim /opt/mysql-slave/conf/my.cnf
# cat /opt/mysql-slave/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=kubemsb_test
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
~~~
### 4.2.5 master节点配置
~~~powershell
# mysql -h 192.168.255.157 -uroot -proot -P 3306
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.37 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
~~~
~~~powershell
授权
MySQL [(none)]> grant replication slave on *.* to 'backup'@'%' identified by '123456';
~~~
~~~powershell
重启容器,使用配置生效
# docker restart mysql-master
~~~
~~~powershell
查看状态
MySQL [(none)]> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 154
Binlog_Do_DB: kubemsb_test
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
~~~
### 4.2.6 slave节点配置
~~~powershell
# docker restart mysql-slave
~~~
~~~powershell
# mysql -h 192.168.255.157 -uroot -proot -P 3307
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.37 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
~~~
~~~powershell
MySQL [(none)]> change master to master_host='mysql-master', master_user='backup', master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=154, master_port=3306;
~~~
~~~powershell
MySQL [(none)]> start slave;
~~~
~~~powershell
MySQL [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: mysql-master
Master_User: backup
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: e0872f94c377-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 154
Relay_Log_Space: 534
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 0130b415-8b21-11ec-8982-0242ac110002
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
~~~
### 4.2.7 验证MySQL集群可用性
~~~powershell
在MySQL Master节点添加kubemsb_test数据库
# mysql -h 192.168.255.157 -uroot -proot -P3306
MySQL [(none)]> create database kubemsb_test;
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| kubemsb_test | |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
~~~
~~~powershell
在MySQL Slave节点查看同步情况
# mysql -h 192.168.255.157 -uroot -proot -P3307
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| kubemsb_test |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
~~~
# 五、使用Docker容器实现Oracle部署
## 5.1 获取参考资料


## 5.2 运行oracle容器
~~~powershell
# docker pull oracleinanutshell/oracle-xe-11g
~~~
~~~powershell
# docker run -h oracle --name oracle -d -p 49160:22 -p 49161:1521 -p 49162:8080 oracleinanutshell/oracle-xe-11g
237db949020abf2cee12e3193fa8a34d9dfadaafd9d5604564668d4472abe0b2
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
237db949020a oracleinanutshell/oracle-xe-11g "/bin/sh -c '/usr/sb…" 7 seconds ago Up 4 seconds 0.0.0.0:49160->22/tcp, :::49160->22/tcp, 0.0.0.0:49161->1521/tcp, :::49161->1521/tcp, 0.0.0.0:49162->8080/tcp, :::49162->8080/tcp oracle
~~~
~~~powershell
说明:
49160 为ssh端口
49161 为sqlplus端口
49162 为oem端口
~~~
~~~powershell
oracle数据库连接信息
port:49161
sid:xe
username:system
password:oracle
SYS用户密码为:oracle
~~~
## 5.3 下载客户端连接工具
下载链接地址:https://www.oracle.com/tools/downloads/sqldev-downloads.html










# 六、使用Docker容器实现ElasticSearch+Kibana部署
## 6.1 获取参考资料
### 6.1.1 ES部署参考资料




### 6.1.2 Kibana部署参考资料




## 6.2 ES部署
~~~powershell
# docker pull elasticsearch:7.17.0
~~~
~~~powershell
# mkdir -p /opt/es/config
# mkdir -p /opt/es/data
~~~
~~~powershell
# echo "http.host: 0.0.0.0" >> /opt/es/config/elasticsearch.yml
~~~
~~~powershell
# chmod -R 777 /opt/es/
~~~
~~~powershell
# docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /opt/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /opt/es/data:/usr/share/elasticsearch/data \
-v /opt/es/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.17.0
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e1c306e6e5a3 elasticsearch:7.17.0 "/bin/tini -- /usr/l…" 22 seconds ago Up 20 seconds 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch
~~~

## 6.3 Kibana部署
~~~powershell
# docker pull kibana:7.17.0
~~~
~~~powershell
# docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.255.157:9200 -p 5601:5601 \
-d kibana:7.17.0
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fb60e73f9cd5 kibana:7.17.0 "/bin/tini -- /usr/l…" 2 minutes ago Up 2 minutes 0.0.0.0:5601->5601/tcp, :::5601->5601/tcp kibana
~~~

# 七、使用Docker容器实现Redis部署
## 7.1 获取参考资料




## 7.2 运行Redis容器
~~~powershell
# mkdir -p /opt/redis/conf
~~~
~~~powershell
# touch /opt/redis/conf/redis.conf
~~~
~~~powershell
# docker run -p 6379:6379 --name redis -v /opt/redis/data:/data \
-v /opt/redis/conf:/etc/redis \
-d redis redis-server /etc/redis/redis.conf
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9bd2b39cd92a redis "docker-entrypoint.s…" 44 seconds ago Up 42 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
~~~
## 7.3 验证
~~~powershell
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
~~~
~~~powershell
# yum -y install redis
~~~
~~~powershell
# redis-cli -h 192.168.255.157 -p 6379
192.168.255.157:6379> set test1 a
OK
192.168.255.157:6379> get test1
"a"
~~~
## 7.4 Redis集群
安装redis-cluster;3主3从方式,从为了同步备份,主进行slot数据分片
~~~powershell
编辑运行多个redis容器脚本文件
# vim redis-cluster.sh
# cat redis-cluster.sh
for port in $(seq 8001 8006); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port ${port}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.255.157
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
appendonly yes
EOF
docker run -p ${port}:${port} -p 1${port}:1${port} --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d redis:5.0.7 redis-server /etc/redis/redis.conf; \
done
~~~
~~~powershell
执行脚本
# sh redis-cluster.sh
~~~
~~~powershell
查看已运行容器
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d53864a98ce redis:5.0.7 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:8006->8006/tcp, :::8006->8006/tcp, 6379/tcp, 0.0.0.0:18006->18006/tcp, :::18006->18006/tcp redis-8006
e2b5da0f0605 redis:5.0.7 "docker-entrypoint.s…" 2 minutes ago Up About a minute 0.0.0.0:8005->8005/tcp, :::8005->8005/tcp, 6379/tcp, 0.0.0.0:18005->18005/tcp, :::18005->18005/tcp redis-8005
70e8e8f15aea redis:5.0.7 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:8004->8004/tcp, :::8004->8004/tcp, 6379/tcp, 0.0.0.0:18004->18004/tcp, :::18004->18004/tcp redis-8004
dff8e4bf02b4 redis:5.0.7 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:8003->8003/tcp, :::8003->8003/tcp, 6379/tcp, 0.0.0.0:18003->18003/tcp, :::18003->18003/tcp redis-8003
c34dc4c423ef redis:5.0.7 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:8002->8002/tcp, :::8002->8002/tcp, 6379/tcp, 0.0.0.0:18002->18002/tcp, :::18002->18002/tcp redis-8002
b8cb5feffb43 redis:5.0.7 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:8001->8001/tcp, :::8001->8001/tcp, 6379/tcp, 0.0.0.0:18001->18001/tcp, :::18001->18001/tcp redis-8001
~~~
~~~powershell
登录redis容器
# docker exec -it redis-8001 bash
root@b8cb5feffb43:/data#
~~~
~~~powershell
创建redis-cluster
root@b8cb5feffb43:/data# redis-cli --cluster create 192.168.255.157:8001 192.168.255.157:8002 192.168.255.157:8003 192.168.255.157:8004 192.168.255.157:8005 192.168.255.157:8006 --cluster-replicas 1
~~~
~~~powershell
输出:
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.255.157:8005 to 192.168.255.157:8001
Adding replica 192.168.255.157:8006 to 192.168.255.157:8002
Adding replica 192.168.255.157:8004 to 192.168.255.157:8003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: abd07f1a2679fe77558bad3ff4b7ab70ec41efa5 192.168.255.157:8001
slots:[0-5460] (5461 slots) master
M: 40e69202bb3eab13a8157c33da6240bb31f2fd6f 192.168.255.157:8002
slots:[5461-10922] (5462 slots) master
M: 9a927abf3c2982ba9ffdb29176fc8ffa77a2cf03 192.168.255.157:8003
slots:[10923-16383] (5461 slots) master
S: 81d0a4056328830a555fcd75cf523d4c9d52205c 192.168.255.157:8004
replicates 9a927abf3c2982ba9ffdb29176fc8ffa77a2cf03
S: 8121a28519e5b52e4817913aa3969d9431bb68af 192.168.255.157:8005
replicates abd07f1a2679fe77558bad3ff4b7ab70ec41efa5
S: 3a8dd5343c0b8f5580bc44f6b3bb5b4371d4dde5 192.168.255.157:8006
replicates 40e69202bb3eab13a8157c33da6240bb31f2fd6f
Can I set the above configuration? (type 'yes' to accept): yes 输入yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.....
>>> Performing Cluster Check (using node 192.168.255.157:8001)
M: abd07f1a2679fe77558bad3ff4b7ab70ec41efa5 192.168.255.157:8001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 81d0a4056328830a555fcd75cf523d4c9d52205c 192.168.255.157:8004
slots: (0 slots) slave
replicates 9a927abf3c2982ba9ffdb29176fc8ffa77a2cf03
M: 40e69202bb3eab13a8157c33da6240bb31f2fd6f 192.168.255.157:8002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 8121a28519e5b52e4817913aa3969d9431bb68af 192.168.255.157:8005
slots: (0 slots) slave
replicates abd07f1a2679fe77558bad3ff4b7ab70ec41efa5
M: 9a927abf3c2982ba9ffdb29176fc8ffa77a2cf03 192.168.255.157:8003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 3a8dd5343c0b8f5580bc44f6b3bb5b4371d4dde5 192.168.255.157:8006
slots: (0 slots) slave
replicates 40e69202bb3eab13a8157c33da6240bb31f2fd6f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
~~~
# 八、使用Docker容器实现RabbitMQ部署
## 8.1 获取参考资料




## 8.2 部署RabbitMQ
> 部署带管理控制台的RabbitMQ
~~~powershell
# docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 -v /opt/rabbitmq:/var/lib/rabbitmq rabbitmq:management
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
97d28093faa4 rabbitmq:management "docker-entrypoint.s…" 11 seconds ago Up 6 seconds 0.0.0.0:4369->4369/tcp, :::4369->4369/tcp, 0.0.0.0:5671-5672->5671-5672/tcp, :::5671-5672->5671-5672/tcp, 0.0.0.0:15671-15672->15671-15672/tcp, :::15671-15672->15671-15672/tcp, 0.0.0.0:25672->25672/tcp, :::25672->25672/tcp, 15691-15692/tcp rabbitmq
~~~
~~~powershell
端口说明:
4369, 25672 (Erlang发现&集群端口)
5672, 5671 (AMQP端口)
15672 (web管理后台端口)
61613, 61614 (STOMP协议端口)
1883, 8883 (MQTT协议端口)
~~~



================================================
FILE: docs/cloud/docker/docker_date.md
================================================
# Docker容器数据持久化存储机制
# 一、Docker容器数据持久化存储介绍
- 物理机或虚拟机数据持久化存储
- 由于物理机或虚拟机本身就拥有大容量的磁盘,所以可以直接把数据存储在物理机或虚拟机本地文件系统中,亦或者也可以通过使用额外的存储系统(NFS、GlusterFS、Ceph等)来完成数据持久化存储。
- Docker容器数据持久化存储
- 由于Docker容器是由容器镜像生成的,所以一般容器镜像中包含什么文件或目录,在容器启动后,我们依旧可以看到相同的文件或目录。
- 由于Docker容器属于“用后即焚”型计算资源,因此Docker容器不适合做数据持久化存储
# 二、Docker容器数据持久化存储方式
Docker提供三种方式将数据从宿主机挂载到容器中:
- docker run -v
- 运行容器时,直接挂载本地目录至容器中
- volumes
- Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)
- 是Docker默认存储数据方式
- bind mounts
- 将宿主机上的任意位置文件或目录挂载到容器中
# 三、Docker容器数据持久化存储方式应用案例演示
## 3.1 docker run -v
### 3.1.1 未挂载本地目录
~~~powershell
运行一个容器,未挂载本地目录
# docker run -d --name web1 nginx:latest
~~~
~~~powershell
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c4ad9f2c15fa nginx:latest "/docker-entrypoint.…" 46 seconds ago Up 44 seconds 80/tcp web1
~~~
~~~powershell
使用curl命令访问容器
# curl http://172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>
~~~
~~~powershell
查看容器中/usr/share/nginx/html目录中目录或子目录
# docker exec web ls /usr/share/nginx/html
50x.html
index.html
~~~
### 3.1.2 挂载本地目录
~~~powershell
创建本地目录
# mkdir /opt/wwwroot
~~~
~~~powershell
向本地目录中添加index.html文件
# echo 'kubemsb' > /opt/wwwroot/index.html
~~~
~~~powershell
运行web2容器,把/opt/wwwroot目录挂载到/usr/share/nginx/html目录中
# docker run -d --name web2 -v /opt/wwwroot/:/usr/share/nginx/html/ nginx:latest
~~~
~~~powershell
查看容器IP地址
# docker inspect web2
......
"IPAddress": "172.17.0.3",
......
~~~
~~~powershell
使用curl命令访问容器
# curl http://172.17.0.3
kubemsb
~~~
### 3.1.3 未创建本地目录
~~~powershell
运行web3容器,挂载未创建的本地目录,启动容器时将自动创建本地目录
# docker run -d --name web3 -v /opt/web3root/:/usr/share/nginx/html/ nginx:latest
~~~
~~~powershell
往自动创建的目录中添加一个index.html文件
# echo "kubemsb web3" > /opt/web3root/index.html
~~~
~~~powershell
在容器中执行查看文件命令
# docker exec web3 cat /usr/share/nginx/html/index.html
kubemsb web3
~~~
## 3.2 volumes
### 3.2.1 创建数据卷
~~~powershell
创建一个名称为nginx-vol的数据卷
# docker volume create nginx-vol
nginx-vol
~~~
~~~powershell
确认数据卷创建后的位置
# ls /var/lib/docker/volumes/
backingFsBlockDev metadata.db nginx-vol
~~~
~~~powershell
查看已经创建数据卷
# docker volume ls
DRIVER VOLUME NAME
local nginx-vol
~~~
~~~powershell
查看数据卷详细信息
# docker volume inspect nginx-vol
[
{
"CreatedAt": "2022-02-08T14:36:16+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data",
"Name": "nginx-vol",
"Options": {},
"Scope": "local"
}
]
~~~
### 3.2.2 使用数据卷
~~~powershell
运行web4容器,使用--mount选项,实现数据卷挂载
# docker run -d --name web4 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx:latest
~~~
或
~~~powershell
运行web4容器,使用-v选项,实现数据卷挂载
# docker run -d --name web4 -v nginx-vol:/usr/share/nginx/html/ nginx:latest
~~~
~~~powershell
查看容器运行后数据卷中文件或子目录
# ls /var/lib/docker/volumes/nginx-vol/_data/
50x.html index.html
~~~
~~~powershell
使用curl命令访问容器
# curl http://172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>
~~~
~~~powershell
修改index.html文件内容
# echo "web4" > /var/lib/docker/volumes/nginx-vol/_data/index.html
~~~
~~~powershell
再次使用curl命令访问容器
# curl http://172.17.0.2
web4
~~~
## 3.3 bind mounts
~~~powershell
创建用于容器挂载的目录web5root
# mkdir /opt/web5root
~~~
~~~powershell
运行web5容器并使用bind mount方法实现本地任意目录挂载
# docker run -d --name web5 --mount type=bind,src=/opt/web5root,dst=/usr/share/nginx/html nginx:latest
~~~
~~~powershell
查看已挂载目录,里面没有任何数据
# ls /opt/web5root/
~~~
~~~powershell
添加内容至/opt/web5root/index.html中
# echo "web5" > /opt/web5root/index.html
~~~
~~~powershell
使用curl命令访问容器
# curl http://172.17.0.3
web5
~~~
================================================
FILE: docs/cloud/docker/docker_devops.md
================================================
# 基于Docker容器DevOps应用方案 企业业务代码发布系统
# 一、企业业务代码发布方式
## 1.1 传统方式
- 以物理机或虚拟机为颗粒度部署
- 部署环境比较复杂,需要有先进的自动化运维手段
- 出现问题后重新部署成本大,一般采用集群方式部署
- 部署后以静态方式展现
## 1.2 容器化方式
- 以容器为颗粒度部署
- 部署方式简单,启动速度快
- 一次构建可到处运行
- 出现故障后,可随时恢复
- 可同时部署多套环境(测试、预发布、生产环境等)
# 二、企业业务代码发布逻辑图

# 三、企业业务代码发布工具及流程图
## 3.1 工具
| 序号 | 工具 | 工具用途 |
| ---- | ------- | ------------------------------------------------------------ |
| 1 | git | 用于提交业务代码或克隆业务代码仓库 |
| 2 | gitlab | 用于存储业务代码 |
| 3 | jenkins | 用于利用插件完成业务代码编译、构建、推送至Harbor容器镜像仓库及项目部署 |
| 4 | tomcat | 用于运行JAVA业务代码 |
| 5 | maven | 用于编译业务代码 |
| 6 | harbor | 用于存储业务代码构建的容器镜像存储 |
| 7 | docker | 用于构建容器镜像,部署项目 |
## 3.2 流程图
> 本次部署Java代码包。

# 四、企业业务代码发布系统环境部署
## 4.1 主机规划
| 序号 | 主机名 | 主机IP | 主机功能 | 软件 |
| ---- | -------------- | ------------- | ---------------------------- | -------------------- |
| 1 | dev | 192.168.10.20 | 开发者 项目代码 solo | git |
| 2 | gitlab-server | 192.168.10.21 | 代码仓库 | gitlab-ce |
| 3 | jenkins-server | 192.168.10.22 | 编译代码、打包镜像、项目发布 | jenkins、docker、git |
| 4 | harbor-server | 192.168.10.23 | 存储容器镜像 | harbor、docker |
| 5 | web-server | 192.168.10.24 | 运行容器,项目上线 | docker |
## 4.2 主机准备
### 4.2.1 主机名配置
~~~powershell
# hostnamectl set-hostname xxx
~~~
> 根据主机规划实施配置
### 4.2.2 主机IP地址配置
~~~powershell
# vim /etc/sysconfig/network-scripts/ifcfg-ens33
# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="none" 配置为静态IP
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="ec87533a-8151-4aa0-9d0f-1e970affcdc6"
DEVICE="ens33"
ONBOOT="yes"
IPADDR="192.168.10.2x" 把2x替换为对应的IP地址
PREFIX="24"
GATEWAY="192.168.10.2"
DNS1="119.29.29.29"
~~~
### 4.2.3 主机名与IP地址解析配置
~~~powershell
# vim /etc/hosts
# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.20 dev
192.168.10.21 gitlab-server
192.168.10.22 jenkins-server
192.168.10.23 harobr-server
192.168.10.24 web-server
~~~
### 4.2.4 主机安全设置
~~~powershell
# systemctl stop firewalld;systemctl disable firewalld
~~~
~~~powershell
# firewall-cmd --state
~~~
~~~powershell
# sestatus
~~~
### 4.2.5 主机时间同步
~~~powershell
# crontab -e
# crotab -l
0 */1 * * * ntpdate time1.aliyun.com
~~~
## 4.3 主机中工具安装
### 4.3.1 dev主机
>下载项目及上传代码至代码仓库
~~~powershell
# yum -y install git
~~~
### 4.3.2 gitlab-server主机
#### 4.3.2.1 获取YUM源




~~~powershell
# cat /etc/yum.repos.d/gitlab.repo
[gitlab]
name=gitlab-ce
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7
enabled=1
gpgcheck=0
~~~
#### 4.3.2.2 gitlab-ce安装
~~~powershell
# yum -y install gitlab-ce
~~~
#### 4.3.2.3 gitlab-ce配置
~~~powershell
# vim /etc/gitlab/gitlab.rb
32 external_url 'http://192.168.10.21'
~~~
#### 4.3.2.4 启动gitlab-ce
~~~powershell
# gitlab-ctl reconfigure
~~~
~~~powershell
# gitlab-ctl status
~~~
#### 4.3.2.5 访问gitlab-ce
~~~powershell
# cat /etc/gitlab/initial_root_password
......
Password: znS4Bqlp0cfYUKg2dHzFiNCAN0GnhtnD4ENjEtEXMVE=
~~~


### 4.3.3 jenkins-server主机
#### 4.3.3.1 jdk安装
~~~powershell
# ls
jdk-8u191-linux-x64.tar.gz
~~~
~~~powershell
# mv jdk1.8.0_191 /usr/local/jdk
~~~
~~~powershell
# vim /etc/profile
# cat /etc/profile
......
export JAVA_HOME=/usr/local/jdk
export PATH=${JAVA_HOME}/bin:$PATH
~~~
~~~powershell
# source /etc/profile
~~~
~~~powershell
# java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
~~~
#### 4.3.3.2 jenkins安装
##### 4.3.3.2.1 安装



~~~powershell
# wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
~~~
~~~powershell
# rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
~~~

~~~powershell
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
~~~
~~~powershell
# yum -y install jenkins
~~~
##### 4.3.3.2.2 jenkins配置
~~~powershell
# vim /etc/init.d/jenkins
在81行下面添加如下内容:
82 /usr/local/jdk/bin/java
~~~
~~~powershell
# vim /etc/sysconfig/jenkins
在19行双引号中添加jdk中java命令路径
19 JENKINS_JAVA_CMD="/usr/local/jdk/bin/java"
~~~
##### 4.3.3.2.3 jenkins启动
~~~powershell
# chkconfig --list
注:该输出结果只显示 SysV 服务,并不包含
原生 systemd 服务。SysV 配置数据
可能被原生 systemd 配置覆盖。
要列出 systemd 服务,请执行 'systemctl list-unit-files'。
查看在具体 target 启用的服务请执行
'systemctl list-dependencies [target]'。
jenkins 0:关 1:关 2:开 3:开 4:开 5:开 6:关
netconsole 0:关 1:关 2:关 3:关 4:关 5:关 6:关
network 0:关 1:关 2:开 3:开 4:开 5:开 6:关
# chkconfig jenkins on
~~~
~~~powershell
# systemctl start jenkins
~~~
##### 4.3.3.2.4 jenkins访问
~~~powershell
# cat /var/lib/jenkins/secrets/initialAdminPassword
3363d658a1a5481bbe51a1ece1eb08ab
~~~

##### 4.3.3.2.5 jenkins初始化配置







#### 4.3.3.3 git安装
~~~powershell
# yum -y install git
~~~
#### 4.3.3.4 maven安装
##### 4.3.3.4.1 获取maven安装包


~~~powershell
# wget https://dlcdn.apache.org/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz
~~~
##### 4.3.3.4.2 maven安装
~~~powershell
# ls
apache-maven-3.8.4-bin.tar.gz
~~~
~~~powershell
# tar xf apache-maven-3.8.4-bin.tar.gz
# ls
apache-maven-3.8.4
~~~
~~~powershell
# mv apache-maven-3.8.4 /usr/local/mvn
~~~
~~~powershell
# vim /etc/profile
......
export JAVA_HOME=/usr/local/jdk
export MAVEN_HOME=/usr/local/mvn
export PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:$PATH
~~~
~~~powershell
# source /etc/profile
~~~
~~~powershell
# mvn -v
Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)
Maven home: /usr/local/mvn
Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/local/jdk/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.49.1.el7.x86_64", arch: "amd64", family: "unix"
~~~
#### 4.3.3.5 docker安装
~~~powershell
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
~~~
~~~powershell
# yum -y install docker-ce
~~~
~~~powershell
# systemctl enable docker
# systemctl start docker
~~~
### 4.3.4 harbor-server主机
#### 4.3.4.1 docker安装
~~~powershell
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
~~~
~~~powershell
# yum -y install docker-ce
~~~
~~~powershell
# systemctl enable docker
# systemctl start docker
~~~
#### 4.3.4.2 docker-compose安装
##### 4.3.4.2.1 获取docker-compose文件




~~~powershell
# wget https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64
~~~
##### 4.3.4.2.2 docker-compose安装及测试
~~~powershell
# ls
docker-compose-linux-x86_64
~~~
~~~powershell
# chmod +x docker-compose-linux-x86_64
~~~
~~~powershell
# mv docker-compose-linux-x86_64 /usr/bin/docker-compose
~~~
~~~powershell
# docker-compose version
Docker Compose version v2.2.3
~~~
#### 4.3.4.3 harbor部署
##### 4.3.4.3.1 harbor部署文件获取





~~~powershell
# wget https://github.com/goharbor/harbor/releases/download/v2.4.1/harbor-offline-installer-v2.4.1.tgz
~~~
##### 4.3.4.3.2 harbor部署
~~~powershell
# ls
harbor-offline-installer-v2.4.1.tgz
~~~
~~~powershell
# tar xf harbor-offline-installer-v2.4.1.tgz -C /home
~~~
~~~powershell
# cd /home
# ls
harbor
[root@harbor-server home]# cd harbor/
[root@harbor-server harbor]# ls
common.sh harbor.v2.4.1.tar.gz harbor.yml.tmpl install.sh LICENSE prepare
~~~
~~~powershell
# mv harbor.yml.tmpl harbor.yml
~~~
~~~powershell
[root@harbor-server harbor]# vim harbor.yml
[root@harbor-server harbor]# cat harbor.yml
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 192.168.10.23 修改
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 80
# https related config
#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 注释
~~~
~~~powershell
[root@harbor-server harbor]# ./prepare
~~~
~~~powershell
[root@harbor-server harbor]# ./install.sh
~~~
~~~powershell
[root@harbor-server harbor]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
12605eae32bb goharbor/harbor-jobservice:v2.4.1 "/harbor/entrypoint.…" About a minute ago Up About a minute (healthy) harbor-jobservice
85849b46d56d goharbor/nginx-photon:v2.4.1 "nginx -g 'daemon of…" About a minute ago Up About a minute (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp nginx
6a18e370354f goharbor/harbor-core:v2.4.1 "/harbor/entrypoint.…" About a minute ago Up About a minute (healthy) harbor-core
d115229ef49d goharbor/harbor-portal:v2.4.1 "nginx -g 'daemon of…" About a minute ago Up About a minute (healthy) harbor-portal
f5436556dd32 goharbor/harbor-db:v2.4.1 "/docker-entrypoint.…" About a minute ago Up About a minute (healthy) harbor-db
7fb8c4945abe goharbor/harbor-registryctl:v2.4.1 "/home/harbor/start.…" About a minute ago Up About a minute (healthy) registryctl
d073e5da1399 goharbor/redis-photon:v2.4.1 "redis-server /etc/r…" About a minute ago Up About a minute (healthy) redis
7c09362c986b goharbor/registry-photon:v2.4.1 "/home/harbor/entryp…" About a minute ago Up About a minute (healthy) registry
55d7f39909e3 goharbor/harbor-log:v2.4.1 "/bin/sh -c /usr/loc…" About a minute ago Up About a minute (healthy) 127.0.0.1:1514->10514/tcp harbor-log
~~~
### 4.3.5 web-server
> docker安装
~~~powershell
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
~~~
~~~powershell
# yum -y install docker-ce
~~~
~~~powershell
# systemctl enable docker
# systemctl start docker
~~~
## 4.4 工具集成配置
### 4.4.1 配置docker主机使用harbor
#### 4.4.1.1 jenkins-server
~~~powershell
[root@jenkins-server ~]# vim /etc/docker/daemon.json
[root@jenkins-server ~]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.10.23"]
}
~~~
~~~powershell
[root@jenkins-server ~]# systemctl restart docker
~~~
~~~powershell
[root@jenkins-server ~]# docker login 192.168.10.23
Username: admin
Password:
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
~~~
#### 4.4.1.2 harbor-server
~~~powershell
[root@harbor-server harbor]# vim /etc/docker/daemon.json
[root@harbor-server harbor]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.10.23"]
}
~~~
~~~powershell
[root@harbor-server harbor]# docker-compose down
~~~
~~~powershell
[root@harbor-server harbor]# systemctl restart docker
~~~
~~~powershell
[root@harbor-server harbor]# docker-compose up -d
~~~
#### 4.4.1.3 web-server
~~~powershell
[root@web-server ~]# vim /etc/docker/daemon.json
[root@web-server ~]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.10.23"]
}
~~~
~~~powershell
[root@web-server ~]# systemctl restart docker
~~~
~~~powershell
[root@web-server ~]# docker login 192.168.10.23
Username: admin
Password:
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
~~~
### 4.4.2 配置jenkins使用docker
> 在jenkins-server主机上配置
~~~powershell
验证系统中是否有jenkins用户
[root@jenkins-server ~]# grep jenkins /etc/passwd
jenkins:x:997:995:Jenkins Automation Server:/var/lib/jenkins:/bin/false
~~~
~~~powershell
验证系统中是否有docker用户及用户组
[root@jenkins-server ~]# grep docker /etc/group
docker:x:993:
~~~
~~~powershell
添加jenkins用户到docker用户组
[root@jenkins-server ~]# usermod -G docker jenkins
[root@jenkins-server ~]# grep docker /etc/group
docker:x:993:jenkins
~~~
~~~powershell
重启jenkins服务
[root@jenkins-server ~]# systemctl restart jenkins
~~~
### 4.4.3 密钥配置
#### 4.4.3.1 dev主机至gitlab-ce
##### 4.4.3.1.1 dev主机生成密钥对
~~~powershell
[root@dev ~]# ssh-keygen
~~~
##### 4.4.3.1.2 添加公钥至gitlab-ce
~~~powershell
[root@dev ~]# cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy2PdvT9qX55CLZzzaaEf06x8gl3yHGfdJSmAp9L1Fdtcbd3yz3U0lgdOwWpB8fQ/A3HoUUTWCb1iC5WJBOvqkoD8rJ2xC3HJ62zjOjmqcn2fEs09CzJj3bCfahuqPzaPkIOoH42/Y2QdImQ7xZOqqjS7aIc5T2FjDLG3bMhaYFyvx18b1qiPACuh67iniPQnL667MFZ/0QGGVnQKwxop+SezhP9QqV1bvPk94eTdkERIBiY1CNcNmVryk6PzSKY8gfW++3TGN9F+knhMXcswFOu6FzqxcA3G+hYg+Io2HJaDrsfHGZ6CP5T9QiOlIWlNxz05BOK3OFQ5BPeomA+jv root@dev
~~~



#### 4.4.3.2 jenkins-server主机至gitlab-ce
##### 4.4.3.2.1 在jenkins-server生成密钥对
~~~powershell
[root@jenkins-server ~]# ssh-keygen
~~~
##### 4.4.3.2.2 添加公钥至gitlab-ce
~~~powershell
[root@jenkins-server ~]# cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyg3WaEm5yH9yva8Jm5wfTPwN3ROGMNPpAex8zYj+M1GesoMtE6gkiKHWydAJBiLuu/1fBx6HlgzzxghVj9oK4DmTRZQh2IZY4+zZIGBRaDBuBO1f7+SdVE/jZoLd1a+yZ3FQmy37AlXUcIKxbrDBtefvJ31faziWyZKvT4BGFJCznRU6AOxOg1pe4bWbWI+dGnMIIq7IhtK+6tY/w3OlF7xcWmrJP1oucpq33BYOrnRCL9EO5Zp2jcejDeG5UvXONG7CggT7FDhjwcCRZvX+AutDGAtgBckNXZjV9SDKWgDifCSDtDfV4Be4zb8b3hxtSMsbEY8YHxsThsmHrUkbz root@jenkins-server
~~~

#### 4.4.3.3 配置jenkins-sever主机的私钥到凭据列表
~~~powershell
[root@jenkins-server ~]# cat /root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsoN1mhJuch/cr2vCZucH0z8Dd0ThjDT6QHsfM2I/jNRnrKDL
ROoJIih1snQCQYi7rv9Xwceh5YM88YIVY/aCuA5k0WUIdiGWOPs2SBgUWgwbgTtX
+/knVRP42aC3dWvsmdxUJst+wJV1HCCsW6wwbXn7yd9X2s4lsmSr0+ARhSQs50VO
gDsToNaXuG1m1iPnRpzCCKuyIbSvurWP8NzpRe8XFpqyT9aLnKat9wWDq50Qi/RD
uWado3How3huVL1zjRuwoIE+xQ4Y8HAkWb1/gLrQxgLYAXJDV2Y1fUgyloA4nwkg
7Q31eAXuM2/G94cbUjLGxGPGB8bE4bJh61JG8wIDAQABAoIBAEOwy6BPyuelo1Y1
g3LnujTlWRgZ23kCAb7/sPYYFEb/qAxysIGCSVJVi0PO76gQBDM4iftmCsLv/+UI
UbolGK5Ybuxj5lB9LeyPfaba0qTOoINhkFxwvvRo7V0Ar3BsKzywqoxHb9nxEoZG
8XSVl4t7zPlgonzK3MqHmAxwk9QrIB/rnjolHGN6HvfK2Cwq5WN1crspwQ+XDbRS
J5qoAtv6PJzrU6QhJl/zSMCb0MytlIhZi+V+1yY/QhAYrWJgWypEwGlAXlVC90r4
twX1W/sl63xzFF396WjM1478yqpttvID06dKTC9T3y/k8lLmRNXwqmTCIm7C/jxP
9wjXJUECgYEA4r1N4AML7JpvE7hBRkreSdIIwoppRkBwl6gt/AJj8yt2ydQ8PY4P
X3s5ZkCfPzHX2XsVUUcQpsBFcU2PyG29+qzt3XOmlGYgJG11xPQbwi95/u9VSd5u
AuaNNa2YPw2teuM0hKVAl5knfy0+YHcOCdU14gHCCWsD4uOz5Zg9jVMCgYEAyYzv
SBvCqbZ4d5agTn+ZiOkmgKVT4UVnmZPivFXnCWiIbX2fi3ok7jU1hZAs6lf6VlTU
EPV8T1LwjO9yhFmicepzSl9lJCMbMXHt20OsqN0oUQFpoTQ07pbBE2K8c1IuQUEi
B2SoLHqv7Ym9jHQqvT3DVhTiC+H2LwsgVRvvi+ECgYAxaID0xJUvnMOBr5ABykTA
H1WrVs/z8AzY71v942N2VM1Q07/AxhkRfF+YqZJKCgl4KbsOeAbn31QCiZ1AVrGk
U1SOAiqVgd+VMIkOPwdhfEkARZT3QNIGLcktnkNj0g4wjhwen4gAwO37Z5eFG8xi
ViSkuC9ZMAmrwmSsLk2TYwKBgHQh0tYXuMiVLUCq99+DQnJS9S53FKfel900Cxc9
4AvZwZJlKgLx9EmVOyukcVzuKH6KDk9fQ6tpPNXYOoHsK9+7mYanBN4XpFmPLeCD
U/9QvyQ9ziFmtYEsOD/1SmSgW6qZ3wOnigdnAeu6zA8b+GxmJCF7kuwJ3RIqNQ0V
NafBAoGAXyynoTT2zugFq8jYRubxkMk7NdnTRAnGh+mlyrGGMsNLmPvfAw+6yKph
1fVHKXHtSrgtK0CVOIcmaH3r+LfG4Mfrjlq+8qiKcepBFvO9cZLNKn11vqQtzs7m
y+ydl4xTcCPoAMDsVeamJ3fv+9nyXe5KqYtw+BJMjpP+PnNN2YQ=
-----END RSA PRIVATE KEY-----
~~~






## 4.5 jenkins插件安装
### 4.5.1 maven integration
> 用于编译JAVA项目




### 4.5.2 git parameter
> 用于基于git版本提交进行参数构建项目


### 4.5.3 gitlab
> 用于jenkins-server拉取项目


### 4.5.4 Generic Webhook Trigger
> 用于项目自动化构建


### 4.5.5 ssh
> 用于jenkins-server对web-server实施项目部署


## 4.6 jenkins全局工具配置

### 4.6.1 JDK配置
~~~powershell
[root@jenkins-server ~]# java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
[root@jenkins-server ~]# echo $JAVA_HOME
/usr/local/jdk
~~~


### 4.6.2 Git配置
~~~powershell
[root@jenkins-server ~]# git version
git version 1.8.3.1
~~~

### 4.6.3 Maven配置
~~~powershell
[root@jenkins-server ~]# mvn --version
Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)
Maven home: /usr/local/mvn
Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/local/jdk/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.49.1.el7.x86_64", arch: "amd64", family: "unix"
[root@jenkins-server ~]# echo $MAVEN_HOME
/usr/local/mvn
~~~


## 4.7 jenkins系统配置
> 主要配置jenkins-server通过ssh协议连接web-server
### 4.7.1 添加jenkins-server访问web-server凭据





### 4.7.2 配置ssh协议连接主机




# 五、企业业务代码项目发布
## 5.1 数据库管理系统部署 mariadb及创建项目数据库
~~~powershell
[root@web-server ~]# yum -y install mariadb mariadb-server
~~~
~~~powershell
[root@web-server ~]# systemctl enable mariadb
[root@web-server ~]# systemctl start mariadb
~~~
~~~powershell
[root@web-server ~]# mysqladmin -uroot password 'abc123'
~~~
~~~powershell
[root@web-server ~]# mysql -uroot -pabc123
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
~~~
~~~powershell
MariaDB [(none)]> create database if not exists solo default charset utf8 collate utf8_general_ci;
~~~
~~~powershell
MariaDB [(none)]> grant all on solo.* to 'root'@'%' identified by "123456";
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> grant all on solo.* to 'root'@'localhost' identified by "123456";
Query OK, 0 rows affected (0.00 sec)
~~~
## 5.2 项目代码获取

~~~powershell
# git clone --recurse-submodules https://gitee.com/dl88250/solo.git
~~~
## 5.3 项目代码修改
~~~powershell
[root@dev ~]# ls
solo
~~~
~~~powershell
[root@dev ~]# vim solo/src/main/resources/local.properties
[root@dev ~]# cat solo/src/main/resources/local.properties
#
# Solo - A small and beautiful blogging system written in Java.
# Copyright (c) 2010-present, b3log.org
#
# Solo is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
#
#
# Description: Solo local environment configurations.
# Version: 1.1.3.15, Mar 17, 2019
# Author: Liang Ding
#
#### MySQL runtime ####
runtimeDatabase=MYSQL
jdbc.username=root
jdbc.password=123456
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.URL=jdbc:mysql://192.168.10.24:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
#### H2 runtime ####
#runtimeDatabase=H2
#jdbc.username=root
#jdbc.password=
#jdbc.driver=org.h2.Driver
#jdbc.URL=jdbc:h2:~/solo_h2/db;MODE=MYSQL
# The minConnCnt MUST larger or equal to 3
jdbc.minConnCnt=5
jdbc.maxConnCnt=10
# The specific table name prefix
jdbc.tablePrefix=b3_solo
~~~
## 5.4 项目代码上传到gitlab



~~~powershell
# git config --global user.name "dev"
# git config --global user.email "dev@kubemsb.com"
~~~
~~~powershell
[root@dev solo]# git remote remove origin
~~~
~~~powershell
[root@dev solo]# git remote add origin git@192.168.10.21:root/solo.git
~~~
~~~powershell
[root@dev solo]# git add -A .
[root@dev solo]# git commit -m "new"
[master 3e39b0a] new
1 file changed, 1 insertion(+), 1 deletion(-)
~~~
~~~powershell
[root@dev solo]# git tag 1.0.0
~~~
~~~powershell
[root@dev solo]# git push origin 1.0.0
~~~
~~~powershell
[root@dev solo]# git push -u origin --all
~~~

## 5.5 构建项目运行基础应用容器镜像
> 在harbor-server主机上操作
### 5.5.1 创建项目目录
~~~powershell
[root@harbor-server ~]# mkdir tomcatdir
[root@harbor-server ~]# cd tomcatdir
~~~
### 5.5.2 生成Dockerfile文件
~~~powershell
[root@harbor-server tomcatdir]# echo "tomcat is running" >> index.html
~~~
~~~powershell
[root@harbor-server tomcatdir]# vim Dockerfile
[root@harbor-server tomcatdir]# cat Dockerfile
FROM centos:centos7
MAINTAINER "www.kubemsb.com"
ENV VERSION=8.5.75
ENV JAVA_HOME=/usr/local/jdk
ENV TOMCAT_HOME=/usr/local/tomcat
RUN yum -y install wget
RUN wget https://dlcdn.apache.org/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz --no-check-certificate
RUN tar xf apache-tomcat-${VERSION}.tar.gz
RUN mv apache-tomcat-${VERSION} /usr/local/tomcat
RUN rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/*
RUN mkdir /usr/local/tomcat/webapps/ROOT
ADD ./index.html /usr/local/tomcat/webapps/ROOT/
ADD ./jdk /usr/local/jdk
RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile
RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile
RUN echo "export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH" >> /etc/profile
RUN echo "export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" >> /etc/profile
RUN source /etc/profile
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
~~~
~~~powershell
[root@harbor-server tomcatdir]# ls
Dockerfile index.html jdk
~~~
### 5.5.3 使用docker build构建容器镜像
~~~powershell
[root@harbor-server tomcatdir]# docker build -t 192.168.10.23/library/tomcat:8575 .
~~~
### 5.5.4 推送容器镜像至harbor容器镜像仓库
~~~powershell
[root@harbor-server tomcatdir]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.10.23/library/tomcat 8575 01c433f8562d About a minute ago 796MB
~~~
~~~powershell
[root@harbor-server tomcatdir]# docker login 192.168.10.23
Username: admin
Password:
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
~~~
~~~powershell
[root@harbor-server tomcatdir]# docker push 192.168.10.23/library/tomcat:8575
~~~

### 5.5.5 验证容器镜像可用性
~~~powershell
[root@harbor-server ~]# docker run -d 192.168.10.23/library/tomcat:8575
d5443961ca65311ca0d68d53d44be997f5d6fde2d78772173ac6927112f34579
~~~
~~~powershell
[root@harbor-server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d5443961ca65 192.168.10.23/library/tomcat:8575 "/usr/local/tomcat/b…" 3 seconds ago Up 2 seconds 8080/tcp nifty_tesla
~~~
~~~powershell
[root@harbor-server ~]# docker inspect d544
获得:172.17.0.2
~~~
~~~powershell
[root@harbor-server ~]# curl http://172.17.0.2:8080
tomcat is running
~~~
## 5.6 项目构建及发布
### 5.6.1 项目构建及发布步骤
第一步:jenkins获取项目代码
第二步:jenkins对项目代码编译,由maven完成
第三步:jenkins使用docker对编译完成的项目代码进行打包,打包成容器应用镜像
第四步:jenkins把打包的容器应用镜像上传到harbor
第五步:jenkins通过ssh插件完成对web-server进行运行容器应用镜像的操作
### 5.6.2 创建项目任务








~~~powershell
Dockerfile:
REPOSITORY=192.168.10.23/library/solo:${Tag}
# 构建镜像
cat > Dockerfile << EOF
FROM 192.168.10.23/library/tomcat:8575
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY target/*.war /usr/local/tomcat/webapps/ROOT.war
CMD ["/usr/local/tomcat/bin/catalina.sh", "run"]
EOF
docker build -t $REPOSITORY .
# 上传镜像
docker login 192.168.10.23 -u admin -p Harbor12345
docker push $REPOSITORY
docker logout 192.168.10.23
~~~
~~~powershell
shell script:
REPOSITORY=192.168.10.23/library/solo:${Tag}
# 部署
docker rm -f blog-solo |true
docker image rm $REPOSITORY |true
docker container run -d --name blog-solo -p 80:8080 $REPOSITORY
~~~





================================================
FILE: docs/cloud/docker/docker_file.md
================================================
# Dockerfile精讲及新型容器镜像构建技术
# 一、容器与容器镜像之间的关系
说到Docker管理的容器不得不说容器镜像,主要因为容器镜像是容器模板,通过容器镜像我们才能快速创建容器。
如下图所示:

> Docker Daemon通过容器镜像创建容器。
# 二、容器镜像分类
- 操作系统类
- CentOS
- Ubuntu
- 在dockerhub下载或自行制作
- 应用类
- Tomcat
- Nginx
- MySQL
- Redis
# 三、容器镜像获取的方法
主要有以下几种:
1、在DockerHub直接下载
2、把操作系统中文件系统打包为容器镜像
3、把正在运行的容器打包为容器镜像,即docker commit
4、通过Dockerfile实现容器镜像的自定义及生成
# 四、容器镜像获取方法演示
## 4.1 在DockerHub直接下载
~~~powershell
# docker pull centos:latest
~~~
~~~powershell
# docker pull nginx:latest
~~~
## 4.2 把操作系统中文件系统打包为容器镜像
### 4.2.1 安装一个最化的操作系统

### 4.2.2 把操作系统中文件系统进行打包
~~~powershell
# tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7u6.tar /
~~~
### 4.2.3 把打包后文件加载至本地文件系统生成本地容器镜像
~~~powershell
# ls
centos7u6.tar
~~~
~~~powershell
# docker import centos7u6.tar centos7u6:v1
~~~
~~~powershell
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7u6 v1 130cb005b2dc 7 seconds ago 1.09GB
~~~
~~~powershell
# docker run -it centos7u6:v1 bash
[root@50f24f688b4d /]# ip a s
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
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
~~~
## 4.3 把正在运行的容器打包为容器镜像
### 4.3.1 运行一个容器
~~~powershell
# docker run -it centos7u6:v1 bash
~~~
### 4.3.2 在容器中安装应用
~~~powershell
[root@064aace45718 /]# yum -y install httpd
~~~
### 4.3.3 把正在运行的容器打包为容器镜像
~~~powershell
[root@064aace45718 /]# ctrl + p +q
~~~
~~~powershell
# docker commit 064aace45718 centos7u6-httpd:v1
~~~
~~~powershell
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7u6-httpd v1 30ec9d728880 6 seconds ago 1.29GB
~~~
~~~powershell
# docker run -it centos7u6-httpd:v1 bash
[root@01a1373b4a3f /]# rpm -qa | grep httpd
httpd-tools-2.4.6-97.el7.centos.4.x86_64
httpd-2.4.6-97.el7.centos.4.x86_64
~~~
## 4.4 通过Dockerfile实现容器镜像的自定义及生成
### 4.4.1 Dockerfile介绍
Dockerfile是一种能够被Docker程序解释的剧本。Dockerfile由一条一条的指令组成,并且有自己的书写格式和支持的命令。当我们需要在容器镜像中指定自己额外的需求时,只需在Dockerfile上添加或修改指令,然后通过docker build生成我们自定义的容器镜像(image)。

### 4.4.2 Dockerfile指令
- 构建类指令
- 用于构建image
- 其指定的操作不会在运行image的容器上执行(FROM、MAINTAINER、RUN、ENV、ADD、COPY)
- 设置类指令
- 用于设置image的属性
- 其指定的操作将在运行image的容器中执行(CMD、ENTRYPOINT、USER 、EXPOSE、VOLUME、WORKDIR、ONBUILD)
- 指令说明
| 指令 | 描述 |
| ------- | --------------------------------------------------- |
| FROM | 构建新镜像基于的基础镜像 |
| LABEL | 标签 |
| RUN | 构建镜像时运行的Shell命令 |
| COPY | 拷贝文件或目录到镜像中 |
| ADD | 解压压缩包并拷贝 |
| ENV | 设置环境变量 |
| USER | 为RUN、CMD和ENTRYPOINT执行命令指定运行用户 |
| EXPOSE | 声明容器运行的服务端口 |
| WORKDIR | 为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录 |
| CMD | 运行容器时默认执行,如果有多个CMD指令,最后一个生效 |
- 指令详细解释
通过`man docker_file`可以查看到详细的说明,这里简单的翻译并列出常用的指令
1, **FROM**
FROM指令用于指定其后构建新镜像所使用的基础镜像。
FROM指令必是Dockerfile文件中的首条命令。
FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库,优先本地仓库。
```powershell
格式:FROM <image>:<tag>
例:FROM centos:latest
```
2, **RUN**
RUN指令用于在**构建**镜像中执行命令,有以下两种格式:
* shell格式
~~~powershell
格式:RUN <命令>
例:RUN echo 'kubemsb' > /var/www/html/index.html
~~~
* exec格式
~~~powershell
格式:RUN ["可执行文件", "参数1", "参数2"]
例:RUN ["/bin/bash", "-c", "echo kubemsb > /var/www/html/index.html"]
~~~
**注意:** 按优化的角度来讲:当有多条要执行的命令,不要使用多条RUN,尽量使用&&符号与\符号连接成一行。因为多条RUN命令会让镜像建立多层(总之就是会变得臃肿了:smiley:)。
~~~powershell
RUN yum install httpd httpd-devel -y
RUN echo test > /var/www/html/index.html
可以改成
RUN yum install httpd httpd-devel -y && echo test > /var/www/html/index.html
或者改成
RUN yum install httpd httpd-devel -y \
&& echo test > /var/www/html/index.html
~~~
3, **CMD**
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
~~~powershell
格式有三种:
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
~~~
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。
~~~powershell
什么是启动容器时指定运行的命令?
# docker run -d -p 80:80 镜像名 运行的命令
~~~
4, **EXPOSE**
EXPOSE指令用于指定容器在运行时监听的端口
~~~powershell
格式:EXPOSE <port> [<port>...]
例:EXPOSE 80 3306 8080
~~~
上述运行的端口还需要使用docker run运行容器时通过-p参数映射到宿主机的端口.
5, **ENV**
ENV指令用于指定一个环境变量.
~~~powershell
格式:ENV <key> <value> 或者 ENV <key>=<value>
例:ENV JAVA_HOME /usr/local/jdkxxxx/
~~~
6, **ADD**
ADD指令用于把宿主机上的文件拷贝到镜像中
~~~powershell
格式:ADD <src> <dest>
<src>可以是一个本地文件或本地压缩文件,还可以是一个url,
如果把<src>写成一个url,那么ADD就类似于wget命令
<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
~~~
7, **COPY**
COPY指令与ADD指令类似,但COPY的源文件只能是本地文件
~~~powershell
格式:COPY <src> <dest>
~~~
8, **ENTRYPOINT**
ENTRYPOINT与CMD非常类似
相同点:
一个Dockerfile只写一条,如果写了多条,那么只有最后一条生效
都是容器启动时才运行
不同点:
如果用户启动容器时候指定了运行的命令,ENTRYPOINT不会被运行的命令覆盖,而CMD则会被覆盖
~~~powershell
格式有两种:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
~~~
9, **VOLUME**
VOLUME指令用于把宿主机里的目录与容器里的目录映射.
只指定挂载点,docker宿主机映射的目录为自动生成的。
~~~powershell
格式:VOLUME ["<mountpoint>"]
~~~
10, **USER**
USER指令设置启动容器的用户(像hadoop需要hadoop用户操作,oracle需要oracle用户操作),可以是用户名或UID
~~~powershell
USER daemon
USER 1001
~~~
**注意**:如果设置了容器以daemon用户去运行,那么RUN,CMD和ENTRYPOINT都会以这个用户去运行
镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户
11, **WORKDIR**
WORKDIR指令设置工作目录,类似于cd命令。不建议使用`RUN cd /root` ,建议使用WORKDIR
~~~powershell
WORKDIR /root
~~~
### 4.4.3 Dockerfile基本构成
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时执行指令
### 4.4.4 Dockerfile生成容器镜像方法

### 4.4.5 Dockerfile生成容器镜像案例
#### 4.4.5.0 使用Dockerfile生成容器镜像步骤
~~~powershell
第一步:创建一个文件夹(目录)
第二步:在文件夹(目录)中创建Dockerfile文件(并编写)及其它文件
第三步:使用`docker build`命令构建镜像
第四步:使用构建的镜像启动容器
~~~
#### 4.4.5.1 使用Dockerfile生成Nginx容器镜像
~~~powershell
[root@localhost ~]# mkdir nginxroot
[root@localhost ~]# cd nginxroot
[root@localhost nginxroot]#
~~~
~~~powershell
[root@localhost nginxroot]# echo "nginx's running" >> index.html
[root@localhost nginxroot]# ls
index.html
[root@localhost nginxroot]# cat index.html
nginx's running
~~~
~~~powershell
[root@localhost nginxroot]# vim Dockerfile
[root@localhost nginxroot]# cat Dockerfile
FROM centos:centos7
MAINTAINER "www.kubemsb.com"
RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install nginx
ADD index.html /usr/share/nginx/html/
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
CMD /usr/sbin/nginx
~~~
~~~powershell
[root@localhost nginxroot]# docker build -t centos7-nginx:v1 .
~~~
~~~powershell
输出:
Sending build context to Docker daemon 3.072kB
第一步:下载基础镜像
Step 1/9 : FROM centos:centos7
---> eeb6ee3f44bd
第二步:维护者信息
Step 2/9 : MAINTAINER "www.kubemsb.com"
---> Using cache
---> f978e524772c
第三步:安装wget
Step 3/9 : RUN yum -y install wget
---> Running in 4e0fc3854088
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirrors.huaweicloud.com
* extras: mirrors.tuna.tsinghua.edu.cn
* updates: mirrors.tuna.tsinghua.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package wget.x86_64 0:1.14-18.el7_6.1 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
wget x86_64 1.14-18.el7_6.1 base 547 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 547 k
Installed size: 2.0 M
Downloading packages:
warning: /var/cache/yum/x86_64/7/base/packages/wget-1.14-18.el7_6.1.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for wget-1.14-18.el7_6.1.x86_64.rpm is not installed
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Importing GPG key 0xF4A80EB5:
Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
Package : centos-release-7-9.2009.0.el7.centos.x86_64 (@CentOS)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : wget-1.14-18.el7_6.1.x86_64 1/1
install-info: No such file or directory for /usr/share/info/wget.info.gz
Verifying : wget-1.14-18.el7_6.1.x86_64 1/1
Installed:
wget.x86_64 0:1.14-18.el7_6.1
Complete!
Removing intermediate container 4e0fc3854088
---> 369e33a2152a
第四步:使用wget下载YUM源
Step 4/9 : RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
---> Running in 4bdfc0a1c844
--2022-02-10 06:18:07-- http://mirrors.aliyun.com/repo/epel-7.repo
Resolving mirrors.aliyun.com (mirrors.aliyun.com)... 221.195.209.65, 221.195.209.64, 221.195.209.70, ...
Connecting to mirrors.aliyun.com (mirrors.aliyun.com)|221.195.209.65|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 664 [application/octet-stream]
Saving to: '/etc/yum.repos.d/epel.repo'
0K 100% 158M=0s
2022-02-10 06:18:07 (158 MB/s) - '/etc/yum.repos.d/epel.repo' saved [664/664]
Removing intermediate container 4bdfc0a1c844
---> 1d73faa62447
第五步:安装Nginx
Step 5/9 : RUN yum -y install nginx
---> Running in 51b50c2ce841
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
* base: mirrors.huaweicloud.com
* extras: mirrors.tuna.tsinghua.edu.cn
* updates: mirrors.tuna.tsinghua.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package nginx.x86_64 1:1.20.1-9.el7 will be installed
--> Processing Dependency: nginx-filesystem = 1:1.20.1-9.el7 for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: libcrypto.so.1.1(OPENSSL_1_1_0)(64bit) for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: libssl.so.1.1(OPENSSL_1_1_0)(64bit) for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: libssl.so.1.1(OPENSSL_1_1_1)(64bit) for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: nginx-filesystem for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: openssl for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: redhat-indexhtml for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: system-logos for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: libcrypto.so.1.1()(64bit) for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: libprofiler.so.0()(64bit) for package: 1:nginx-1.20.1-9.el7.x86_64
--> Processing Dependency: libssl.so.1.1()(64bit) for package: 1:nginx-1.20.1-9.el7.x86_64
--> Running transaction check
---> Package centos-indexhtml.noarch 0:7-9.el7.centos will be installed
---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed
---> Package gperftools-libs.x86_64 0:2.6.1-1.el7 will be installed
---> Package nginx-filesystem.noarch 1:1.20.1-9.el7 will be installed
---> Package openssl.x86_64 1:1.0.2k-24.el7_9 will be installed
--> Processing Dependency: openssl-libs(x86-64) = 1:1.0.2k-24.el7_9 for package: 1:openssl-1.0.2k-24.el7_9.x86_64
--> Processing Dependency: make for package: 1:openssl-1.0.2k-24.el7_9.x86_64
---> Package openssl11-libs.x86_64 1:1.1.1k-2.el7 will be installed
--> Running transaction check
---> Package make.x86_64 1:3.82-24.el7 will be installed
---> Package openssl-libs.x86_64 1:1.0.2k-19.el7 will be updated
---> Package openssl-libs.x86_64 1:1.0.2k-24.el7_9 will be an update
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
nginx x86_64 1:1.20.1-9.el7 epel 587 k
Installing for dependencies:
centos-indexhtml noarch 7-9.el7.centos base 92 k
centos-logos noarch 70.0.6-3.el7.centos base 21 M
gperftools-libs x86_64 2.6.1-1.el7 base 272 k
make x86_64 1:3.82-24.el7 base 421 k
nginx-filesystem noarch 1:1.20.1-9.el7 epel 24 k
openssl x86_64 1:1.0.2k-24.el7_9 updates 494 k
openssl11-libs x86_64 1:1.1.1k-2.el7 epel 1.5 M
Updating for dependencies:
openssl-libs x86_64 1:1.0.2k-24.el7_9 updates 1.2 M
Transaction Summary
================================================================================
Install 1 Package (+7 Dependent packages)
Upgrade ( 1 Dependent package)
Total download size: 26 M
Downloading packages:
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
--------------------------------------------------------------------------------
Total 3.1 MB/s | 26 MB 00:08
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : centos-logos-70.0.6-3.el7.centos.noarch 1/10
Installing : centos-indexhtml-7-9.el7.centos.noarch 2/10
Installing : 1:make-3.82-24.el7.x86_64 3/10
Installing : gperftools-libs-2.6.1-1.el7.x86_64 4/10
Installing : 1:openssl11-libs-1.1.1k-2.el7.x86_64 5/10
Updating : 1:openssl-libs-1.0.2k-24.el7_9.x86_64 6/10
Installing : 1:openssl-1.0.2k-24.el7_9.x86_64 7/10
Installing : 1:nginx-filesystem-1.20.1-9.el7.noarch 8/10
Installing : 1:nginx-1.20.1-9.el7.x86_64 9/10
Cleanup : 1:openssl-libs-1.0.2k-19.el7.x86_64 10/10
Verifying : 1:nginx-filesystem-1.20.1-9.el7.noarch 1/10
Verifying : 1:nginx-1.20.1-9.el7.x86_64 2/10
Verifying : 1:openssl-libs-1.0.2k-24.el7_9.x86_64 3/10
Verifying : 1:openssl11-libs-1.1.1k-2.el7.x86_64 4/10
Verifying : gperftools-libs-2.6.1-1.el7.x86_64 5/10
Verifying : 1:make-3.82-24.el7.x86_64 6/10
Verifying : 1:openssl-1.0.2k-24.el7_9.x86_64 7/10
Verifying : centos-indexhtml-7-9.el7.centos.noarch 8/10
Verifying : centos-logos-70.0.6-3.el7.centos.noarch 9/10
Verifying : 1:openssl-libs-1.0.2k-19.el7.x86_64 10/10
Installed:
nginx.x86_64 1:1.20.1-9.el7
Dependency Installed:
centos-indexhtml.noarch 0:7-9.el7.centos
centos-logos.noarch 0:70.0.6-3.el7.centos
gperftools-libs.x86_64 0:2.6.1-1.el7
make.x86_64 1:3.82-24.el7
nginx-filesystem.noarch 1:1.20.1-9.el7
openssl.x86_64 1:1.0.2k-24.el7_9
openssl11-libs.x86_64 1:1.1.1k-2.el7
Dependency Updated:
openssl-libs.x86_64 1:1.0.2k-24.el7_9
Complete!
Removing intermediate container 51b50c2ce841
---> 88a7d7a2c522
第六步:添加文件至容器
Step 6/9 : ADD index.html /usr/share/nginx/html/
---> a2226a4d6720
第七步:设置nginx服务运行方式
Step 7/9 : RUN echo "daemon off;" >> /etc/nginx/nginx.conf
---> Running in 01d623937807
Removing intermediate container 01d623937807
---> 53fddea5b491
第八步:暴露端口
Step 8/9 : EXPOSE 80
---> Running in 9b73fcf7ee1b
Removing intermediate container 9b73fcf7ee1b
---> 903377216b23
第九步:运行命令,执行nginx二进制文件
Step 9/9 : CMD /usr/sbin/nginx
---> Running in 58037652952c
Removing intermediate container 58037652952c
---> 944d27b80f1f
生成镜像,并为镜像打标记:
Successfully built 944d27b80f1f
Successfully tagged centos7-nginx:v1
~~~
~~~powershell
[root@localhost nginxroot]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-nginx v1 944d27b80f1f 3 minutes ago 587MB
~~~
~~~powershell
[root@localhost ~]# docker run -d -p 8081:80 centos7-nginx:v1
~~~
~~~powershell
[root@localhost ~]# curl http://localhost:8081
nginx's running
~~~
#### 4.4.5.2 使用Dockerfile生成Tomcat容器镜像
~~~powershell
[root@localhost ~]# mkdir tomcatdir
[root@localhost ~]# cd tomcatdir/
[root@localhost tomcatdir]#
~~~
~~~powershell
[root@localhost tomcatdir]# echo "tomcat is running" >> index.html
~~~
~~~powershell
[root@localhost tomcatdir]# ls
Dockerfile jdk index.html
jdk为目录
index.html 网站首页
~~~
~~~powershell
[root@localhost tomcatdir]# vim Dockerfile
[root@localhost tomcatdir]# cat Dockerfile
FROM centos:centos7
MAINTAINER "www.kubemsb.com"
ENV VERSION=8.5.75
ENV JAVA_HOME=/usr/local/jdk
ENV TOMCAT_HOME=/usr/local/tomcat
RUN yum -y install wget
RUN wget https://dlcdn.apache.org/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz
RUN tar xf apache-tomcat-${VERSION}.tar.gz
RUN mv apache-tomcat-${VERSION} /usr/local/tomcat
RUN rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/*
RUN mkdir /usr/local/tomcat/webapps/ROOT
ADD ./index.html /usr/local/tomcat/webapps/ROOT/
ADD ./jdk /usr/local/jdk
RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile
RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile
RUN echo "export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH" >> /etc/profile
RUN echo "export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" >> /etc/profile
RUN source /etc/profile
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
~~~
~~~powershell
[root@localhost tomcatdir]# docker build -t centos-tomcat:v1 .
Sending build context to Docker daemon 398.9MB
Step 1/20 : FROM centos:centos7
---> eeb6ee3f44bd
Step 2/20 : MAINTAINER "www.kubemsb.com"
---> Using cache
---> f978e524772c
Step 3/20 : ENV VERSION=8.5.75
---> Using cache
---> 792767bbdb22
Step 4/20 : ENV JAVA_HOME=/usr/local/jdk
---> Using cache
---> 6eb3855650f0
Step 5/20 : ENV TOMCAT_HOME=/usr/local/tomcat
---> Using cache
---> e38bdbbfd19d
Step 6/20 : RUN yum -y install wget
---> Using cache
---> 4c6aafa6d8ba
Step 7/20 : RUN wget http://dlcdn.apache.org/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz
---> Using cache
---> 9bdb6f636a5f
Step 8/20 : RUN tar xf apache-tomcat-${VERSION}.tar.gz
---> Using cache
---> 6abe5cb0ef26
Step 9/20 : RUN mv apache-tomcat-${VERSION} /usr/local/tomcat
---> Using cache
---> b3907af15c22
Step 10/20 : RUN rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/*
---> Using cache
---> b775439344e3
Step 11/20 : RUN mkdir /usr/local/tomcat/webapps/ROOT
---> Using cache
---> 149ad46776eb
Step 12/20 : ADD ./index.html /usr/local/tomcat/webapps/ROOT/
---> 064579c39a46
Step 13/20 : ADD ./jdk /usr/local/jdk
---> 477fd38dfbcf
Step 14/20 : RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile
---> Running in 3fc9bc5e8ba5
Removing intermediate container 3fc9bc5e8ba5
---> 3c43bccd5779
Step 15/20 : RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile
---> Running in 80f8150f0e80
Removing intermediate container 80f8150f0e80
---> e01307ccb02a
Step 16/20 : RUN echo "export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH" >> /etc/profile
---> Running in 92a6a4fd1cbc
Removing intermediate container 92a6a4fd1cbc
---> 1d26f53b7095
Step 17/20 : RUN echo "export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" >> /etc/profile
---> Running in fb5ee1710c36
Removing intermediate container fb5ee1710c36
---> d2eaff35dce3
Step 18/20 : RUN source /etc/profile
---> Running in 0422af810b35
Removing intermediate container 0422af810b35
---> fc6d285288ca
Step 19/20 : EXPOSE 8080
---> Running in eeb64d4f9e94
Removing intermediate container eeb64d4f9e94
---> 05ec1c6d06cf
Step 20/20 : CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
---> Running in 66b7851e2772
Removing intermediate container 66b7851e2772
---> ad338289055c
Successfully built ad338289055c
Successfully tagged centos-tomcat:v1
~~~
~~~powershell
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-tomcat v1 ad338289055c 6 minutes ago 797MB
~~~
~~~powershell
# docker run -d -p 8082:8080 centos-tomcat:v1
~~~
~~~powershell
# curl http://localhost:8082
tomcat is running
~~~
### 4.4.6 使用Dockerfile生成容器镜像优化
#### 4.4.6.1 减少镜像分层
Dockerfile中包含多种指令,如果涉及到部署最多使用的算是RUN命令了,使用RUN命令时,不建议每次安装都使用一条单独的RUN命令,可以把能够合并安装指令合并为一条,这样就可以减少镜像分层。
~~~powershell
FROM centos:latest
MAINTAINER www.kubemsb.com
RUN yum install epel-release -y
RUN yum install -y gcc gcc-c++ make -y
RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz
RUN tar zxf php-5.6.36.tar.gz
RUN cd php-5.6.36
RUN ./configure --prefix=/usr/local/php
RUN make -j 4
RUN make install
EXPOSE 9000
CMD ["php-fpm"]
~~~
**优化内容如下:**
~~~powershell
FROM centos:latest
MAINTAINER www.kubemsb.com
RUN yum install epel-release -y && \
yum install -y gcc gcc-c++ make
RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
tar zxf php-5.6.36.tar.gz && \
cd php-5.6.36 && \
./configure --prefix=/usr/local/php && \
make -j 4 && make install
EXPOSE 9000
CMD ["php-fpm"]
~~~
#### 4.4.6.2 清理无用数据
- 一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。
- 把生成容器镜像过程中部署的应用软件包做删除处理
~~~powershell
FROM centos:latest
MAINTAINER www.kubemsb.com
RUN yum install epel-release -y && \
yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
libcurl-devel libjpeg-devel libpng-devel openssl-devel \
libmcrypt-devel libxslt-devel libtidy-devel autoconf \
iproute net-tools telnet wget curl && \
yum clean all && \
rm -rf /var/cache/yum/*
RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
tar zxf php-5.6.36.tar.gz && \
cd php-5.6.36 && \
./configure --prefix=/usr/local/php \
make -j 4 && make install && \
cd / && rm -rf php*
~~~
#### 4.4.6.3 多阶段构建镜像
项目容器镜像有两种,一种直接把项目代码复制到容器镜像中,下次使用容器镜像时即可直接启动;另一种把需要对项目源码进行编译,再复制到容器镜像中使用。
不论是哪种方法都会让制作镜像复杂了些,并也会让容器镜像比较大,建议采用分阶段构建镜像的方法实现。
~~~powershell
$ git clone https://github.com/kubemsb/tomcat-java-demo
$ cd tomcat-java-demo
$ vi Dockerfile
FROM maven AS build
ADD ./pom.xml pom.xml
ADD ./src src/
RUN mvn clean package
FROM kubemsb/tomcat
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war
$ docker build -t demo:v1 .
$ docker container run -d -v demo:v1
~~~
~~~powershell
第一个 FROM 后边多了个 AS 关键字,可以给这个阶段起个名字
第二个 FROM 使用上面构建的 Tomcat 镜像,COPY 关键字增加了 —from 参数,用于拷贝某个阶段的文件到当前阶段。
~~~
# 五、新型容器镜像构建技术 BuildPacks
================================================
FILE: docs/cloud/docker/docker_image.md
================================================
# Docker容器镜像
# 一、Docker容器镜像操作
## 2.1 查看本地容器镜像
### 2.1.1 使用docker images命令查看
~~~powershell
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bash latest 5557e073f11c 2 weeks ago 13MB
nginx latest 605c77e624dd 3 weeks ago 141MB
centos latest 5d0da3dc9764 4 months ago 231MB
~~~
### 2.1.2 使用docker image命令查看
~~~powershell
#
gitextract_h3qke_bo/ ├── .gitignore ├── CNAME ├── README.md ├── docs/ │ ├── CNAME │ ├── cloud/ │ │ ├── apprelease.md │ │ ├── compute.md │ │ ├── containerlinux.md │ │ ├── docker/ │ │ │ ├── docker_compose.md │ │ │ ├── docker_container.md │ │ │ ├── docker_container_enterprice.md │ │ │ ├── docker_date.md │ │ │ ├── docker_devops.md │ │ │ ├── docker_file.md │ │ │ ├── docker_image.md │ │ │ ├── docker_image_fast.md │ │ │ ├── docker_native.md │ │ │ ├── docker_network.md │ │ │ ├── docker_nginx.md │ │ │ └── docker_swarm.md │ │ ├── kubernetes/ │ │ │ ├── kubernetes_ack.md │ │ │ ├── kubernetes_calico.md │ │ │ ├── kubernetes_cluster.md │ │ │ ├── kubernetes_cluster_serve.md │ │ │ ├── kubernetes_configMap_secret.md │ │ │ ├── kubernetes_core.md │ │ │ ├── kubernetes_deploy_golang.md │ │ │ ├── kubernetes_deploy_java.md │ │ │ ├── kubernetes_deploy_python.md │ │ │ ├── kubernetes_devops.md │ │ │ ├── kubernetes_flannel.md │ │ │ ├── kubernetes_flink.md │ │ │ ├── kubernetes_gitops.md │ │ │ ├── kubernetes_harbor.md │ │ │ ├── kubernetes_hdfs.md │ │ │ ├── kubernetes_helm.md │ │ │ ├── kubernetes_helm_prometheus.md │ │ │ ├── kubernetes_hight.md │ │ │ ├── kubernetes_hight_bin1.md │ │ │ ├── kubernetes_hight_bin2.md │ │ │ ├── kubernetes_hybridnet.md │ │ │ ├── kubernetes_introduce.md │ │ │ ├── kubernetes_ipv4_and_ipv6.md │ │ │ ├── kubernetes_kafka.md │ │ │ ├── kubernetes_karmada.md │ │ │ ├── kubernetes_kubeconfig.md │ │ │ ├── kubernetes_kubesphere.md │ │ │ ├── kubernetes_kubesphere_devops.md │ │ │ ├── kubernetes_kurator.md │ │ │ ├── kubernetes_kustomize.md │ │ │ ├── kubernetes_logs_collect.md │ │ │ ├── kubernetes_master.md │ │ │ ├── kubernetes_nginx_ingress_controller.md │ │ │ ├── kubernetes_openfass.md │ │ │ ├── kubernetes_rancher.md │ │ │ ├── kubernetes_rke.md │ │ │ ├── kubernetes_rokectmq.md │ │ │ ├── kubernetes_safety.md │ │ │ ├── kubernetes_sealos.md │ │ │ ├── kubernetes_spark.md │ │ │ ├── kubernetes_storage_ceph.md │ │ │ ├── kubernetes_storage_volume.md │ │ │ ├── kubernetes_traefik.md │ │ │ ├── kubernetes_ui.md │ │ │ ├── kubernetes_velero.md │ │ │ ├── kubernetes_way.md │ │ │ └── kubernetes_zookeeper.md │ │ ├── kubernetes.md │ │ ├── native.md │ │ └── virtual.md │ ├── dart/ │ │ └── syntax.md │ ├── docker/ │ │ ├── docker-compose.md │ │ ├── docker-jenkins.md │ │ ├── docker-phabricator.md │ │ ├── docker.md │ │ └── docker_core.md │ ├── emotion/ │ │ ├── emotion.md │ │ ├── eq.md │ │ ├── lifetime.md │ │ ├── livefail.md │ │ ├── lookbook.md │ │ ├── losecome.md │ │ ├── onepath.md │ │ ├── selfdiscipline.md │ │ ├── threeheart.md │ │ ├── twopath.md │ │ └── workheard.md │ ├── exp/ │ │ ├── ai.md │ │ ├── cl.md │ │ ├── code-principle.md │ │ ├── cto.md │ │ ├── devops.md │ │ ├── four_deep_learning.md │ │ ├── learnweetout.md │ │ ├── micro-service.md │ │ ├── pt.md │ │ ├── raft-gossip.md │ │ ├── techbig.md │ │ └── tl.md │ ├── framework/ │ │ ├── agility.md │ │ ├── algorithm-ten.md │ │ ├── data_middle.md │ │ ├── fgb.md │ │ ├── fwork.md │ │ └── split.md │ ├── go/ │ │ └── go_base.md │ ├── index.md │ ├── java/ │ │ ├── bio-nio.md │ │ ├── feature.md │ │ ├── java-simple.md │ │ ├── java-string.md │ │ ├── java-utils.md │ │ ├── java-validator.md │ │ ├── javavm.md │ │ ├── load-class.md │ │ ├── orm.md │ │ ├── rocketmq/ │ │ │ └── rmq-1.md │ │ ├── spring-cloud.md │ │ ├── springAnnotation.md │ │ └── springdesign.md │ ├── js/ │ │ ├── baidu-tongji.js │ │ ├── extra.js │ │ └── google.js │ ├── kubernetes/ │ │ ├── k8s_controller_manager.md │ │ ├── k8s_etcd.md │ │ ├── k8s_fw_rule_and_object_design.md │ │ └── k8s_kube_APIServer.md │ ├── linux/ │ │ ├── linux.md │ │ ├── often.md │ │ └── ope.md │ ├── micro/ │ │ ├── ddd.md │ │ ├── design.md │ │ ├── distrimsg.md │ │ ├── fbs-lock.md │ │ ├── kafka.md │ │ ├── redis_cluster.md │ │ └── spring-cloud-micro.md │ ├── net/ │ │ ├── c_core_safety.md │ │ ├── c_core_study_route.md │ │ ├── c_docker.md │ │ ├── c_sharp.md │ │ └── c_sqlserver_nginx.md │ ├── php/ │ │ └── kj.md │ ├── python/ │ │ ├── fabric.md │ │ ├── feature.md │ │ ├── str_joint.md │ │ └── syntax_rule.md │ ├── sql/ │ │ ├── data_split.md │ │ ├── mybatis.md │ │ ├── mysql_backups.md │ │ ├── mysql_index.md │ │ ├── mysql_log.md │ │ ├── mysql_pxc.md │ │ ├── mysql_use.md │ │ ├── mysql_yh.md │ │ ├── mysql_yh17.md │ │ └── sql_server_master.md │ ├── tool/ │ │ ├── cat-monitoring.md │ │ ├── cicd.md │ │ ├── git.md │ │ ├── gitbook.md │ │ ├── gitcmr.md │ │ ├── gitflow.md │ │ ├── gitquestion.md │ │ ├── gitstudy.md │ │ ├── gitusual.md │ │ ├── markdown.md │ │ ├── minio.md │ │ └── mkdocs.md │ └── web/ │ ├── ali_js_style.md │ ├── es6.md │ ├── javascript.md │ ├── js_tool_method.md │ ├── node.js.md │ ├── react.md │ ├── react_interview.md │ └── vue_cp_react.md └── mkdocs.yml
SYMBOL INDEX (2 symbols across 1 files)
FILE: docs/js/google.js
function gtag (line 5) | function gtag(){dataLayer.push(arguments);}
function gtag (line 12) | function gtag(){dataLayer.push(arguments);}
Condensed preview — 177 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,342K chars).
[
{
"path": ".gitignore",
"chars": 30,
"preview": "/site\n/.obsidian\n/docs/csdn.md"
},
{
"path": "CNAME",
"chars": 16,
"preview": "burningmyself.cn"
},
{
"path": "README.md",
"chars": 9965,
"preview": "# 个人博客\n\n---\n本仓库下存放个人博客的源文件。持续更新,欢迎 star。\n\n如果大家觉得那里写的不合适的可以给我提 Issue\n\n[Github](https://github.com/burningmyself)\n\n[Gitee]"
},
{
"path": "docs/CNAME",
"chars": 16,
"preview": "burningmyself.cn"
},
{
"path": "docs/cloud/apprelease.md",
"chars": 3212,
"preview": "# 应用(Application)部署容器化演进之路\n\n# 一、应用程序部署痛点\n\n## 1.1 应用程序部署流程\n\n**举例:部署一个JAVA编程语言开发的Web应用,以War包放入Tomcat方式部署。**\n\n- 部署过程如下:\n -"
},
{
"path": "docs/cloud/compute.md",
"chars": 2356,
"preview": "# 云计算\n\n# 一、计算资源使用方式\n\n## 1.1 主机资源使用方式\n\n在云计算出现之前,常用的主机资源使用方式有:\n\n- 自己购买物理机\n- IDC托管物理机\n- IDC租用物理机\n- 虚拟机\n- 虚拟主机\n\n## 1.2 传统资源管"
},
{
"path": "docs/cloud/containerlinux.md",
"chars": 11288,
"preview": "# 容器技术所涉及Linux内核关键技术\n\n# 一、容器技术前世今生\n\n## 1.1 1979年 — chroot\n\n- 容器技术的概念可以追溯到1979年的UNIX chroot。\n- 它是一套“UNIX操作系统”系统,旨在将其root目"
},
{
"path": "docs/cloud/docker/docker_compose.md",
"chars": 10893,
"preview": "# Docker容器服务编排利器 Docker Compose应用实战\n\n# 一、使用Docker Compose必要性及定义\n\n用容器运行一个服务,需要使用`docker run`命令。但如果我要运行多个服务呢?\n\n假设我要运行一个web"
},
{
"path": "docs/cloud/docker/docker_container.md",
"chars": 70279,
"preview": "# 轻量级或工业级容器管理工具 Containerd\n\n\n\n# 一、Containerd介绍\n\n## 1.0 前言\n\n- 早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把co"
},
{
"path": "docs/cloud/docker/docker_container_enterprice.md",
"chars": 28963,
"preview": "# Docker容器化部署企业级应用集群\n\n# 一、Docker容器化部署企业级应用\n\n## 1.1 使用Docker容器化部署企业级应用必要性\n\n- 有利于快速实现企业级应用部署\n- 有利于快速实现企业级应用恢复\n\n\n\n## 1.2 使用"
},
{
"path": "docs/cloud/docker/docker_date.md",
"chars": 4872,
"preview": "# Docker容器数据持久化存储机制\n\n# 一、Docker容器数据持久化存储介绍\n\n- 物理机或虚拟机数据持久化存储\n - 由于物理机或虚拟机本身就拥有大容量的磁盘,所以可以直接把数据存储在物理机或虚拟机本地文件系统中,亦或者也可以通"
},
{
"path": "docs/cloud/docker/docker_devops.md",
"chars": 32191,
"preview": "# 基于Docker容器DevOps应用方案 企业业务代码发布系统\n\n# 一、企业业务代码发布方式\n\n## 1.1 传统方式\n\n- 以物理机或虚拟机为颗粒度部署\n- 部署环境比较复杂,需要有先进的自动化运维手段\n- 出现问题后重新部署成本大"
},
{
"path": "docs/cloud/docker/docker_file.md",
"chars": 23668,
"preview": "# Dockerfile精讲及新型容器镜像构建技术\n\n# 一、容器与容器镜像之间的关系\n\n说到Docker管理的容器不得不说容器镜像,主要因为容器镜像是容器模板,通过容器镜像我们才能快速创建容器。\n\n如下图所示:\n\n\n\n## 1.2开通阿里云V"
},
{
"path": "docs/cloud/kubernetes/kubernetes_calico.md",
"chars": 36304,
"preview": "\n\n# kubernetes网络解决方案 Calico\n\n# 一、CNI方案\n\n学习目标\n\n这一节,我们从 基础原理、方案解读、小结 三个方面来学习\n\n**基础原理**\n\n容器访问模式\n\n容器; 这些"
},
{
"path": "docs/cloud/kubernetes/kubernetes_deploy_golang.md",
"chars": 8216,
"preview": "# Kubernetes集群golang项目上云部署\n\n# 一、项目情况\n\n本次上线部署的是一个基于Golang开发的百万并发的IM系统,提供平台用户基本聊天及群聊功能等。\n\n\n\n# 二、项目源码\n\n\n\n~~~powershell\n[roo"
},
{
"path": "docs/cloud/kubernetes/kubernetes_deploy_java.md",
"chars": 23267,
"preview": "# kubernetes集群java项目上云部署\n\n\n\n# 一、部署前准备工作\n\n## 1.1 部署项目情况\n\n### 1.1.1 业务部署架构\n\n- 单体服务架构\n- 分布式服务架构\n- 微服务架构\n- 超微服务架构\n\n\n\n### 1.1"
},
{
"path": "docs/cloud/kubernetes/kubernetes_deploy_python.md",
"chars": 16207,
"preview": "# kubernetes集群Python项目上云部署\n\n\n\n# 一、项目资源及项目代码\n\n\n\n~~~powershell\n[root@localhost cmdb]# pwd\n/root/cmdb\n[root@localhost cmdb]"
},
{
"path": "docs/cloud/kubernetes/kubernetes_devops.md",
"chars": 66857,
"preview": "# DevOps\n\n### 一、DevOps介绍\n\n软件开发最开始是由两个团队组成:\n\n- 开发计划由[开发团队]()从头开始设计和整体系统的构建。需要系统不停的迭代更新。\n- [运维团队]()将开发团队的Code进行测试后部署上线。希望系"
},
{
"path": "docs/cloud/kubernetes/kubernetes_flannel.md",
"chars": 162260,
"preview": "# 1 集群环境实践\n\n## 1.1 单主集群\n\n### 1.1.1 基础环境部署\n\n学习目标\n\n这一节,我们从 集群规划、主机认证、小结 三个方面来学习。\n\n**集群规划**\n\n简介\n\n```powershell\n在这里,我们以单主分布式"
},
{
"path": "docs/cloud/kubernetes/kubernetes_flink.md",
"chars": 131071,
"preview": "## 1.1 **Kubernetes 介绍**\n\nKubernetes是Google公司在2014年6月开源的一个容器集群管理系统,使用Go语言开发,也叫K8S(k8s 这个缩写是因为k和s之间有八个字符的关系)。Kubernetes这个"
},
{
"path": "docs/cloud/kubernetes/kubernetes_gitops.md",
"chars": 48942,
"preview": "# GitOps\n\n# 一、什么是GitOps\n\n说起GitOps,可能马上会联想到我们前面讲的DevOps,那么GitOps和DevOps之间有什么关系、又有什么区别呢?\n\nDevOps是一种文化\n\nDevOps包含了Developmen"
},
{
"path": "docs/cloud/kubernetes/kubernetes_harbor.md",
"chars": 14187,
"preview": "# Kubernetes集群使用容器镜像仓库Harbor\n\n# 一、容器镜像仓库Harbor部署\n\n## 1.1 在docker主机部署harbor\n\n### 1.1.1 docker-ce安装\n\n#### 1.1.1.1 获取YUM源\n\n"
},
{
"path": "docs/cloud/kubernetes/kubernetes_hdfs.md",
"chars": 11772,
"preview": "## **1.1 大数据HDFS分布式文件系统搭建**\n\n这里我们使用5台节点来安装分布式文件系统,每台节点给了4G内存,4个core,并且每台节点已经关闭防火墙、配置主机名、设置yum源、各个节点时间同步、各个节点两两免密、安装JDK操作"
},
{
"path": "docs/cloud/kubernetes/kubernetes_helm.md",
"chars": 51098,
"preview": "# Kubernetes集群包管理解决方案及应用商店 Helm&Kubeapps\n\n\n\n# 一、引入helm原因\n\n当今的软件开发,随着云原生技术的普及,我们的工程应用进行微服务化和容器化的现象也变得越来越普遍。而Kubernetes几乎已"
},
{
"path": "docs/cloud/kubernetes/kubernetes_helm_prometheus.md",
"chars": 64478,
"preview": "# helm部署prometheus监控系统及应用\n\n# 一、helm安装\n\n\n\n~~~powershell\nwget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz\n~~~\n\n\n\n~~"
},
{
"path": "docs/cloud/kubernetes/kubernetes_hight.md",
"chars": 31885,
"preview": "# kubeadm部署高可用kubernetes集群 1.21 \n\n \n\n# 一、kubernetes 1.21发布\n\n\n\n\n\nKubernetes(简称为:k8s)是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,用于管理云平台中多个主机上的容器化的应用,Ku"
},
{
"path": "docs/cloud/kubernetes/kubernetes_hight_bin2.md",
"chars": 60309,
"preview": "# Kubernetes高可用集群二进制部署(Runtime Containerd)\n\nKubernetes(简称为:k8s)是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,用于管理云平台中多个主机上的容器化的应"
},
{
"path": "docs/cloud/kubernetes/kubernetes_hybridnet.md",
"chars": 46539,
"preview": "# k8s集群 underlay 网络方案 hybridnet\n\n# 零、容器网络方案介绍\n\n## 0.1 overlay 网络方案\n\n基于VXLAN、 NVGRE等封装技术实现overlay叠加网络:\n\n1、叠加网络/覆盖网络, 在物理网"
},
{
"path": "docs/cloud/kubernetes/kubernetes_introduce.md",
"chars": 4947,
"preview": "# Kubernetes介绍与集群架构\n\n# 一、认识容器编排工具\n\n- docker machine\n - 主要用于准备docker host\n - 现已弃用\n - 建议使用docker desktop\n- docker compo"
},
{
"path": "docs/cloud/kubernetes/kubernetes_ipv4_and_ipv6.md",
"chars": 38569,
"preview": "# K8S 1.22版本双栈协议(IPv4&IPv6)集群部署\n\n# 一、部署说明\n\n> 此笔记主要针对 k8s 1.22,其它版本请自行测试使用。\n>\n> 必须使用Open vSwitch功能。\n\n\n\n# 二、主机准备\n\n## 2.1 主"
},
{
"path": "docs/cloud/kubernetes/kubernetes_kafka.md",
"chars": 5653,
"preview": "# kubernetes云原生中间件上云部署 kafka\n\nApache Kafka是一种流行的分布式流式消息平台。Kafka生产者将数据写入分区主题,这些主题通过可配置的副本存储到broker群集上。 消费者来消费存储在broker的分区"
},
{
"path": "docs/cloud/kubernetes/kubernetes_karmada.md",
"chars": 17208,
"preview": "# karmada实现k8s集群联邦\n\n# 一、karmada介绍\n\n## 1.1 karmada是什么\n\nKarmada(Kubernetes Armada)是一个Kubernetes管理系统,使您能够跨多个Kubernetes集群和云运"
},
{
"path": "docs/cloud/kubernetes/kubernetes_kubeconfig.md",
"chars": 21155,
"preview": "# 使用kubeconfig管理多集群方法\n\n# 一、 k8s集群部署\n\n> 准备多套k8s集群,可以使用kubeadm部署多套k8s集群。\n\n\n\n~~~powershell\n# wget https://github.com/labri"
},
{
"path": "docs/cloud/kubernetes/kubernetes_kubesphere.md",
"chars": 36095,
"preview": "# 在Linux上以all in one模式安装kubernetes & kubesphere\n\n于刚接触 KubeSphere 并想快速上手该容器平台的用户,All-in-One 安装模式是最佳的选择,它能够帮助您零配置快速部署 Kube"
},
{
"path": "docs/cloud/kubernetes/kubernetes_kubesphere_devops.md",
"chars": 50415,
"preview": "# Kubesphere应用前 账号准备\n\n\n\n# 一、Docker Hub账号注册\n\n。Kubernetes这个"
},
{
"path": "docs/cloud/kubernetes/kubernetes_storage_ceph.md",
"chars": 311904,
"preview": "# 存储解决方案 Ceph\n\n# 1 快速入门\n\n## 1.1 基础知识\n\n### 1.1.1 存储基础\n\n学习目标\n\n这一节,我们从 基础知识、文件系统、小结 三个方面来学习。\n\n**基础知识**\n\n存储基础\n\n```powershell"
},
{
"path": "docs/cloud/kubernetes/kubernetes_storage_volume.md",
"chars": 51427,
"preview": "# kubernetes持久化存储卷\n\n# 一、存储卷介绍\n\npod有生命周期,生命周期结束后pod里的数据会消失(如配置文件,业务数据等)。\n\n**解决: 我们需要将数据与pod分离,将数据放在专门的存储卷上**\n\n\n\npod在k8s集群"
},
{
"path": "docs/cloud/kubernetes/kubernetes_traefik.md",
"chars": 124010,
"preview": "# Kubernetes集群 服务暴露 Traefik\n\n\n\n# 一、认识traefik\n\n## 1.1 traefik简介\n\n- 参考链接: https://traefik.cn/\n\n- [traefik的yaml文件](../../im"
},
{
"path": "docs/cloud/kubernetes/kubernetes_ui.md",
"chars": 6914,
"preview": "# Kubernetes集群UI及主机资源监控\n\n# 一、Kubernetes dashboard作用\n\n- 通过dashboard能够直观了解Kubernetes集群中运行的资源对象\n- 通过dashboard可以直接管理(创建、删除、重"
},
{
"path": "docs/cloud/kubernetes/kubernetes_velero.md",
"chars": 30874,
"preview": "# kubernetes集群备份与恢复管理利器Velero\n\n# 一、Velero简介\n\nVelero 是一款可以安全的备份、恢复和迁移 Kubernetes 集群资源和持久卷等资源的备份恢复软件。\n\nVelero 实现的 kubernet"
},
{
"path": "docs/cloud/kubernetes/kubernetes_way.md",
"chars": 2309,
"preview": "# Kubernetes集群部署方式说明\n\n# 一、本地化部署\n\n## 1.1 kubeadm\n\n\n\n# 一、云原生定义\n\n## 1.1 理解云原生\n\n### 1.1.1 从字面理解\n\n云原生从字面意思上来看可以分成:\n\n- 云(Cloud)\n- 原生(Native)\n- 云原生(CloudNativ"
},
{
"path": "docs/cloud/virtual.md",
"chars": 12681,
"preview": "# 虚拟化技术\n\n# 一、计算机系统虚拟化定义\n\n## 1.1 物理机向虚拟机演进过程\n\n当物理机资源足够某一应用使用,并有多余的富余时,可以把多余的资源提供给其它的应用使用,这时就需要一种计算资源“打包技术”,2001年vmware公司提"
},
{
"path": "docs/dart/syntax.md",
"chars": 36541,
"preview": "# Dart语法学习\n\n## 目录\n* 参考资料\n* 语言特性\n* 关键字\n* 变量与常量\n* 数据类型\n* 运算符 operators\n* 控制流程语句\n* 异常 Exceptions\n* 函数 Function\n* 类 Class\n* "
},
{
"path": "docs/docker/docker-compose.md",
"chars": 13636,
"preview": "# docker和docker-compose 配置 mysql mssql mongodb redis nginx jenkins 环境\n\n## 磁盘挂载\n\n``` shell\nfdisk -l #查看磁盘列表\nmkfs.ext4 /de"
},
{
"path": "docs/docker/docker-jenkins.md",
"chars": 1808,
"preview": "# Docker部署Jenkins\n\n## Jenkins简介\nJenkins是开源CI&CD软件领导者,提供超过1000个插件来支持构建、部署、自动化,满足任何项目的需要。我们可以用Jenkins来构建和部署我们的项目,比如说从我们的代码"
},
{
"path": "docs/docker/docker-phabricator.md",
"chars": 1467,
"preview": "# Docker部署Phabricator\n\n## 安装\n\n1. 拉取镜像启动容器\n```\ndocker run --name phabricator \\\n-p 443:443 \\\n-p 80:80 \\\n-v /etc/localtime"
},
{
"path": "docs/docker/docker.md",
"chars": 12865,
"preview": "# Docker\n\n## Docker简介\n\n* Docker是开源应用容器引擎,轻量级容器技术。\n* 基于Go语言,并遵循Apache2.0协议开源\n* Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发"
},
{
"path": "docs/docker/docker_core.md",
"chars": 20016,
"preview": "# Docker 核心技术\n\n\n## 1. 从系统架构谈起\n\n### 传统分层架构 vs 微服务\n\n\n\n要不要管理好情绪\n\n有一个男孩脾气很坏,于是他的父亲就给了他一袋钉子,并且告诉他,当他想发脾气的时候,就钉一根钉子在后院的围篱上。第一天,这个男孩钉下了40根钉子。慢慢地,男孩可以控制他的情绪,不再乱发脾气,所"
},
{
"path": "docs/emotion/eq.md",
"chars": 5469,
"preview": "# 提高情商从哪几方面入手\n\n情商的重要性,想必你一定知道。\n\n情商高的人,他们往往是最受欢迎的人,而他们,也拥有许多的支持者。\n \n那你知道,高情商的表现都有哪些吗?\n\n## 不抱怨、不指责、不批评,有着正面的积极情绪,且充满热情\n\n生活"
},
{
"path": "docs/emotion/lifetime.md",
"chars": 1514,
"preview": "# 心态好的人,一辈子都好\n\n### 01\n昨天微信收到一条私信,一位朋友问我:\n \n“三十而立的年纪了,没钱、没车、没房,每天麻木的上班下班,浑浑噩噩地过日子,经常会不想活了,但是又没那个勇气,觉得自己特孤独、特没用,茶茶你说,我怎么才能"
},
{
"path": "docs/emotion/livefail.md",
"chars": 1255,
"preview": "# 如果你觉得自己活得很失败\n\n我之前也觉得自己特失败,就是,身边朋友,不是去了名校深造,就是拿到了漂亮的offer,噢,也包括我这个朋友,我当时给他发“恭喜”的时候,还在想,大家都混得蛮好。\n\n**谁不想要成功呢。往往是现状越难言,越想要"
},
{
"path": "docs/emotion/lookbook.md",
"chars": 1127,
"preview": "# 我们为什么要读书?这是让我印象最深的答案\n\n我一直有每天看书的习惯,即便工作再忙,也仍然坚持着。比如在地铁拥挤嘈杂的环境中,我掏出一本书看,就像肩上卸下一个大包袱。在书籍的世界里,我的心灵获得了放松。\n \n于我而言,看书的行为很单纯。你"
},
{
"path": "docs/emotion/losecome.md",
"chars": 2221,
"preview": "# 所有的失去,都会以另一种方式归来\n\n``\n曾有人问我,失去的东西回来了还要吗?我说,就像曾经丢了一粒扣子,等找到那粒扣子的时候,我早已经换了一件新衣服。\n``\n\n大部分的痛苦,都是不肯换场的结果,大部分的哀伤,只是源于执念太深。\n \n好"
},
{
"path": "docs/emotion/onepath.md",
"chars": 985,
"preview": "# 余生,学会一个人走,不管有没有人陪\n\n### 孤独\n\n很多人说,人生总是有诸多无常,起伏波折是上帝给每个人的考验。\n \n是啊,一帆风顺,大多只是一种奢望。\n\n到了一定的年龄,岁月总是如期而来,磨难总是不请自到,孤独总是突如而至。\n \n有"
},
{
"path": "docs/emotion/selfdiscipline.md",
"chars": 1476,
"preview": "# 关于自律,80%的人都理解错了\n\n### 立Flag\n2019年的份额已经过去了超过1/24。也就是说,如果你计划今年要跑100公里的步,到今天应该已经跑了4公里。你的Flag还好吗?\n \n看过一项研究说,只有8%的人可以实现自己的新年"
},
{
"path": "docs/emotion/threeheart.md",
"chars": 1141,
"preview": "# 人生有这三种好心态\n\n### 第一,放宽心。\n\n许多人会因为人与人之间的隔阂或矛盾而感到不愉快,但随着年岁渐长就会发现,许多事真的没必要。\n \n比如职场上的明争暗斗、生意上的尔虞我诈、竞争对手的互相拆台,我们以为战胜了别人,就赢得了想要"
},
{
"path": "docs/emotion/twopath.md",
"chars": 1521,
"preview": "# 往后余生还很精彩,别被熬夜拖垮了\n\n### 熬夜前因后果\n\n我特别理解熬夜人的苦衷:也许白天时间不够用,只能利用晚上充实自己;也许工作所迫,不得不通宵干活;也许平时有太多身不由己,只能在夜深人静时自我放逐。\n \n有人把熬夜细分为“被迫式"
},
{
"path": "docs/emotion/workheard.md",
"chars": 2911,
"preview": "# 工作心得:资质平庸的人该怎么办?引人深思!\n\n天赋秉异的人永远是少数,剩下的都是资质平庸的芸芸众生。相信即使只是普通人,也有一颗不甘于平庸的心。那么资质平庸的人该如何在职场上做出一番成就呢?\n\n其实以大多数人的努力程度之低,根本轮不到拼"
},
{
"path": "docs/exp/ai.md",
"chars": 2081,
"preview": "# 人工智能、机器学习、神经网络、深度学习、TensorFlow、图像处理必备书籍(附PDF百度盘下载链接)\n---\n在学习人工智能相关相关知识中往往不理解其中相关术语意义和知识原理的组成,下面书籍是阿拉灯神丁君在阅读了大量书籍后觉得很不错"
},
{
"path": "docs/exp/cl.md",
"chars": 3795,
"preview": "# 集群和负载均衡\n在“高并发,海量数据,分布式,NoSql,云计算......”概念满天飞的年代,相信不少朋友都听说过甚至常与人提起“集群,负载均衡”等,\n\n但不是所有人都有机会真正接触到这些技术,也不是所有人都真正理解了这些“听起来很牛"
},
{
"path": "docs/exp/code-principle.md",
"chars": 7873,
"preview": "# 编码原则\n\n## 吻(保持最简单愚蠢)\n如果保持简单而不是复杂,大多数系统都能发挥最佳性能。\n\n为什么:\n* 更少的代码花费更少的时间来编写,具有更少的错误,并且更容易修改。\n* 简约是最终的成熟。\n* 似乎没有任何东西可以添加,但是当"
},
{
"path": "docs/exp/cto.md",
"chars": 1643,
"preview": "# CTO 技能图谱\n\n### 岗位职责\n* \t建立技术团队文化\n* \t规划技术发展路线\n* \t落地产品研发成果\n* \t宣传公司技术品牌\n* \t吸引优秀技术人才\n\n### 基本素质\n* \t正直诚实的道德修养\n* \t谦虚谨慎的工作态度\n* \t"
},
{
"path": "docs/exp/devops.md",
"chars": 5848,
"preview": "# 一分钟告诉你究竟DevOps是什么鬼?\n\n\n\n## 历史回顾\n为了能够更好的理解什么是DevOps,我们很有必要对当时还只有程序员(此前还没有派生出开发者,"
},
{
"path": "docs/exp/four_deep_learning.md",
"chars": 7343,
"preview": "# 数据科学家必知的 5 个深度学习框架\n\n从出道起,我就一直是一名程序员。我喜欢从头开始编写代码,这有助于我清楚地理解主题(或技巧)。当我们刚开始学习数据科学时,这种方法尤为有用。\n\n尝试从无到有地实现一个神经网络,你将会明白很多有趣的事"
},
{
"path": "docs/exp/learnweetout.md",
"chars": 6285,
"preview": "# 程序员如何技术成长\n\n在浩大的软件世界里,作为一名普通程序员,显得十分渺小,甚至会感到迷茫。\n我们内心崇拜技术,却也对日新月异的技术抱有深深的恐惧。有时候我会思考难道在\n技术领域内不断紧跟新潮,不断提升技能就是我的价值所在?那么我是技术"
},
{
"path": "docs/exp/micro-service.md",
"chars": 12477,
"preview": "# 微服务架构技术栈选型手册\n2014~2018,微服务经过三年的发展,现状如何?这是一份为让你更好使用微服务的技术站选型手册。除此之外,你还可以按需选用配套的微服务架构视频内容。\n## 一、前言\n2014 年可以认为是微服务 1.0 的元"
},
{
"path": "docs/exp/pt.md",
"chars": 2200,
"preview": "# 需求又变了,要不要怼回去?\n\n需求变更,让每一个技术人头疼的问题,应该以怎么样的态度来面对需求变更,是今天要讨论的话题。\n \n为什么技术人讨厌需求变更?\n\n一个典型的互联网产品项目的流程是:\n1. 调研,产品经理设计需求;\n2. 产品经"
},
{
"path": "docs/exp/raft-gossip.md",
"chars": 2258,
"preview": "# Raft算法和Gossip协议\n简单介绍下集群数据同步,集群监控用到的两种常见算法。\n## Raft算法\nraft 集群中的每个节点都可以根据集群运行的情况在三种状态间切换:follower, candidate 与 leader。le"
},
{
"path": "docs/exp/techbig.md",
"chars": 6202,
"preview": "# 如何成为技术大牛\n\n不管是开发、测试、运维,每个技术人员心里多多少少都有一个成为技术大牛的\n梦,毕竟“梦想总是要有的,万一实现了呢”!正是对技术梦的追求,促使我们不断\n地努力和提升自己。\n然而“梦想是美好的,现实却是残酷的”,很多同学在"
},
{
"path": "docs/exp/tl.md",
"chars": 12126,
"preview": "# 在阿里做了5年技术Leader,我总结出这些套路!\n\n本文的作者是阿里的技术Leader——**云狄**,他将从管理的角度分享技术 TL 的核心职责,主要分为如下几个方面与大家共同探讨、交流:\n\n* 团队建设\n* 团队管理\n* 团队文化"
},
{
"path": "docs/framework/agility.md",
"chars": 3187,
"preview": "# 如何理解敏捷开发\n\n## 为什么要敏捷开发\n\n“没有人喜欢敏捷,但我们不得不敏捷。就像没有人喜欢工作,但你必须工作。”这是我经常用来调侃敏捷的一句话。试想一下,拿到一份完整详尽的需求文档,逐个功能Coding,测试部署上线。不需要再次确"
},
{
"path": "docs/framework/algorithm-ten.md",
"chars": 4381,
"preview": "# 必学的 10 大算法\n\n>10 大常用机器学习算法,包括线性回归、Logistic 回归、线性判别分析、朴素贝叶斯、KNN、随机森林等。\n\n## 线性回归\n\n在统计学和机器学习领域,线性回归可能是最广为人知也最易理解的算法之一。\n\n预测"
},
{
"path": "docs/framework/data_middle.md",
"chars": 11746,
"preview": "# 数据中台的思考与总结\n\n## 数据中台\n\n\n\n### 数据汇聚\n\n数据汇聚是数据中台必须提供的核心工具,把各种异构网络、异构数据源的"
},
{
"path": "docs/framework/fgb.md",
"chars": 1199,
"preview": "# 怎么理解分布式、高并发、多线程?\n\n是不是很多人都认为分布式=高并发=多线程?\n\n当面试官问到高并发系统可以采用哪些手段来解决,或者被问到分布式系统如何解决一致性的问题,是不是一脸懵逼?\n \n一开始,不少人都会将三者混淆,误以为所谓的分"
},
{
"path": "docs/framework/fwork.md",
"chars": 9450,
"preview": "# 走向架构师必备的技能\n\n中国有很多年轻人,他们18,9岁或21,2岁,通过自学也写了不少代码,他们有的代码写的很漂亮,一些技术细节相当出众,也很有钻研精神,但是他们被一些错误的认识和观点左右,缺乏对系统,对程序的整体理解能力,这些人,一"
},
{
"path": "docs/framework/split.md",
"chars": 6522,
"preview": "# 架构拆分的代价之一二三\n\n架构拆分可以用来节省人们执行事务生命周期活动所需的时间,这就是传说中购买“寸光阴”的方式,也是传说中的“银弹”。不过要获得这个“银弹”,也不是没有代价的。但既然节省的是时间,而时间又是无价的,因此人们也愿意采用"
},
{
"path": "docs/go/go_base.md",
"chars": 40299,
"preview": "\n# Go基础语法\n\n## 模块一:Go 语言特性\n\n\n##### 统一思想- 12 factors\n\nI. 基准代码\n一份基准代码,多份部署\n\nII. 依赖\n显式声明依赖关系\n\nIII. 配置\n在环境中存储配置\n\nIV. 后端服务\n把后端"
},
{
"path": "docs/index.md",
"chars": 298,
"preview": "# 朽木自雕\n\n 活在当下,活着就要发挥,就要创造\n\n## 个人爱好,纯属扯蛋\n\n## 捐赠\n\n如果你觉得这写文章能帮助到了你,你可以帮作者买一杯果汁表示鼓励\n\n\n\n[Paypal Me](h"
},
{
"path": "docs/java/bio-nio.md",
"chars": 3350,
"preview": "# 关于BIO和NIO的理解\n摘要: 关于BIO和NIO的理解\n\n最近大概看了ZooKeeper和Mina的源码发现都是用Java NIO实现的,所以有必要搞清楚什么是NIO。下面是我结合网络资料自己总结的,为了节约时间图示随便画的,能达意"
},
{
"path": "docs/java/feature.md",
"chars": 53224,
"preview": "# Java 新特性总结\n\n总结的这些新特性,都是自己觉得在开发中实际用得上的。\n简单概括下就是:\n\n* JAVA1.3:普通的原始的JAVA,基本语法相信大家都见过了\n* JAVA1.4:assert关键字\n* JAVA5:枚举类型、泛型"
},
{
"path": "docs/java/java-simple.md",
"chars": 37132,
"preview": "# Java 代码精简\n\n## 利用语法\n\n### 利用三元表达式\n\n普通\n\n``` java\nString title;\nif (isMember(phone)) {\n title = \"会员\";\n} else {\n titl"
},
{
"path": "docs/java/java-string.md",
"chars": 9641,
"preview": "# String性能提升10倍的几个方法\n\nString 类型是我们使用最频繁的数据类型,没有之一。那么提高 String 的运行效率,无疑是提升程序性能的最佳手段。\n我们本文将从 String 的源码入手,一步步带你实现字符串优化的小目标"
},
{
"path": "docs/java/java-utils.md",
"chars": 9555,
"preview": "# java常用工具库使用\n\n\n\n## 字符串相关工具类\n\nJava 中 String 应该是日常用的最多一个类吧,平常我们很多代码需要围绕 String ,做一些"
},
{
"path": "docs/java/java-validator.md",
"chars": 11699,
"preview": "# Validator 注解使用\n\n## 为什么要用validator\n\n* javax.validation的一系列注解可以帮我们完成参数校验,免去繁琐的串行校验\n\n不然我们的代码就像下面这样:\n\n``` java\n/**\n * "
},
{
"path": "docs/java/javavm.md",
"chars": 24397,
"preview": "# Java 虚拟机\n<nav>\n<a href=\"#一基本概念\">一、基本概念</a><br/>\n<a href=\"#二Java-内存区域\">二、Java 内存区域</a><br/>\n &nb"
},
{
"path": "docs/java/load-class.md",
"chars": 6729,
"preview": "# 谈谈 Java 类加载机制\n\n最近在学习 Tomcat 架构,其中很重要的一个模块是类加载器,因为以前学习的不够深入,所以趁这个机会好好把类加载机制搞明白。\n\n<!-- TOC -->\n\n- [Overview](#overview)\n"
},
{
"path": "docs/java/orm.md",
"chars": 1739,
"preview": "# 浅析 Mybatis 与 Hibernate 的区别与用途\n\n有很长一段时间对mybatis是比较陌生的,只知道与Hibernate一样是个orm数据库框架。随着使用熟练度的增加,发现它与Hibernate区别是非常大的,应当结合不同的"
},
{
"path": "docs/java/rocketmq/rmq-1.md",
"chars": 1689,
"preview": "# RocketMq下载与安装\n\n本文讲解下载并安装单机版RocketMq,linux环境。\n\n### 正文介绍:\n\n目前 RocketMQ 已经成为Apache 顶级项目 。 在阿里内部, RocketMQ 很好地服务了 集 团大大小小上"
},
{
"path": "docs/java/spring-cloud.md",
"chars": 21070,
"preview": "# 什么是Spring Cloud\n\n>Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式会话,群集状态)。"
},
{
"path": "docs/java/springAnnotation.md",
"chars": 5342,
"preview": "# Spring 中的 18 个注解\n\n## 1 @Controller\n\n标识一个该类是Spring MVC controller处理器,用来创建处理http请求的对象.\n```java\n@Controller\npublic class "
},
{
"path": "docs/java/springdesign.md",
"chars": 7019,
"preview": "# Spring 常用三种设计模式\n\n关于设计模式,如果使用得当,将会使我们的代码更加简洁,并且更具扩展性。本文主要讲解Spring中如何使用策略模式,工厂方法模式以及Builder模式。\n\n## 策略模式\n\n关于策略模式的使用方式,在Sp"
},
{
"path": "docs/js/baidu-tongji.js",
"chars": 1419,
"preview": "\nvar _hmt = _hmt || [];\n(function() {\n let hm = document.createElement(\"script\");\n // rosemarys.gitee.io\n hm.src = \"h"
},
{
"path": "docs/js/extra.js",
"chars": 588,
"preview": "\n(function () {\n let generator = document.getElementsByTagName(\"meta\").generator; \n generator.name=\"keywords\";\n gene"
},
{
"path": "docs/js/google.js",
"chars": 594,
"preview": "// burningmyself.gitee.io\n// Global site tag (gtag.js) - Google Analytics\n/* <script async src=\"https://www.googletagman"
},
{
"path": "docs/kubernetes/k8s_controller_manager.md",
"chars": 35113,
"preview": "# kubernetes 控制平面组件\n\n- kube-scheduler\n- Controller Manager\n- kubelet\n- CRI\n- CNI\n- CSI\n\n## kuber-scheduler\n\nkube-schedul"
},
{
"path": "docs/kubernetes/k8s_etcd.md",
"chars": 22028,
"preview": "# Kubernetes 控制平面组件:etcd\n\n## etcd\n\nEtcd是CoreOS基于Raft开发的分布式key-value存储,可用于服务发现、共享配置以及一致性\n保障(如数据库选主、分布式锁等)。\n\n在分布式系统中,如何管理节"
},
{
"path": "docs/kubernetes/k8s_fw_rule_and_object_design.md",
"chars": 21644,
"preview": "\n# Kubernet\n\n## Kubernetes 架构原则和对象设计\n\n### 什么是云计算\n\n,又或者是读写分离的设计。但"
},
{
"path": "docs/micro/spring-cloud-micro.md",
"chars": 8194,
"preview": "# 基于SpringCloud分布式架构\n\n## 为什么要使用分布式架构\n\n* Spring Cloud 专注于提供良好的开箱即用经验的典型用例和可扩展性机制覆盖\n* 分布式/版本化配置\n* 服务注册和发现\n* 路由\n* Service-t"
},
{
"path": "docs/net/c_core_safety.md",
"chars": 3223,
"preview": "# 让你的ASP.NET Core应用程序更安全\n\n对于ASP.NET Core应用程序,除了提供认证和授权机制来保证服务的安全性,还需要考虑下面的一些安全因素:\n\n* CSRF\n\n* 强制HTTPS\n\n* 安全的HTTP Headers\n"
},
{
"path": "docs/net/c_core_study_route.md",
"chars": 8339,
"preview": "# ASP.NET Core开发者指南\n\n> 2019年[ASP.NET Core](https://docs.microsoft.com/zh-cn/aspnet/core/?view=aspnetcore-2.2)开发者指南:\n\n你可以"
},
{
"path": "docs/net/c_docker.md",
"chars": 3785,
"preview": "# .NET Core 微服务架构-Docker部署\n\n本文主要介绍通过Docker来部署通过.NET Core开发的微服务架构,部署的微服务主要包括统一网关(使用Ocelot开发)、统一认证(IdentityServer4)、应用服务(A"
},
{
"path": "docs/net/c_sharp.md",
"chars": 25383,
"preview": "# C# 新特性\n\n## C# 6\n### 一、字符串插值 (String Interpolation)\n\nC# 6之前我们拼接字符串时需要这样\n```C#\n var Name = \"Jack\";\n var results = \"Hello"
},
{
"path": "docs/net/c_sqlserver_nginx.md",
"chars": 12083,
"preview": "# ASP.NET Core 实战:使用 Docker 容器化部署 ASP.NET Core + sqlserver + Nginx\n\n### 一、前言\n\n 在之前的文章(ASP.NET Core 实战:Linux 小白的 .NET Co"
},
{
"path": "docs/php/kj.md",
"chars": 4300,
"preview": "# PHP\n\n在PHP开发中,选择合适的框架有助于加快软件开发,节约宝贵的项目时间,让开发者专注于功能的实现上。由于流行的框架经过了大量项目的检验,所以使用框架还有助于创建更加稳定和安全的应用程序。本文搜集了目前全球最流行的25款PHP框架"
},
{
"path": "docs/python/fabric.md",
"chars": 2825,
"preview": "# 远程部署神器 Fabric,支持 Python3\n\n如果你搜一圈 “Fabric “关键字,你会发现 90% 的资料都是过时的,因为现在 Fabric 支持 Python3,但是它又不兼容旧版 Fabric。所以,如果你按照那些教程去操"
},
{
"path": "docs/python/feature.md",
"chars": 12122,
"preview": "# Python新特性\n## Python2.x与3.x版本区别\nPython的3.0版本,常被称为Python 3000,或简称Py3k。相对于Python的早期版本,这是一个较大的升级。 \n为了不带入过多的累赘,Python 3"
},
{
"path": "docs/python/str_joint.md",
"chars": 3189,
"preview": "# Python 拼接字符串的 7 种方式\n## 1、来自C语言的%方式\n```python\nprint('%s %s' % ('Hello', 'world'))\n>>> Hello world\n```\n%号格式化字符串的方式继承自古老的"
},
{
"path": "docs/python/syntax_rule.md",
"chars": 3537,
"preview": "# Python 语法技巧\n\nPython 开发中有哪些高级技巧?这是知乎上一个问题,我总结了一些常见的技巧在这里,可能谈不上多高级,但掌握这些至少可以让你的代码看起来 Pythonic 一点。如果你还在按照类C语言的那套风格来写的话,在 "
},
{
"path": "docs/sql/data_split.md",
"chars": 3297,
"preview": "# 数据库之互联网常用分库分表方案\n\n## 一、数据库瓶颈\n\n不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值。在业务Service来看就是,可用数据库连接少甚至无连接可用。接"
},
{
"path": "docs/sql/mybatis.md",
"chars": 11996,
"preview": "# Mybatis使用心德\n\n## 什么是Mybatis?\n\n1. Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂"
},
{
"path": "docs/sql/mysql_backups.md",
"chars": 10340,
"preview": "# 数据备份与恢复\n\n<nav>\n<a href=\"#一备份简介\">一、备份简介</a><br/>\n <a href=\"#21-备份分类\">2.1"
},
{
"path": "docs/sql/mysql_index.md",
"chars": 6166,
"preview": "# MySQL索引优化\n---\n本文主要讨论MySQL索引的部分知识。将会从MySQL索引基础、索引优化实战和数据库索引背后的数据结构三部分相关内容,下面一一展开。\n\n## 一、MySQL——索引基础\n\n首先,我们将从索引基础开始介绍一下什"
},
{
"path": "docs/sql/mysql_log.md",
"chars": 3237,
"preview": "# MySQL查询日志\nMySQL中的日志包括:错误日志、二进制日志、通用查询日志、慢查询日志等等。这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志。\n1. 通用查询日志:记录建立的客户端连接和执行的语句。\n\n2. 慢查询日志:记"
},
{
"path": "docs/sql/mysql_pxc.md",
"chars": 5388,
"preview": "# Docker 搭建pxc集群 + haproxy + keepalived 高可用\n\n## docker基本指令:\n1. 更新软件包\n```shell\nyum -y update\n```\n2. 安装Docker虚拟机(centos 7)"
},
{
"path": "docs/sql/mysql_use.md",
"chars": 2479,
"preview": "# 埋在MySQL数据库应用中的17个关键问题!\n\nMySQL的使用非常普遍,跟MySQL有关的话题也非常多,如性能优化、高可用性、强一致性、安全、备份、集群、横向扩展、纵向扩展、负载均衡、读写分离等。要想掌握其中的精髓,可得花费不少功力,"
},
{
"path": "docs/sql/mysql_yh.md",
"chars": 5090,
"preview": "# MySQL 优化指南\n\n## 慢查询日志 开启撒网模式\n\n开启了MySQL慢查询日志之后,MySQL会自动将执行时间超过指定秒数的SQL统统记录下来,这对于搜罗线上慢SQL有很大的帮助。\n\n``` sql\nSHOW VARIABLES "
},
{
"path": "docs/sql/mysql_yh17.md",
"chars": 4542,
"preview": "# 项目中常用的19条MySQL优化\n\n## 一、EXPLAIN\n\n做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划。\n\n下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据\n\n是基于 Java 开发的实时应用监控平台,包括实时应用监控,业务监控。\n\nCAT 作为服务端项目基础组件,提供了 Java,"
},
{
"path": "docs/tool/cicd.md",
"chars": 3818,
"preview": "# 推荐 10 个好用的 CI/CD 工具\n\n- 虽然云平台的到来让开发者免于安装和维护物理服务器,但测试和部署代码过程依旧需要人为完成,持续集成可以自动消除构建、测试和部署代码的大部分痛苦。如果希望最大限度提高效率,持续集成和交付工具是最"
},
{
"path": "docs/tool/git.md",
"chars": 5575,
"preview": "# Git 常用命令速查手册\n\n\n\n## 初始化仓库\n\n``` s\ngit init\n```\n\n## 设置远程仓库地址后再做push\n\n''' s\ngit remote add "
},
{
"path": "docs/tool/gitbook.md",
"chars": 8331,
"preview": "# GitBook 使用教程\n首先先献上 我的 [blog](https://burningmyself.github.io/blog/ \"blog\") 地址,可以在我的博客导航栏处找到,下面进行相关的介绍。\n## 背景\n由于之前都把零散的"
},
{
"path": "docs/tool/gitcmr.md",
"chars": 7079,
"preview": "# Git提交日志规范\n\n在软件开发流程中,git或者其他的版本控制工具已经成为必不可少的一部分。Git每次提交代码都需要写commit message,否则不允许提交,一般来说commit message应该清晰明了,说明本次提交的目的,"
},
{
"path": "docs/tool/gitflow.md",
"chars": 5650,
"preview": "# Git基本命令和GitFlow工作流 \n---\n### git 团队协作的一些命令\n\n1. 开分支\n```\ngit branch 新分支名\n例如,在master分支下,新开一个开发分支:\ngit branch dev\n```\n2. 切换"
},
{
"path": "docs/tool/gitquestion.md",
"chars": 3126,
"preview": "# Git 使用过程中遇到的问题以及解决办法\ngit 是项目当中最常用的代码管理库,熟练的使用git不是万能的,但不能熟练的使用git是万万不能的,归纳了一下真正开始在多人协作的代码库中提交自己的代码时遇到的问题。\n## git fetch"
},
{
"path": "docs/tool/gitstudy.md",
"chars": 9651,
"preview": "# 30 分钟让你掌握 Git 的黑魔法\n\n## 担忧\n\n很多人怕使用 git,我个人觉得主要可能是两部分的原因:\n\n* 没接触过:平时接触的代码还托管在 SVN 或 CVS 等工具上。\n* 不太熟悉:可能对 git 的使用还不太熟悉和全面"
},
{
"path": "docs/tool/gitusual.md",
"chars": 4553,
"preview": "# 10 大 Git 命令 动画展示\n\n>git merge、git rebase、git reset、git revert、git fetch、git pull、git reflog 你知道这些 git 命令执行的究竟是什么任务吗?如果你"
},
{
"path": "docs/tool/markdown.md",
"chars": 4796,
"preview": "## 主要内容\n> #### Markdown*是什么*?\n> #### *谁*创造了它?\n> #### *为什么*要使用它?\n> #### *怎么*使用?\n> #### *谁*在用?\n> #### 尝试一下\n\n## 正文\n### 1. M"
},
{
"path": "docs/tool/minio.md",
"chars": 3334,
"preview": "# MinIO 搭建使用\n\n## MinIO简介\n\nMinIO 是一款基于Go语言的高性能对象存储服务,在Github上已有19K+Star。它采用了Apache License v2.0开源协议,非常适合于存储大容量非结构化的数据,例如图"
},
{
"path": "docs/tool/mkdocs.md",
"chars": 11858,
"preview": "# mkdocs简单使用\n\n[官网](http://www.mkdocs.org/)\n\n## 一、安装\n\n``` python\n# 查看 python 版本\npython --version\n# Python 2.7.2\n\n# 查看 pip"
},
{
"path": "docs/web/ali_js_style.md",
"chars": 56719,
"preview": "# Airbnb JavaScript Style Guide() {\n\n**用更合理的方式写 JavaScript**\n\n[ => arr.every(fn);\n\nall([4, 2, 3], x =>"
},
{
"path": "docs/web/node.js.md",
"chars": 1519,
"preview": "## Node 介绍\n\n- Node 中的 JavaScript\n + EcmaScript\n * 变量\n * 方法\n * 数据类型\n * 内置对象\n * Array\n * Object\n * D"
},
{
"path": "docs/web/react.md",
"chars": 6563,
"preview": "# React 开发者指南\n\n> 该指南将助你在 2019 成为一名 React 开发者\n\n你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 React 开发者。“作为 React 开发者,我接下来应该学习什么"
},
{
"path": "docs/web/react_interview.md",
"chars": 14379,
"preview": "# React 面试问题\n>如果你是一位有理想的前端开发人员,并且正在准备面试,那么这篇文章就是为你准备的。本文收集了 React 面试中最常见的 50 大问题,这是一份理想的指南,让你为 React 相关的面试做好充分的准备工作。首先我们"
},
{
"path": "docs/web/vue_cp_react.md",
"chars": 12914,
"preview": "# 前端框架用vue还是react?清晰对比两者差异\n\n## 前言\n\n近两年前端技术层出不穷,目前市面上已经有了很多供前端人员使用的开发框架,转眼19年已过大半,前端框架领域日趋成熟,实现了三足鼎立的局面,截止到10月22日,Angular"
},
{
"path": "mkdocs.yml",
"chars": 11046,
"preview": "site_name: BurningMyself\nsite_description: .net,java,php,python,docker,web\nsite_author: BurningMyself\nsite_url: https://"
}
]
About this extraction
This page contains the full source code of the burningmyself/burningmyself.github.io GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 177 files (3.6 MB), approximately 951.7k tokens, and a symbol index with 2 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.