Kubernets 底层原理和实操 (学习圣经)
Kubernets 简称 k8s,用于自动部署,扩展和管理容器化应用程序的开源系统。也就是能帮我们部署和管理分布式系统。
![](https://i-blog.csdnimg.cn/blog_migrate/fadf9c3df6c14b979ca85e2282d68f6b.png)
学习 Kubernets 的相关资料
中文官网:https://kubernetes.io/zh-cn/docs/
官方文档:https://kubernetes.io/zh/docs/home/(推荐)
中文社区:https://www.kubernetes.org.cn/
社区文档:http://docs.kubernetes.org.cn/
Kubernetes API 规约:community/api-conventions.md at master · kubernetes/community (github.com)
Kubernetes kubectl 命令表: http://docs.kubernetes.org.cn/683.html
说在前面:
现在拿到offer超级难,甚至连面试电话,一个都搞不到。
尼恩的技术社群中(50+),很多小伙伴凭借 “左手云原生+右手大数据”的绝活,拿到了offer,并且是非常优质的offer,据说年终奖都足足18个月。
从Java高薪岗位和就业岗位来看,K8S 现在对于 高级工程师, 架构师,越来越重要,下面是一个高薪Java岗位的K8S技能要求:
但是 K8S 又很难。在这里,尼恩从架构师视角出发,基于自己的尼恩Java 架构师知识体系和知识宇宙,对K8S的核心原理做一个宏观的介绍, 一共十二部分, 组成一本《K8S学习圣经》
《K8S学习圣经》 带大家穿透K8S,实现K8S自由,让大家不迷路。
《K8S学习圣经》的组成
- 第一部分:云原生(Cloud Native)的原理与演进
- 第二部分:穿透K8S的8大宏观架构
- 第三部分:最小化K8s环境实操
- 第四部分:Kubernetes 基本概念
- 第五部分:Kubernetes 工作负载
- 第六部分:Kubernetes 的资源控制
- 第七部分: SVC负载均衡底层原理
- 第八部分: Ingress底层原理和实操
- 第九部分: 蓝绿发布、金丝雀发布、滚动发布、A/B测试 实操
- 第十部分: 服务网格Service Mesh 宏观架构模式和实操
- 第十一部分: 使用K8S+Harber 手动部署 Springboot 应用
- 第十二部分: SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
- 第十三部分: k8s springboot 生产实践(高可用部署、基于qps动态扩缩容、prometheus监控)
- 第十四部分:k8s生产环境容器内部JVM参数配置解析及优化
米饭要一口一口的吃,不能急。
结合《K8S学习圣经》,尼恩从架构师视角出发,左手云原生+右手大数据 +SpringCloud Alibaba 微服务 核心原理做一个宏观的介绍。由于内容确实太多, 所以写多个pdf 电子书:
(1) 《 Docker 学习圣经 》PDF (V1已经完成)
(2) 《 SpringCloud Alibaba 微服务 学习圣经 》PDF (V1已经完成)
(3) 《 K8S 学习圣经 》PDF (coding…)
(4) 《 flink + hbase 学习圣经 》PDF (planning …)
以上学习圣经,并且后续会持续升级,从V1版本一直迭代发布。 就像咱们的《 尼恩 Java 面试宝典 》一样, 已经迭代到V60啦。
40岁老架构师尼恩的掏心窝: 通过一系列的学习圣经,带大家穿透“左手云原生+右手大数据 +SpringCloud Alibaba 微服务“ ,实现技术 自由 ,走向颠覆人生,让大家不迷路。
本PDF 《K8S 学习圣经》完整版PDF的 V1版本,后面会持续迭代和升级。供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。
以上学习圣经的 基础知识是 尼恩的 《 高并发三部曲 》,建议在看 学习圣经之前,一定把尼恩的《 Java高并发三部曲 》过一遍,切记,切记。
注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请到《技术自由圈》公众号获取
本书目录
- 学习 Kubernets 的相关资料
- 说在前面:
- 《K8S学习圣经》的组成
- 本书目录
- 第1部分:云原生(Cloud Native)的原理与演进
- 1、什么是云原生(Cloud Native)?
- 云原生的四要素:
- 2、云原生发展历史时间轴
- 2.1 从微服务到服务网格
- 2.2 微服务架构的问题
- 解决方案:
- 2.3 SideCar 旁车模式(边车模式)
- 3、2018 年云原生被CNCF重新定义
- 3.1 服务网格 (Service Mesh)
- 3.2 不可变基础设施(Immutable Infrastructure)
- 3.3 声明式API ( declarative APIs)
- 4、CNCF云原生组织发展和介绍
- 什么是CNCF
- CNCF解决了什么问题
- 介绍几个常用的已经毕业的云原生项目
- 孵化中的项目
- 5、从微服务演进到Service Mesh(服务网格)的过程
- 5.1 单体服务时代
- 5.2 微服务时代
- 5.3 服务网格新时期 (service mesh)
- 6、服务网格(service mesh)原理和价值
- 什么是服务网格(service mesh)
- Service Mesh的价值
- Linkerd
- istio
- 国内兴起的服务网格
- 7、云原生应用和传统应用的区别
- 8、云原生涉及的核心项目
- 1、什么是云原生(Cloud Native)?
- 第2部分:穿透K8S的8大宏观架构
- 尼恩的K8S的独特视角:不是普通的视角
- K8S的核心价值:带领大家从 容器管理的石器时代,进入工业时代
- 图0:K8S 的宏观组件架构图
- 图1:K8S 业务架构图
- 图2:K8S 元数据架构图
- 图3:K8S 容器管理流程架构
- 图4:容器元数据的数据传输架构
- 图5:容器对外暴露架构图
- 图6:总的架构图
- 图7:master 上APIServer 内部架构图
- 图8:worker上 kubelet内部架构图
- 学习 云原生+ 微服务的神器
- 第3部分:K8s运行时 实操
- 什么是minikube
- minikube 背景
- Kubernetes集群架构 与minikube架构对比
- 1、Kubernetes集群架构
- 2、Minikube架构
- minikube安装前准备
- docker安装和环境检查
- docker 版本要求
- 关闭虚拟机swap、selinux、firewalld
- 编辑虚拟机hosts文件
- 登录阿里云
- 创建用户,加入docker用户组
- 让用户minikube获得root权限
- 安装与启动minikube
- 软件版本说明
- 安装minikube
- 启动minikube
- 命令清单:血泪的安装史,尼恩用过的 命令list
- minikube start 参数
- 示例
- –vm-driver=kvm2
- –vm-driver=hyperv
- –vm-driver=none
- 解决拉取镜像的问题
- 错误日志查看
- Q1:解决minikube拉取镜像速度缓慢的问题
- 解决 minikube
start
过程中拉取镜像慢的问题
- 解决 minikube
- Q2:基础镜像拉不下来
- 错误日志查看
- 基础镜像拉不下来
- 指定镜像启动
- 终于开始创建容器,开始启动了
- Q3:新的问题来了:coredns 镜像找不到
- Q4:继续下载镜像
- Q5:使用阿里云代理http://k8s.gcr.io镜像仓库
- Virtual Box 使用的问题
- Q1:嵌套虚拟化问题
- 什么是嵌套 虚拟化特性?
- 虚拟机启用嵌套VT-x/AMD-V
- Q2:conntrack依赖
- Q3:依赖kubectl、kubelet
- Q4:桥接问题
- Q5:初始化失败报错,升级内核
- 启动Dashboard
- 终于全部启动了
- 如何从宿主机也就是我们的Windows中访问dashborad呢
- 直接使用minikube
- minikube重建
- Q1:嵌套虚拟化问题
- docker-compose to minikube
- 部署minikube 遇到的问题
- 外部访问问题
- pull image问题
- POD 容器的问题
- K8s的常用命令
- 查看所有的pod,看看哪些有问题
- storage-provisioner 的ImagePullBackOff 状态
- 启动minikube时指定harber仓库
- minikube 复制证书
- 进入minikube虚拟机
- 增加私仓地址配置
- 重启虚拟机的Docker
- 测试
- 命令清单:尼恩用过的 启动 命令清单 (都是血和泪)
- minikube常用命令
- 一、基本命令
- 二、镜像命令
- 三、配置和管理命令
- 四、网络和连接命令
- 五、高级命令
- 六、疑难解答命令
- 七、其它命令
- 启动minikube完整的命令清单
- Helm 的原理、安装、使用
- Helm 组件及相关术语
- Helm 工作原理
- 安装Helm
- 第4部分:Kubernetes 基本概念
- 1、基础概念理解
- K8S集群
- Node的核心组件
- Pod
- Label
- Deployment
- Service
- Addons
- DNS
- Web UI (Dashboard)
- 2、k8s对象(kubernetes Objects)
- 对象的yaml结构
- 关于 yaml文件的分割
- 2.1 一个简单的Kubernetes API 对象
- 2.1 什么是k8s 资源对象
- kubernetes 对象必需字段
- 2.2 kubernetes API的版本
- 一、查看apiversion 可用版本
- 二、各种apiVersion的含义
- 2.3 获取各个属性字段的含义
- 方式1:从命令行获取方式
- 方式2:官方 API 文档方式
- 2.4、管理k8s对象
- 1、命令式
- 2、指令性
- 3、声明式
- 2.5、对象名称与ID
- Names
- UID
- 2.6 对象规约(Spec)与状态(Status)
- 对象规约(Spec)与状态(Status)
- spec 规约
- status 状态
- 2.7、名称空间
- 名称空间的使用参考:
- 如何访问其他名称空间的东西?
- 查看名称空间
- 在执行请求的时设定namespace
- 设置名称偏好
- 名称空间与DNS
- 名称空间的作用
- 并非所有对象都在命名空间中
- 2.8 、标签和选择器
- 2.9、注解annotation
- 2.8、字段选择器
- 2.10、认识kubectl 客户端命令
- kubectl的所有命令参考:
- 2.11、自动补全
- 2.12、给idea安装kubernetes插件
- 1、plugins kubernetes
- 2、快速生成kubernetes 资源文件模板
- 3、输入
k
即可触发自动命令提示
- 1、基础概念理解
- 第5部分:Kubernetes 工作负载
- 什么是Workloads?
- Pod的原理与生命周期
- 1、什么是Pod
- 2、Pod使用
- 3、Pod生命周期
- “根容器” : Pause 容器
- Pod中容器也有分类
- Pod生命周期的 两个阶段
- Pod的Init 初始化容器 (附Demo)
- Pod 钩子Hook方法 (附Demo)
- Pod 健康检查(探针)机制
- Pod 的状态和重启策略
- Pod 常见的状态
- Pod重启策略
- Pod常见状态转换场景
- 临时容器:线上排错
- 使用方法:
- 通过临时容器查看Java容器log日志
- 临时容器的参数说明:
- 使用临时容器进行 dump 转储
- 基于制作Java Debug 镜像
- 临时容器不能用jmap、jps而只能用jattach
- jattach指令集:
- 临时容器的配置
- 临时容器的使用场景
- 静态Pod
- 如何找到 静态pod 的文件路径
- 静态Pod实操
- Pod 资源需求和限制
- Pod的Probe 探针机制(健康检查机制)
- Probe 探针 背景
- K8S 的3种探针
- livenessProbe和readinessProbe 的区别
- (1)livenessProbe
- (2)readinessProbe
- (3)就绪、存活两种探针的区别
- 存活探针 (liveness)的三种探测方法
- exec 方式示例
- httpGet 方式示例
- TCP 方式示例
- 使用命名的端口
- 就绪探针 (readiness)
- ReadinessProbe 探针使用示例
- ReadinessProbe + LivenessProbe 配合使用示例
- 以上案例中存活探针 参数意思:
- 以上案例中就绪探针 参数意思:
- startupProbe探针
- 1、startupProbe探针介绍
- 2、startupProbe探针与另两种区别
- 3、startupProbe探针方法、属性
- 4、为什么要使用startupProbe、使用场景
- 第6部分:Kubernetes 的资源控制
- 动态的扩容缩容的重要性
- 1:Deployment 资源对象
- Deployment的创建
- Deployment 资源、replicaset资源、Pod资源 三者之间的关系
- Deployment 基本操作
- 副本扩容
- 副本缩容
- Deployment 更新机制
- 准备:升级镜像
- 在线修改yaml
- 滚动机制相关的命令
- 暂停和恢复
- 回滚策略
- 记录保留
- 滚动更新数量
- 使用Deployment 进行灰度发布
- 2:副本资源 RC、副本集RS 资源对象
- RC(Replication Controller)
- RS(Replication Set)
- ReplicatSet的三个部分
- RS扩容缩容
- 3:DaemonSet 守护集
- DaemonSet 组成结构详解
- 调度节点的选择
- 方式一:nodeSelector方式
- 方式二:nodeAffinity方式
- 方式三:podAffinity方式
- Toleration
- 4:StatefulSet 有状态集
- StatefulSet 使用场景
- StatefulSet的一些限制和要求
- StatefulSet示例
- DNS解析
- StatefulSet 的几个要点
- (1)pod管理策略(podManagementPolicy)
- (2)updateStrategy: 更新策略
- (3)对应的headless service
- 5:Job 任务、CronJob 定时任务
- Job 任务
- 并行 job 示例
- CronJob 定时任务
- CronJob示例
- 6:HPA(Horizontal Pod Autoscaling)水平自动伸缩
- 收集指标插件
- Metrics API
- 前置条件: 开启聚合路由
- metrics安装方式一:minikube 中启用指标服务器作为插件
- metrics server安装方式二:手动安装
- 执行安装和检查
- 执行安装的命令清单
- 7:使用HPA对SpringCloud微服务进行自动伸缩
- autoscale命令
- Metrics支持的指标
- 创建hpa、查看hpa、删除hpa
- HPA扩容实操
- 基于自定义指标的自动扩容
- 扩展阅读: GC机制
- 什么是垃圾回收
- 什么是OCI、CRI、CNI、CSI
- OCI、CRI、CNI、CSI、CRD、CNM规范基本概念:
- 实现OCI、CRI、CNI、CSI组件介绍
- 1、OCI、CRI组件
- 2、CNI组件
- CNI 和 CNM 的对比:
- 3、CSI组件
- CRI、OCI的关系
- CRD是什么
- CR是什么
- CRD与CR的关系
- CRD在API Server中的设计和实现机制
- 如何创建 CRD?
- 第7部分:SVC负载均衡底层原理
- Pod的IP 漂移问题
- service 概念
- 四大service 类型
- kubernetes暴露端口的方式
- 1:集群内部实现访问:Clusterip
- 2:集群外部方式访问:NodePort
- 3: LoadBalancer
- 4: Ingress
- DNS解析案例
- 案例
- SVC 流量分发的底层原理
- VIP 和 Service 代理
- 代理模式分类
- Ⅰ、userspace 代理模式
- Ⅱ、Iptables 代理模式
- Ⅲ、ipvs 代理模式
- ipvs为负载均衡提供算法:
- ipvs 对比 iptables
- iptables/netfilter 介绍
- 1,iptables/netfilter介绍
- 2,iptables 基础:
- 3,链的概念:
- 4,表的概念:
- 5,数据经过防火墙的流程图:
- 6,规则:
- 总结: iptables包含4个表,5个链
- iptables 在 K8s 中的应用剖析
- 路由的流程分析:
- service 的路由分析实例
- 先看iptables 中的DNAT
- 再看SNAT
- 基于客户端地址的会话保持模式的svc负载分发策略
- k8s集群中service的域名解析、pod的域名解析
- service的域名
- 1、创建namespace.yaml文件
- 2、创建deployment.yaml文件
- 3、创建service.yaml文件
- 4、测试
- 总结
- service的域名
- 应用持久化存储(PV和PVC)
- 1、Volume
- 1.1、emptyDir
- 1.2、hostPath
- 1.3、外部存储(以NFS为例)
- 2、PV与PVC
- 持久卷的存储插件类型
- 2.1、Static PV
- 1)先搭建好NFS服务器(192.168.100.172)
- 2)创建PV
- 3)创建PVC
- 4)创建Pod
- 2.2、Dynamic PV
- Dynamic PV属于PV的自动化:
- 什么是StorageClass
- 为什么需要StorageClass
- StorageClass案例
- 运行原理
- 1、Volume
- 第8部分:K8S Ingress原理和实操
- 背景:
- svc的作用与不足
- Ingress 的来源
- Ingress的构成
- 什么是Ingress Controller?
- Ingress 资源对象
- ingress-controller组件
- nginx-ingress-controller
- 什么是Ingress Controller?
- 部署ingress-controller
- Minikube安装Ingress
- 手工部署ingress-controller pod及相关资源
- ingress版本的问题
- 调整RBAC api-versions 版本
- 部署 ingress-nginx
- 配置ingress资源
- 报错 failed calling webhook
- 获取 ingress 启动的svc
- 加上本地的host
- 测试访问
- 实操的善后工作
- k8s ingress的工作原理
- (1)Ingress Controller 控制器
- (2) Ingress 资源对象
- 详解ingress资源
- ingress规则
- DefaultBackend
- 资源后端
- 路径类型
- 路径类型示例
- 路径多重匹配
- 主机名通配符
- ingress类
- 名字空间域的参数
- 默认ingress类
- ingress部署的三种模式
- 模式一:NodePort模式的Service
- 模式二:DaemonSet+nodeSelector+HostNetwork
- 模式三:Deployment+LoadBalancer模式的Service
- 模式一的问题:service暴露服务的问题
- DaemonSet+HostNetwork+nodeselector 实操
- nodePort的NAT性能问题
- 指定nginx-ingress-controller运行的node节点
- 修改Deployment为Daemonset,指定节点运行,并开启 hostNetwork
- 启动nginx-ingress-controller
- 查看pod的IP和端口
- 配置ingress资源
- 命令清单
- 生产环境 LVS+keepalive 做高可用和负载均衡
- 边缘节点
- 生产环境可以使用 HA + LB + DaemonSet hostNetwork 架构
- 四种port底层原理:nodePort、port、targetPort、containerPort 的核心
- 1、nodePort
- 2、port
- 3、targetPort
- 4、containerPort
- Ingress 动态域名配置底层原理
- ingress生产建议
- ingress总结
- K8s的常用命令
- kubectl命令 要求
- 背景:
- 第9部分:蓝绿发布、金丝雀发布、滚动发布、A/B测试 原理和实操
- 背景:
- 蓝绿发布、金丝雀发布、滚动发布、A/B测试 核心原理
- 蓝绿发布(Blue-green Deployments) 核心原理
- 金丝雀发布(anCanary Releases) 核心原理
- 滚动发布的 核心原理
- A/B测试(A/B Testing) 核心原理
- 蓝绿发布、金丝雀发布、滚动发布实操
- spring cloud 灰度实操
- 反向代理网关灰度实操
- Kubernetes 中的灰度策略
- Deployment金丝雀部署:按照流量比例
- step1 :启动 V1 服务,查看服务是否正确,然后观察一下服务。
- step2:启动 V2 的服务版本:1 个复本
- step3:观察 V2 流量正常的情况的话,那么启动 V2 的 2 个复本。
- step4:删除 V1 的 2 个复本,流量全部到 V2 上。
- 实操总结
- Deployment实现滚动发布
- step1:启动 V1 服务,查看服务是否正确,然后观察一下服务。
- step2:启动 app-v2-rolling 进行滚动发布
- step3:观察所有容器版本变为 V2 版本
- 实操总结
- Deployment实现蓝绿部署
- step1 :启动 V1 服务,查看服务是否正确,然后观察一下服务。
- step2:启动 V2 的服务版本
- step3:将版本 1 服务切换到版本 2,观察服务情况
- patch
- 实操总结
- Ingress Annotations实现金丝雀发布
- Ingress Annotations实现金丝雀发布 实操
- 华为云的金丝雀发布
- 参考
- 第10部分:服务网格Service Mesh 宏观架构模式
- 第1大模式:Sidecar (边车)模式 架构
- sidecar的(边车)负责的功能
- sidecar模式好处、坏处
- 如何解决依赖的复杂性和性能问题呢?
- 优化之后的sidecar模式优点:
- 第2大模式:代理模式
- 服务网格 istio 框架微服务与SpringCloud 对比
- SpringCloud 和 istio 中间组件的对比
- 云原生Sidecar分体架构微服务Provider一体架构对比
- 两大基础组件的对比
- 角色sidecar 对应到啥组件?
- 小结:
- Istio 架构
- 控制平和数据面
- Istio 的运转流程
- (1)Sidecar自动注入:
- (2)流量拦截:
- (3)服务发现:
- (4)负载均衡:
- (5)流量治理:
- (6)访问安全:
- (7)服务遥测:
- (8)策略执行:
- (9)外部访问:
- Istio组件介绍
- 2.1 Pilot
- 2.2 Mixer
- 2.3 Citadel
- 2.4 Galley
- 2.5 Sidecar-injector
- 2.6 Proxy(Envoy)
- 2.7 Ingress gateway
- 2.8 其他组件
- Istio安装
- 在本地搭建Istio环境
- Kubernetes集群环境
- 安装Istio
- 快速部署Istio
- 初步感受istio
- 手动注入
- 自动注入sidecar
- istio项目案例:bookinfo
- 什么是bookinfo
- sidecar自动注入到微服务
- 启动bookinfo
- 通过ingress方式访问
- 通过istio的ingress gateway访问
- 确定 Ingress 的 IP 和端口
- 第1大模式:Sidecar (边车)模式 架构
- 第11部分:使用K8S+Harber 手动部署 SpringCloud 应用
- 启动minikube时指定私有仓库
- minikube 复制证书
- 进入minikube虚拟机
- 增加私仓地址配置
- 重启虚拟机的Docker
- 测试
- 完整的命令清单
- Docker构建镜像后通过K8S部署
- 镜像与容器关联
- Docker构建镜像并且推送Harber
- 前提:停止或者重启 Harbor
- 创建Dockerfile
- 镜像构建:将本地镜像打包
- docker build语法
- 镜像打tag:镜像添加版本号
- 镜像推送:镜像推送到远程仓库
- 测试
- 完整的命令清单
- Docker构建镜像并且推送Harber
- k8s的Secrets:
- 创建一个k8s的Secrets:
- 1.Secret对象配置过程
- 2.容器镜像拉取的两种策略
- 2.1 ImagePullPolicy
- 2.2 ImgaePullSecrets
- k8s的configMap对象
- Pod可以通过三种方式来使用ConfigMap,分别为:
- configMap是什么
- 1.单pod使用configmap示例图
- 2.多pod使用configmap示例图
- configmap来配置环境变量
- 步骤1:创建configmap
- 方法1:yaml档来设定configmap
- 方法1:命令行设定configmap
- 步骤3:使用configmap来配置
- 步骤1:创建configmap
- docker-compose to minikube
- 简单案例
- 实操案例
- 参考的原始的docker-compose编排文件
- 设置env环境变量
- k8s向etc/hosts里添加内容
- k8s默认被重写/etc/hosts
- Dockerfile里的配置被覆盖
- 将你的配置写到k8s yml里
- Kubernetes volume hostPath explained with examples
- hostPath
- Example
- 部署和创建服务
- ImagePullBackOff错误排查
- 解决问题:停止后重启 Harbor
- CrashLoopBackOff 错误
- 坑1:镜像拉取是ok,但是依赖包没有
- 坑2:java 进程异常结束了
- 坑3:minikube是套娃虚拟机,套娃里边没有映射目录,远程复制
- 坑4:检查域名和环境变量
- 解决问题有感
- ImagePullBackOff错误排查
- 完整的命令清单
- openresty 镜像
- dockerfile
- 第12部分:SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
- 如何进行SpringCloud+Jenkins+ K8s Ingress 灰度发布?
- 回顾Nginx-ingress 架构和原理
- 灰度实操之前的准备
- 部署和测试 stable 版本的 deployment 和 svc
- 部署和测试 canary版本 的 deployment 和 svc
- 基于用户的灰度场景
- 接下来,开始基于 用户的灰度实操
- 基于权重的灰度场景
- 基于权重的 Canary 规则
- 基于权重的发布实操
- 如何进行自动化灰度?
- jenkins安装和pipeline 流水线的使用
- 下载和启动jenkins
- 登录jenkins
- 使用pipeline插件
- 安装Pipeline 插件
- pipeline 的hello world
- pipeline 语法介绍
- Jenkins插件SSH Pipeline Steps
- sshCommand 在远程节点上执行给定的命令并响应输出
- sshGet 从远程主机获取文件或目录
- sshPut 将文件或目录放入远程主机
- sshRemove 删除远程主机上的文件或目录
- sshScript 在远程节点上执行给定的脚本(文件)并响应输出
- 结合 withCredentials 从 Jenkins 凭证存储中读取私钥
- pipeline支持的指令
- ingress 灰度发布流水线设计
- CICD流水线预览
- step1:自动化的制品发布
- 1、克隆 springboot代码项目到本地
- 2、maven构建springboot代码项目
- 3、构建docker镜像
- 4、推送docker镜像到harber上,完成制品发布
- step2:生产环境进行 A/B 测试
- AB测试原理:
- step3:生产环境进行 A/B 测试
- step4:生产环境进行版本正式切换
- 最后总结一下
- 第13部分:springboot 基于 qps 动态扩缩容
- 步骤
- 1、springboot安装prometheus依赖并获取metric
- 2、安装prometheus operator 实现 kubernetes的监控指标
- 2.1 helm安装prometheus operator、prometheus adapter(custom metric)
- 2.2 kubernetes的监控指标
- Prometheus Operator 极简配置Prometheus 监控
- Operator
- Operator介绍
- Prometheus Operator vs. kube-prometheus vs. community helm chart
- Prometheus Operator CRD介绍
- 命令清单: 安装的Prometheus
- 查看安装后的CRD、svc、pods:
- 从外部访问promethus
- 访问Prometheus
- 访问Alertmanager
- 访问Grafana
- 移除kube-prometheus
- 解决prometheus-adapter创建失败的问题
- 查看 安装文件
- 解决kube-state-metrics 创建失败的问题
- 解决namespace 删除不来
- 解决prometheus-adapter创建失败的问题
- 配置prometheus -adapter获取应用qps
- prometheus采集到的metrics适配给kubernetes用
- K8s中 kubernetes的监控指标分为两种:
- Metrics-Server 简介
- prometheus-adpater
- 获取 metrics 定制化指标
- checkout 仓库 k8s-prometheus-adapter
- 脚本进行部署 k8s-prometheus-adapter
- 请求metrics.k8s.io的 api
- 直接访问 api 的方式来测试部署是否 ok
- 排错 no matches for kind “APIService” in version "apiregistration.k8s.io/v1
- 查看版本 kubectl api-versions
- Prometheus adapter 的文件介绍
- 配置文件
- resource metrics API
- 命令清单
- 自定义alertmanager的PrometheusRule
- 配置prometheus及adapter获取应用qps
- 启动springboot应用
- 添加自定义指标
- 架构图原理
- 添加一个自定义监控的步骤
- 部署prometheus-adapter
- custom-metrics-server 规则配置
- 指标发现和配置展示(Metrics Discovery and Presentation Configuration)
- http_requests(每秒请求数QPS)监控指标
- 坑: /metrics 路径的定制化修改
- 查询与 http_requests 相关的指标
- 自定义metric rules、配置HPA
- 配置自定义prometheus-adapter-config配置
- 配置 qps 请求量指标
- 查看 “pods/http_server_requests_per_second” 指标
- HPA配置
- 基于Pod做HPA
- 基于cpu或者memory做HPA
- 启动HPA的伸缩控制器
- hpa验证测试
- 配置grafana展示qps监控数据
- hpa命令清单
- 高阶知识:Adapter 的Discovery规则如何配置?
- 以获取Per-pod HTTP Requests为例
- 1 demo问题场景
- 2 配置适配器
- 3 查询api
- 以获取Per-pod HTTP Requests为例
- prometheus operator 不足之处
- 数据持久化
- tsdb 保留天数
- 告警方式不方便
- 加监控target也不方便
- 第14部分:k8s生产环境容器内部JVM参数配置解析及优化
- Java Heap基础知识
- 容器环境的Java Heap
- UseContainerSupport
- 最佳实践
- 常用容器内存大小对应的jvm内存配置
- 容器启动常用配置
- 配置项的具体介绍
- 1.堆总内存初始化大小分配和最大值分配
- 2.非堆总内存初始化大小分配和最大值分配(1.8为metaspace)
- 3.堆内存之年轻代年老代大小设置
- 4.线程栈大小
- 5.GC日志输出
- 6.每个线程堆栈大小
- 常用容器内存大小对应的jvm内存配置
- Kubernetes(k8s)配置Java服务自动Dump
- 参考:Go语音解决 java 内存溢出时候 dump 文件的存储问题
- 问题
- 方案
- 其他
- 参考文献
第1部分:云原生(Cloud Native)的原理与演进
云原生之所以解释不清楚,是因为云原生没有确切的定义,
云原生一直在发展变化之中,解释权不归某个人或组织所有。
如果要理解 Cloud Native, 首先就要理解字面意思 ,大概是:
- 首先生在云上 ,不是在本地
- 本身生在云上 ,不是在本地
- 天生长在云上 ,不是在本地
- 土生土长在云上 ,不是在本地
所以,这个概念,是建立在 云基础设施基础上的。 云基础设施有: 虚拟服务器、虚拟容器 等,代表作就是K8S。
好,接下来,就看看 官方介绍的 什么是云原生(Cloud Native)。
1、什么是云原生(Cloud Native)?
云原生之所以解释不清楚,是因为云原生没有确切的定义,
云原生一直在发展变化之中,解释权不归某个人或组织所有。
Pivotal公司的Matt Stine于2013年首次提出云原生(Cloud Native)的概念;
2015年,云原生刚推广时,
Matt Stine在《迁移到云原生架构》一书中定义了符合云原生架构的几个特征:
- 符合 12 因素应用、
- 面向微服务架构、
- 自敏捷架构、
- 基于API协作、
- 扛脆弱性;
Pivotal 推出过 Pivotal Cloud Foundry 云原生应用平台和 Spring 开源 Java 开发框架,成为云原生应用架构中先驱者和探路者。
Pivotal 是云原生应用平台第一股,2018 年在纽交所上市,2019 年底被 VMWare 以 27 亿美元收购,加入到 VMware 新的产品线 Tanzu。
到了 2015 年 Google 主导成立了云原生计算基金会(CNCF),开始围绕云原生的概念打造云原生生态体系,起初CNCF对云原生的定义包含以下三个方面:
- 应用容器化(software stack to be Containerized)
- 面向微服务架构(Microservices oriented)
- 应用支持容器的编排调度(Dynamically Orchestrated)
2017年, 云原生应用的提出者之一的Pivotal在其官网上将云原生的定义概况为DevOps、持续交付、微服务、容器这四大特征,这也成了很多人对 Cloud Native的基础印象。
云原生的四要素:
- 持续交付、
- DevOps、
- 微服务、
- 容器:
1) DevOps
DevOps(Development和Operations的组合词)即开发、运维一体化。
涉及软件在整个开发生命周期中的持续开发,持续测试,持续集成,持续部署和持续监控。
最佳实践:Git,Jenkins,Bamboo,Docker,Kubernetes
2) 持续交付
持续交付:持续交付是不误时开发,不停机更新,小步快跑,反传统瀑布式开发模型,这要求开发版本和稳定版本并存,其实需要很多流程和工具支撑。
最佳实践:CI/CD, gitlab, Jenkins,流水线pipeline,tekton等
3) 微服务 (Microservice)
几乎每个云原生的定义都包含微服务,跟微服务相对的是单体应用,
微服务有理论基础,那就是康威定律,指导服务怎么切分。
4) 容器 (Container)
2013年,Docker项目正式发布,2014年,K8s项目也正式发布。
Docker是应用最为广泛的容器引擎,在思科谷歌等公司的基础设施中大量使用。
K8S是容器编排系统,用于容器管理,容器间的负载均衡
2、云原生发展历史时间轴
2.1 从微服务到服务网格
- 微服务
马丁大师在2014年定义了微服务
- Kubernetes
从2014年6月由Google宣布开源,
到2015年7月发布1.0这个正式版本并进入CNCF基金会,再到2018年3月从CNCF基金会正式毕业,迅速成为容器编排领域的标准,是开源历史上发展最快的项目之一
- Linkerd
Scala语言编写,运行在JVM中,Service Mesh名词的创造者
2016年01月15号,0.0.7发布
2017年01月23号,加入CNCF组织
2017年04月25号,1.0版本发布
- Envoy
envoy 是一个开源的服务代理,为云原生设计的程序,由C++语言编程[Lyft]
2016年09月13号,1.0发布
2017年09月14号,加入CNCF组织
- Istio
Google、IBM、Lyft发布0.1版本
Istio是开源的微服务管理、保护和监控框架。Istio为希腊语,意思是”起航“。
2.2 微服务架构的问题
微服务时代有了Spring Cloud就完美了吗?不妨想一想会有哪些问题?
(1)最初是为了业务而写代码,比如登录功能、支付功能等,到后面会发现要解决网络通信的问题,虽然有 Spring Cloud里面的组件帮我们解决了,但是细想一下它是怎么解决的?
在业务代码里面加上spring cloud maven依赖,加上spring cloud组件注解,写配置,打成jar的时候还必须要把非业务的代码也要融合在一起,称为“侵入式框架”;
(2)微服务中的服务支持不同语言开发,也需要维护不同语言和非业务代码的成本;
(3)业务代码开发者应该把更多的精力投入到业务熟悉度上,而不应该是非业务上,Spring Cloud虽然能解决微服务领域的很多问题,但是学习成本还是较大的;
(4)互联网公司产品的版本升级是非常频繁的,为了维护各个版本的兼容性、权限、流量等,
因为Spring Cloud是“代码侵入式的框架”,这时候版本的升级就注定要让非业务代码一起,一旦出现问题,再加上多语言之间的调用,工程师会非常痛苦;
(5)其实我们到目前为止应该感觉到了,服务拆分的越细,只是感觉上轻量级解耦了,但是维护成本却越高了,那么怎么 办呢?
我们不是说spring cloud不好,只是为了引出service mesh,
目前spring cloud微服务还是比较主流的, 我们指出spring cloud的不好也只是为了突出service mesh的优点
问题解决思路
-
本质上是要解决服务之间通信的问题,不应该将非业务的代码融合到业务代码中
-
也就是从客户端发出的请求,要能够顺利到达对应的服务,这中间的网络通信的过程要和业务代码尽量无关
服务通信无非就是服务发现、负载均衡、版本控制等等
-
在很早之前的单体架构中,其实通信问题也是需要写在业务代码中的,那时候怎么解决的呢?
解决方案:
把网络通信,流量转发等问题放到了计算机网络模型中的TCP/UDP层,也就是非业务功能代码下沉,
把这些网络的问题下沉到计算机网络模型当中,也就是网络七层模型
网络七层模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
思考:
我们是否也可以把每个服务配置一个代理,所有通信的问题都交给这个代理去做,
就好比大家熟悉的nginx,haproxy其实它们做反向代理把请求转发给其他服务器,也就为 Service Mesh的诞生和功能实现提供了一个解决思路
2.3 SideCar 旁车模式(边车模式)
Sidecar模式是一种将应用功能从应用本身剥离出来作为单独进程的方式。
SideCar降低了与微服务架构相关的复杂性,并且提供了负载平衡、服务发现、流量管理、电路中断、遥测、故障注入等基础特性。
服务业务代码与Sidecar绑定在一起,每个服务都配置了一个Sidecar代理,每个服务所有的流量都经过sidecar,
sidecar帮我们屏蔽了通信的细节,我的业务开发人员只需要关注业务就行了,而通信的事情交给sidecar处理
sidecar是为了通用基础设施而设计,可以做到与公司框架技术无侵入性
该模式允许我们向应用无侵入添加多种功能,避免了为满足第三方组件需求而向应用添加额外的配置代码。
很多公司借鉴了Proxy模式,推出了Sidecar的产品,比如像Netflix的Prana,蚂蚁金服的SofaMesh
很多公司借鉴了Proxy模式,推出了Sidecar的产品, 比如像Netflix的Prana,蚂蚁金服的SofaMesh
2014年 Netflix发布的Prana
2015年 唯品会发布local proxy
2016年 Twitter的基础设施工程师发布了第一款Service Mesh项目:Linkerd (所以下面介绍Linkerd)
3、2018 年云原生被CNCF重新定义
到了 2018 年,随着近几年来云原生生态的不断壮大,
所有主流云计算供应商都加入了该基金会,
且从 Cloud Native Landscape 中可以看出, 云原生有意蚕食原先非云原生应用的部分。
CNCF 基金会中的会员以及容纳的项目越来越多,该定义已经限制了云原生生态的发展,CNCF 为云原生进行了重新定位。
2018年6月,CNCF正式对外公布了更新之后的云原生的定义(包含中文版本)v1.0版本:
Cloud native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach.
These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil.
The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of open source, vendor-neutral projects. We democratize state-of-the-art patterns to make these innovations accessible for everyone.
中文版本:
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。
云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。
云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。
我们通过将最前沿的模式民主化,让这些创新为大众所用。
新的定义中,继续保持原有的核心内容:容器和微服务,
但是非常特别的是:
将服务网格单独列出来,而不是将服务网格作为微服务的一个子项或者实现模式,体现了云原生中服务网格这一个新生技术的重要性。
而不可变基础设施和声明式API这两个设计指导理念的加入,则强调了这两个概念对云原生架构的影响和对未来发展的指导作用。
3.1 服务网格 (Service Mesh)
微服务技术架构实践中主要有侵入式架构和非侵入式架构两种实现形式。
侵入式架构是指服务框架嵌入程序代码,开发者组合各种组件,如RPC、负载均衡、熔断等,实现微服务架构。
非侵入式架构则是以代理的形式,与应用程序部署在一起,接管应用程序的网络且对其透明,开发者只需要关注自身业务即可,以服务网格为代表。
为了解决微服务框架的侵入性问题,引入Service Mesh。
Serice Mesh提供了专业化的解决方案,其中所涉及的服务通信、容错、认证等功能,都是专业度极高的领城,这些领城应该出现工业级成熟度的制成品,这对于中小企业来说是一个降低成本的选择。
Service Mesh的开源软件包括Istio、Linkerd、 Envoy、 Dubbo Mesh等。
同时,为了让Service Mesh有更好的底层支撑,我们又将Service Mesh运行在Kubernetes上。
3.2 不可变基础设施(Immutable Infrastructure)
What is “Immutable Infrastructure”?
参考URL:https://www.armory.io/blog/what-is-immutable-infrastructure/
不可变基础设施里的“不可变”非常类似于程序设计中的“不可变”概念。
程序设计中,不可变变量(Immutable Variable)就是在完成赋值后就不能发生更改,只能创建新的来整体替换旧的。
对于基础设施的不可变性,最基本的就是指运行服务的服务器在完成部署后,就不再进行更改。
可变基础设施通常会导致以下问题:
- 在灾难发生的时候,难以重新构建服务。持续过多的手工操作,缺乏记录,会导致很难由标准初始化后的服务器来重新构建起等效的服务。
- 在服务运行过程中,持续的修改服务器,就犹如程序中的可变变量的值发生变化而引入的状态不一致的并发风险。这些对于服务器的修改,同样会引入中间状态,从而导致不可预知的问题。
总结:不可变基础设施其实就是生产环境下基础设施不能改动,如果改动,已切都是被记录的,是可以回溯的。
3.3 声明式API ( declarative APIs)
Declarative APIs
https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
声明式 API 的 “声明式” 是什么意思?
对于我们使用 Kubernetes API 对象的方式,一般会编写对应 API 对象的 YAML 文件交给 Kubernetes(而不是使用一些命令来直接操作 API)。
所谓“声明式”,指的就是我只需要提交一个定义好的 API 对象来“声明”(这个 YAML 文件其实就是一种“声明”),表示所期望的最终状态是什么样子就可以了。而如果提交的是一个个命令,去指导怎么一步一步达到期望状态,这就是“命令式”了。
“命令式 API”接收的请求只能一个一个实现,否则会有产生冲突的可能;“声明式API”一次能处理多个写操作,并且具备 Merge 能力。
Kubernetes 有很多能力,这些能力都是通过各种 API 对象来提供。也就是说,API 对象正是我们使用 Kubernetes 的接口,我们正是通过操作这些提供的 API 对象来使用 Kubernetes 能力的。
总结:声明式API其实就是所有资源抽象,抽象成api。这些api 标准化,相当于规范标准了。
4、CNCF云原生组织发展和介绍
CNCF 是一个开源软件基金会,致力于使云原生计算具有普遍性和可持续性。
云原生计算使用开源软件技术栈将应用程序部署为微服务,将每个部分打包到自己的容器中,并动态编排这些容器以优化资源利用率。
云原生技术使软件开发人员能够更快地构建出色的产品。
什么是CNCF
cncf官网:https://www.cncf.io/
CNCF基金会是 2015年由Linux基金会发起了一个 The Cloud Native Computing Foundation(CNCF)基金组织,
CNCF基金会的成立标志着云原生正式进入高速发展轨道,Google、Cisco、Docker各大厂纷纷加入,并逐步构建出围绕 Cloud Native 的具体工具,而云原生这个的概念也逐渐变得更具体化。
CNCF最初对云原生定义是也是狭窄的,当时把云原生定位为容器化封装+自动化管理+面向微服务。
CNCF的目的不一样,他成立的目的是希望打破云巨头的垄断,实际上是希望通过容器和k8s,将提供底层资源的云服务商变得无差异化。
这主要因为CNCF基金会在当时的核心拳头软件就是k8s,因此在概念定义上主要是围绕着容器编排建立起来的生态。
这也是为什么我们感觉CNCF 定义云原生的时候就是在说容器生态。
CNCF 是非营利性 Linux 基金会的一部分。
官网介绍:
Building sustainable ecosystems for cloud native software
为云原生软件建立可持续的生态系统
Cloud Native Computing Foundation (CNCF) serves as the vendor-neutral home for many of the fastest-growing open source projects, including Kubernetes, Prometheus, and Envoy.
云本地计算基金会(CNCF)是许多增长最快的开放源码项目的供应商中立主机,其中包括 Kubernetes、 Prometheus 和 truster。
CNCF 致力于培育和维护一个厂商中立的开源社区生态,用以推广云原生技术。
从 2015 年 Google 牵头成立 CNCF 以来,云原生技术开始进入公众的视线并取得快速的发展,到 2018 年包括 Google、AWS、Azure、Alibaba Cloud 等大型云计算供应商都加入了云原生基金会 CNCF,云原生技术也从原来的应用容器化发展出包括容器、Service Mesh、微服务、不可变基础设施、Serverless、FaaS 等众多技术方向。
CNCF解决了什么问题
- 统一基础平台:kubernetes
- 如果我们需要日志监控:Prometheus
- 需要代理:Envoy
- 需要分布式链路跟踪:Jaeger
- …
地址
:https://www.cncf.io/
介绍几个常用的已经毕业的云原生项目
Kubernetes
Kubernetes 是世界上最受欢迎的容器编排平台也是第一个 CNCF 项目。 Kubernetes 帮助用户构建、扩展和管理应用程序及其动态生命周期。
Prometheus
Prometheus 为云原生应用程序提供实时监控、警报包括强大的查询和可视化能力,并与许多流行的开源数据导入、导出工具集成。
Jaeger
Jaeger 是由 Uber 开发的分布式追踪系统,用于监控其大型微服务环境。 Jaeger 被设计为具有高度可扩展性和可用性,它具有现代 UI,旨在与云原生系统(如 OpenTracing、Kubernetes 和 Prometheus)集成。
Containerd
Containerd 是由 Docker 开发并基于 Docker Engine 运行时的行业标准容器运行时组件。
作为容器生态系统的选择,Containerd 通过提供运行时,可以将 Docker 和 OCI 容器镜像作为新平台或产品的一部分进行管理。
Envoy
Envoy 是最初在 Lyft 创建的 Service Mesh(服务网格),现在用于Google、Apple、Netflix等公司内部。 Envoy 是用 C++ 编写的,旨在最大限度地减少内存和 CPU 占用空间,同时提供诸如负载均衡、网络深度可观察性、微服务环境中的跟踪和数据库活动等功能。
Fluentd
Fluentd 是一个统一的日志记录工具,可收集来自任何数据源(包括数据库、应用程序服务器、最终用户设备)的数据,并与众多警报、分析和存储工具配合使用。
Fluentd 通过提供一个统一的层来帮助用户更好地了解他们的环境中发生的事情,以便收集、过滤日志数据并将其路由到许多流行的源和目的地。
孵化中的项目
Open Tracing
OpenTracing:为不同的平台,供应中立的API,使开发人员可以轻松地应用分布式跟踪。
GRPC
gRPC 是一个高性能、开源和通用的 RPC 框架,语言中立,支持多种语言。
CNI
CNI 就是这样一个标准,它旨在为容器平台提供网络的标准化。不同的容器平台能够通过相同的接口调用不同的网络组件。
Helm
Helm 是 Kubernetes 的包管理器。包管理器类似于我们在Centos中使用的yum一样,能快速查找、下载和安装软件包。
Etcd
一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现。一般用的最多的就是作为一个注册中心来使用
5、从微服务演进到Service Mesh(服务网格)的过程
CNCF非常特别的是:
将服务网格单独列出来,而不是将服务网格作为微服务的一个子项或者实现模式,体现了云原生中服务网格这一个新生技术的重要性。
来看看 从微服务演进到Service Mesh(服务网格)的过程
5.1 单体服务时代
2010年前,大多数服务业务单一且简单,采用典型的单机+数据库模式,
所有的功能都写在一个应用里并进行集中部署
论坛业务、聊天室业务、邮箱业务全部都耦合在一台小型机上面,所有的业务数据也都存储在一台数据库上。
随着应用的日益复杂与多样化,开发者对系统的容灾,伸缩以及业务响应能力有了更高的要求
如果小型机和数据库中任何一个出现故障,整个系统都会崩溃,
若某个板块的功能需要更新,那么整个系统都需要重新发布,
如何保障可用性的同时快速响应业务的变化,需要将系统进行拆分,将上面的应用拆分出多个子应用。
优点:应用跟应用解耦,系统容错提高了,也解决了独立应用发布的问题
应用垂直拆分解决了应用发布的问题,但是随着用户数量的增加,单机的计算能力依旧是杯水车薪
用户量越来越大,同时也要进行高可用保证, 大部分系统,需要进行横向扩展(水平扩展)
在接入层,引入负载均衡组件,有了负载均衡之后,架构图如下
阿里巴巴在2008提出去“IOE”,也就是IBM小型机、Oracle数据库,EMC存储,
全部改成集群化负载均衡架构,在2013年支付宝最后一台IBM小型机下线
优点:
应用跟应用解耦,系统容错提高了,也解决了独立应用发布的问题,同时可以水平扩展来提供应用的并发量
5.2 微服务时代
分布式微服务时代
微服务是在2012年提出的概念,微服务的希望的重点是一个服务只负责一个独立的功能。
拆分原则,任何一个需求不会因为发布或者维护而影响到不相关的服务,一切可以做到独立部署运维。
比如传统的“用户中心”服务,对于微服务来说,需要根据业务再次拆分,可能需要拆分成“买家服务”、“卖家服务”、“商家服务”等。
典型代表:
Spring Cloud,相对于传统分布式架构,SpringCloud使用的是HTTP作为RPC远程调用,配合上注册中心Eureka和API网关Zuul,可以做到细分内部服务的同时又可以对外暴露统一的接口,让外部对系统内部架构无感,此外Spring Cloud的config组件还可以把配置统一管理。
马丁大师对微服务的定义:https://martinfowler.com/articles/microservices.html
微服务真正定义的时间是在2014年
The term "Microservice Architecture" has sprung up over the last few years to describe a particular way of designing software applications as suites of independently deployable services. While there is no precise definition of this architectural style, there are certain common characteristics around organization around business capability, automated deployment, intelligence in the endpoints, and decentralized control of languages and data.
大概意思:可独立部署服务,服务会越来越细
spring cloud地址
:https://spring.io/projects/spring-cloud
集群部署多了,这些重复的功能无疑会造成资源浪费,所以会把重复功能抽取出来,名字叫"XX服务(Service)"
为了解决服务跟服务如何相互调用,需要一个程序之间的通信协议,所以就有了远程过程调用(RPC),作用就是让服务之间的程序调用变得像本地调用一样的简单
5.3 服务网格新时期 (service mesh)
服务网格和微服务的本质区别,主要在于 单体服务进行 业务服务和 非业务基础 服务进行解耦
非业务基础 服务,交给基础框架进行 管理和控制
非业务基础 (sidecar)服务 + 服务治理 中间件 (Pilot/mixor),组成一个网络结构, 被称之为服务网格
如下图所示
为啥叫做服务网格,主要 从架构层面看起来跟网格很像,
如果每一个格子都是一个sidecar数据单位(单元格),然后sidecar进行彼此通信,所以这些单元格 组成 数据面
这些 sidecar数据单位(单元格),由统一的控制/配置中间组件(类似nacos注册中心)进行配置和控制, 那些控制组件 组成 了 控制面
宏观上 ,服务网格 =数据面 + 控制面
特点:
- 基础设施:
服务网格是一种处理服务之间通信的基础设施层。
- 支撑云原生:
服务网格尤其适用于在云原生场景下帮助应用程序在复杂的服务间可靠地传递请求。
- 网络代理:
在实际使用中,服务网格一般是通过一组轻量级网络代理来执行治理逻辑的。
- 对应用透明:
轻量网络代理与应用程序部署在一起,但应用感知不到代理的存在,还是使用原来的方式工作。
6、服务网格(service mesh)原理和价值
什么是服务网格(service mesh)
istio官网 也对什么是service mesh给出了定义
地址
:https://istio.io/docs/concepts/what-is-istio/#what-is-a-service-mesh
Istio addresses the challenges developers and operators face as monolithic applications transition towards a distributed microservice architecture. To see how, it helps to take a more detailed look at Istio’s service mesh.
翻译:
解决开发与运维部署分布式微服务面临的问题
The term service mesh is used to describe the network of microservices that make up such applications and the interactions between them. As a service mesh grows in size and complexity, it can become harder to understand and manage. Its requirements can include discovery, load balancing, failure recovery, metrics, and monitoring. A service mesh also often has more complex operational requirements, like A/B testing, canary rollouts, rate limiting, access control, and end-to-end authentication.
翻译:
也是解决微服务之间服务跟服务之间通信的问题,可以包括服务发现、负载平衡、故障恢复、度量和监视,服务网格通常还具有更复杂的操作需求,如A/B测试、速率限制、访问控制和端到端身份验证
服务网格:指的是微服务网络应用之间的交互,随着规模和复杂性增加,服务跟服务调用错综复杂
如下图所示
如果每一个格子都是一个sidecar数据单元,然后sidecar进行彼此通信,从架构层面看起来跟网格很像,整体组成一个服务网格 service mech
服务网格将 “业务服务”和“基础设施”解耦,将一个微服务进程一分为二:
特点:
- 基础设施:服务网格是一种处理服务之间通信的基础设施层。
- 支撑云原生:服务网格尤其适用于在云原生场景下帮助应用程序在复杂的服务间可靠地传递请求。
- 网络代理:在实际使用中,服务网格一般是通过一组轻量级网络代理来执行治理逻辑的。
- 对应用透明:轻量网络代理与应用程序部署在一起,但应用感知不到代理的存在,还是使用原来的方式工作。
Service Mesh的价值
服务网格将 “业务服务”和“基础设施”解耦,
Service Mesh上的sidecar支撑了所有的上层应用,业务开发者无须关心底层构成,可以用Java,也可以用Go等语言完成自己的业务开发。
Istio的理论概念是Service Mesh(服务网络),我们不必纠结于概念实际也是微服务的一种落地形式有点类似上面的SideCar模式。
Service Mesh 的主要思想是职责解耦、责任清晰,即不像SpringCloud一样将服务治理交给研发来做,也不集成到k8s中产生职责混乱,
Istio是通过为服务配 Agent代理来提供服务发现、负截均衡、限流、链路跟踪、鉴权等微服务治理手段。
Istio开始就是与k8s结合设计的,Istio结合k8s可以牛逼的落地微服务架构。
istio 超越 spring cloud等传统开发框架之处, 就在于不仅仅带来了远超这些框架所能提供的功能, 而且也不需要应用程序为此做大量的改动,开发人员也不必为上面的功能实现进行大量的知识储备。
Linkerd
2016年1月,离开Twitter的基础设施工程师打造的一个服务网格项目 Linkerd,
第一个Service Mesh项目由此诞生,解决通用性。
Linkerd很好地结合了Kubernetes所提供的功能,
以此为基础,在每个Kubernetes Node上都部署运行一个Linkerd实例,用代理的方式将加入Mesh的Pod通信转接给Linkerd,这样Linkerd就能在通信链路中完成对通信的控制和监控。
Linkerd设计思想
Linderd的思想跟sidecar很类似,目标也是屏蔽网络通信细节
Linkerd除了完成对Service Mesh的命名,以及Service Mesh各主要功能的落地,还有以下重要创举:
- 无须侵入工作负载的代码,直接进行通信监视和管理;
- 提供了统一的配置方式,用于管理服务之间的通信和边缘通信;
- 除了支持Kubernetes,还支持多种底层平台。
总结:
- 跟我们前面sidecar很类似,以前的调用方式都是服务来调用服务,在Linkerd思想要求所有的流量都走sidecar,Linkerd帮业务人员屏蔽了通信细节,通信不需要侵入到业务代码内部了,这样业务开发者就专注于业务开发的本身
- Linkerd在面世之后,迅速获得用户的关注,并在多个用户的生产环境上成功部署、运行。2017年,Linkerd加入CNCF,随后宣布完成对千亿次生产环境请求的处理,紧接着发布了1.0版本,并且具备一定数量的商业用户,一时间风光无限,一直持续到Istio横空出世。
问题:
在早期的时候又要部署服务,又要部署sidecar,对于运维人员来说比较困难的,
所以没有得到很好的发展,其实主要的 问题是Linkerd只是实现了数据层面的问题,但没有对其进行很好的管理。
或者说, Linkerd 没有实现一套好的 控制面 组件。
istio
由Google、IBM和Lyft共同发起的开源项目
istio,是由go语言编写的
什么是istio?
地址
:https://istio.io/docs/concepts/what-is-istio/#why-use-istio
Istio makes it easy to create a network of deployed services with load balancing, service-to-service authentication, monitoring, and more, with few or no code changes in service code. You add Istio support to services by deploying a special sidecar proxy throughout your environment that intercepts all network communication between microservices, then configure and manage Istio using its control plane functionality
通过Istio,可以轻松创建带有负载平衡,服务到服务的身份验证,监视等功能的已部署服务网络,使得服务中的代码更改很少或没有更改。
通过在整个环境中部署一个特殊的sidecar代理来拦截微服务之间的所有网络通信,然后使用其控制平面功能配置和管理,可以为服务添加Istio支持。
注意这句话:
通过Istio,使得服务中的代码更改很少或没有更改, 可以轻松创建 微服务。
如果我们用的是spring cloud,要加依赖、加注解、改配置 依赖组件,才能完成 创建 微服务
istio 提供了很好的 控制面 组件。
什么是控制平面? 控制平面就是来管理数据平面,也就是管理sideCar
所以istio既有数据平面也有很好控制平面
istio能干什么?
Automatic load balancing for HTTP, gRPC, WebSocket, and TCP traffic.
Fine-grained control of traffic behavior with rich routing rules, retries, failovers, and fault injection.
A pluggable policy layer and configuration API supporting access controls, rate limits and quotas.
Automatic metrics, logs, and traces for all traffic within a cluster, including cluster ingress and egress.
Secure service-to-service communication in a cluster with strong identity-based authentication and authorization.
- 1.HTTP、gRPC、WebSocket和TCP流量的自动负载平衡。
- 2.对流量行为的 路由、重试、故障转移和错误 进行细粒度控制。
- 3.支持访问控制、速率限制、配置API。
- 4.集群内所有流量的自动衡量、日志和跟踪,包括集群入口和出口。
- 5.使用基于身份验证和授权来保护集群中服务跟服务之间的通信。
**总结:**很明显Istio不仅拥有“数据平面(Data Plane)”,而且还拥有“控制平面(Control Plane),也就是拥有了数据 接管与集中控制能力。
国内兴起的服务网格
前面提到,在Service Mesh这个概念得到具体定义之前,实际上已经有很多厂商开始了微服务新的尝试,这一动作势必引发对微服务治理的强劲需求。
在Service Mesh概念普及之后,有的厂商意识到自身产品也具备Service Mesh的特点,也有厂商受其启发,将自有的服务治理平台进行完善和改造,推出自己的Service Mesh产品。
例如,蚂蚁金服、腾讯和华为都推出自己的网格产品,华为的产品甚至已被投入公有云进行商业应用。
- 蚂蚁金服 sofa Mesh
前身是SOFA RPC ,2018年07月正式开源
- 腾讯 Tencent Service Mesh
- 华为 CSE Mesher
总结:基本上都借鉴了Sidecar、Envoy和Istio等设计思想
7、云原生应用和传统应用的区别
云原生是一个很宽泛的概念,想要开发一个支持云原生的应用并不难,
可能就是简单的实现可基于容器部署、使用Kubernetes进行编排与调度,集成CI/CD工具以及Prometheus监控工具等。
云原生在一个更好的基础平台与设施上提供了更多的应用。
因为做了容器化就不需要指定操作系统,K8S 的资源调度更有弹性,之前需要通过代码来协调实现伸缩策略,比较麻烦,借助DevOps 会容易达成协作,因为它整个流程都是自动的,能够敏捷开发。还有微服是都是各自独立的,具有高内聚、低耦合的原则,具有自动化运维、快速恢复的特点,自愈能力强。当集群宕掉了,它会自动拉起。
总结: 云原生与传统应用有比较明显的区别,云原生更倡导敏捷、自动化、容错,而传统应用则大多还处于原生的瀑布开发模型和人工运维阶段。
8、云原生涉及的核心项目
第2部分:穿透K8S的8大宏观架构
在这里,尼恩用自己 20 年陈酿的 3高架构知识宇宙, 给大家从宏观上,梳理一下穿透K8S的8大宏观架构
尼恩的K8S的独特视角:不是普通的视角
尼恩从架构师视角,带大家通过8个图,穿透K8S,实现K8S自由
- 图0:K8S 的宏观组件架构图
- 图1:K8S 业务架构图
- 图2:K8S 元数据架构图
- 图3:K8S 容器管理流程架构
- 图4:容器元数据的数据传输架构
- 图5:容器对外暴露架构图
- 图6:总的架构图
- 第7:master 上APIServer 内部架构图
- 第8:worker上 kubelet内部架构图
K8S的核心价值:带领大家从 容器管理的石器时代,进入工业时代
首先,回顾一下, 在石器时代,我们是怎么管理容器的:
- docker 命令 (石器时代早期)
- docker 编排 (石器时代晚期期)
图0:K8S 的宏观组件架构图
K8S,是一个围绕容器打造的分布式系统,和其他的分布式系统比如rocketmq、kafka、elasticsearch,其实宏观上非常类似
两个大组件:
- master : 集群管理+元数据管理
- worker(node): 容器的生命周期管理
master上的主要组件是 api-server + 一大堆的控制器
node上主要的组件就是 kubelet (容器管理)+ kube-proxy(流量负载均衡)
具体介绍,请参见前面的视频。
图1:K8S 业务架构图
在尼恩的 3高架构知识宇宙中, 系统的架构,都是从业务架构开始的。
K8S 业务架构:
- 容器元数据管理 (管理镜像地址、资源信息、部署的副本数量、部署的节点信息,对外暴露的端口信息等等)
- 容器什么周期管理 ( 管死管生管过程)
具体如下:
具体介绍,请参见前面的视频。
图2:K8S 元数据架构图
包括:镜像地址、资源信息、部署的副本数量、部署的节点信息,对外暴露的端口信息等等
Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器
Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod
Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签
Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控
Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行
Replication Controller:
Replication Controller 保证了在所有时间内,都有特定数量的Pod副本正在运行,如果太多了,Replication Controller就杀死几个,如果太少了,Replication Controller会新建几个。
和直接创建的pod不同的是,Replication Controller会替换掉那些删除的或者被终止的pod,不管删除的原因是什么(维护阿,更新啊,Replication Controller都不关心)。
基于这个理由,我们建议即使是只创建一个pod,我们也要使用Replication Controller。
Replication Controller 就像一个进程管理器,监管着不同node上的多个pod,而不是单单监控一个node上的pod,Replication Controller 会委派本地容器来启动一些节点上服务(Kubelet ,Docker)。
ReplicaSet:
ReplicaSet是下一代复本控制器。ReplicaSet和 Replication Controller之间的唯一区别是现在的选择器支持。Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa))。
在使用时官方推荐ReplicaSet。
Deployment:
为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。
典型的应用场景包括:
- 定义Deployment来创建Pod和ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续Deployment
具体介绍,请参见前面的视频。
图3:K8S 容器管理流程架构
从容器管理的入口, 到最终容器的创建, 具体流程如下图所示:
第一步: 用户向APIServer (数据总线)提交一份 部署文件,里边有用户视角的 容器元数据信息
第一步: APIServer 通知 一系列的控制器进行 部署文件处理, 得到最终的 元数据 对象,也就是 资源对象,持久化到 etcd,并且发布到 Node节点的 kubelet组件
第三部: Node节点的 kubelet组件判断是否属于自己管理的容器,如果是,则进行容器的创建
创建容器时,主要用到下面三个接口
(1)CRI(Container Runtime Interface):
容器运行时接口,提供计算资源。
kubernetes1.5版本之后,kubernetes项目推出了自己的运行时接口api–CRI(container runtime interface)。
(2)CNI(Container Network Interface):
容器网络接口,提供网络资源。
是和 CoreOS 主导制定的容器网络标准,它本身并不是实现或者代码,可以理解成一个协议。CNI旨在为容器平台提供网络的标准化。容器平台可以从CNI获取到满足网络互通条件的网络参数(如IP地址、网关、路由、DNS等)。
(3)CSI(Container Storage Interface):
容器存储接口,提供存储资源。
由 kubernetes、Mesos、Docker 等社区成员联合制定的一个行业标准接口规范,旨在将任意存储系统暴露给容器化应用程序。
kubernetes 1.9 版为alpha阶段–>kubernetes 1.10版为beta阶段–>kubernetes 1.13 GA。
具体介绍,请参见前面的视频。
图4:容器元数据的数据传输架构
内部的 api server 和 kublet 客户端 组件之间, 通过 长短链接 相结合的方式,完成高性能数据传输:
- 长连接: 进行增量元数据 推送 , 推模式
- 短连接: 进行全量元数据 拉取 , 推模式
具体介绍,请参见前面的视频。
图5:容器对外暴露架构图
两个阶段:
- 元数据对象创建的阶段: 完成容器的选择, 容器清理的建立,以及端口的映射
- 流量路由阶段: 由 kube-proxy组件 进行 流量的分发,和 pod 之间的负载均衡
具体介绍,请参见前面的视频。
图6:总的架构图
有了前面的基础之后,来一个总的架构图
K8S,是一个围绕容器打造的分布式系统,和其他的分布式系统比如rocketmq、kafka、elasticsearch,其实宏观上非常类似
两个大组件:
- master : 集群管理+元数据管理
- worker(node): 容器的生命周期管理
master上的主要组件是 api-server + 一大堆的控制器
node上主要的组件就是 kubelet (容器管理)+ kube-proxy(流量负载均衡)
另外通过etcd 进行元数据的持久化。
具体介绍,请参见前面的视频。
图7:master 上APIServer 内部架构图
Kube-APIServer是Kubernetes最重要的核心组件之一,主要提供以下功能:
- 提供集群管理的RESTAPI接口,包括∶认证Authentication、 授权Authorization、准入Admission(Mutating&Valiating)。
- 提供其他模块之间的数据交互和通信的枢纽(其他模块通过APIServer查询或修改数据,只有APIServer才直接操作etcd)。
- APIServer提供etcd数据缓存以减少集群对etcd的访问。
APIServer对请求的处理流程,采用了类似 责任链 模式的架构, 由很多的处理器组成:
(1)APIHandler:APIServer 本质上是一个 RestServer,那么就需要注册不同对象的Handler
(2)AuthN:认证,除了可以使用Kubernetes 自带的认证机制外,还可以使用 webhook自己定义一些认证机制。当配置了外部的认证机制后,认证请求就可以被转发到外部去,这样就可以去集成企业统一的认证平台
(3)Rate Limit:限流
(4)Auditing:审计,所有的操作都会生成一条日志记录
(5)AuthZ:认证,可以使用 k8s 自带的 RBAC(role-base access control),也可以使用 webhook 自定义
(6)Aggregator:
可以像 nginx 一样做路由配置,如果 APIServer 是标准的 K8S APIServer,就会走默认的 K8S APIServer,包括Mutating、Validation等;
如果是自定义的 APIServer,就会走Aggregated APIServer(自定义、独立部署的 APIServer),包括自定义的Mutating、Validation等。
(7)Mutating:变形,可以加一些属性
(8)Validating:验证,加完属性后再做一些验证
图8:worker上 kubelet内部架构图
Kubelet 将 容器运行时, 容器网络和 容器存储抽象成了CRI,CNI,CSI。
主要的工作为:
(1)Kubelet 是node上 Kubernetes的初始化系统(init system)
(2)Kubelet 从不同源获取Pod清单,并按需求启停Pod的核心组件:
- 可从本地文件目录获取Pod 清单
- 从给定的HTTPServer或Kube-APIServer等源头获取Pod 清单;
(3)Kubelet负责汇报当前节点的资源信息和健康状态;
(4)Kubelet负责Pod的健康检查和状态汇报。
学习 云原生+ 微服务的神器
本地、轻量级 K8S 环境,一键启动, 学习 云原生+ 微服务 , 非常方便
尼恩会给大家准备好 虚拟机的box文件,可以直接用,省去 折腾的烦恼
第3部分:K8s运行时 实操
k8s有多种部署方式,目前主流的方式有3种:kubeadm、minikube、二进制包。
1)kubeadm:一个用于快速搭建单节点kubernetes的工具
2)minikube:一个用于快速搭建kubernetes集群的工具
3)二进制包:从官网下载每个组件的二进制包,依次去安装,此方式对于理解kubernetes组件更加有效
什么是minikube
minikube 是本地 Kubernetes,
优点是:快速启动,消耗机器资源较少,非常适合新手体验与开发。
minikube 最大特点就是“小而美”,可执行文件仅有不到 100MB,运行镜像也不过 1GB,
但就在这么小的空间里却集成了 Kubernetes 的绝大多数功能特性,不仅有核心的容器编排功能,还有丰富的插件,例如 Dashboard、GPU、Ingress、Istio、Kong、Registry 等等,综合来看非常完善。
minikube 背景
徒手搭建过k8s的同学都晓得其中的煎熬,复杂的认证,配置环节相当折磨人,出错率相当高,
而minikube就是为解决这个问题而衍生出来的工具,它基于go语言开发,
minikube可以在单机环境下快速搭建可用的k8s集群,非常适合测试和本地开发,现有的大部分在线k8s实验环境也是基于minikube
可以在minikube上体验kubernetes的相关功能。
minikube基于go语言开发, 是一个易于在本地运行 Kubernetes 的工具,可在你的笔记本电脑上的虚拟机内轻松创建单机版 Kubernetes 集群。
便于尝试 Kubernetes 或使用 Kubernetes 日常开发。
可以在单机环境下快速搭建可用的k8s集群,非常适合测试和本地开发。
所以,可以在本地实验环境来安装minikube,来入门学习kubernetes相关的知识;
Kubernetes集群架构 与minikube架构对比
1、Kubernetes集群架构
通常情况下,一套完整的Kubernetes集群至少需要包括master节点和node节点,
下图是常规k8s的集群架构,master节点一般是独立的,用于协调调试其它节点之用,而容器实际运行都是在node节点上,kubectl位于 master节点。
2、Minikube架构
下图是 Minikube的架构,可以看出,master 节点与其它节点合为一体,而整体则通过宿主机上的 kubectl 进行管理,这样可以更加节省资源。
其支持大部分kubernetes的功能,列表如下
- DNS
- NodePorts
- ConfigMaps and Secrets
- Dashboards
- Container Runtime: Docker, and rkt
- Enabling CNI (Container Network Interface)
- Ingress
- …
Minikube 支持 Windows、macOS、Linux 三种 OS,会根据平台不同,下载对应的虚拟机镜像,并在镜像内安装 k8s。
minikube安装前准备
推荐在linux主机上安装,我本地用的是 centos。
安装minikube的主机必要配置:
- 2 CPUs or more
- 2GB of free memory
- 20GB of free disk space
- Internet connection
- Container or virtual machine manager, such as: Docker, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware
Container 容器我本地安装是docker;
docker安装和环境检查
安装过程,请参见下面的文档:
尼恩编著,《 docker 学习圣经 》PDF
注:
由于国内访问docker镜像库很是缓慢,所以建议配置阿里云的代理,通过修改daemon配置文件/etc/docker/daemon.json来使用加速器:
$ cd /etc/docker
# 在daemon.json文件末尾追加如下配置:
$ sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://bjtzu1jb.mirror.aliyuncs.com",
"http://f1361db2.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://reg-mirror.qiniu.com",
"https://dockerhub.azk8s.cn",
"https://registry.docker-cn.com"
]
}
EOF
# 重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
docker 版本要求
For improved Docker performance, Upgrade Docker to a newer version (Minimum recommended version is 18.09.0)
! docker is currently using the devicemapper storage driver, consider switching to overlay2 for better performance
* Using image repository registry.cn-hangzhou.aliyuncs.com/google_containers
* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Creating docker container (CPUs=2, Memory=2200MB) ...
* Preparing Kubernetes v1.23.1 on Docker 20.10.8 ...
docker 版本:
[root@cdh1 ~]# docker version
Client: Docker Engine - Community
Version: 20.10.23
API version: 1.41
Go version: go1.18.10
Git commit: 7155243
Built: Thu Jan 19 17:36:21 2023
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.23
API version: 1.41 (minimum version 1.12)
Go version: go1.18.10
Git commit: 6051f14
Built: Thu Jan 19 17:34:26 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.15
GitCommit: 5b842e528e99d4d4c1686467debf2bd4b88ecd86
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
关闭虚拟机swap、selinux、firewalld
# 临时关闭swap
swapoff -a
# 临时关闭selinux,如永久关闭请配置为permissive
setenforce 0
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
永久关闭swap可注释掉/etc/fstab中的swap行,然后重启。
永久关闭selinux可编辑/etc/sysconfig/selinux,配置为SELINUX=permissive,然后重启。
此处为常规操作不详述。
编辑虚拟机hosts文件
与安装k8s类似,需要添加主机名解析
echo "127.0.0.1 test1" >> /etc/hosts
其中test1为虚拟机主机名。
如果不添加该解析,启动minikube时会有如下报错:
[WARNING Hostname]: hostname "test1" could not be reached[WARNING Hostname]: hostname "test1": lookup test1 on 172.18.3.4:53: no such host
登录阿里云
注册阿里云账号, 开通容器镜像服务
docker login --username=修改成你自己的账号 registry.cn-hangzhou.aliyuncs.com
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/kaigejava/my_kaigejava:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/kaigejava/my_kaigejava:[镜像版本号]
创建用户,加入docker用户组
新建一个minikube用户
useradd minikube
新建一个用户组
groupadd docker
将minikube添加到docker组
usermod -aG docker minikube
将当前用户添加到该docker组(root)
usermod -aG docker $USER
更新用户组
newgrp docker
重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
让用户minikube获得root权限
1、添加用户,首先用adduser命令添加一个普通用户,命令如下:
添加一个名为minikube的用户
- adduser minikube 添加用户
- passwd minikube//修改密码
2、赋予root权限 (三种方法,推荐第三)
方法一: 修改 /etc/sudoers 文件,找到下面一行,把前面的注释(#)去掉
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL
然后修改用户,使其属于root组(wheel),命令如下:
usermod -g root minikube
修改完毕,现在可以用minikube帐号登录,然后用命令 su – ,即可获得root权限进行操作。
方法二: 修改 /etc/sudoers 文件,找到下面一行,在root下面添加一行,如下所示:
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
minikube ALL=(ALL) ALL
修改完毕,现在可以用minikube帐号登录,然后用命令 su – ,即可获得root权限进行操作。
su minikube
su -
方法三: 修改 /etc/passwd 文件,直接修改用户id为0,就是root的用户id
cat /etc/passwd
7 个字段的详细信息如下:
(1)用户名 (user1): 已创建用户的用户名,字符长度 1 个到 12 个字符。如果是“*”的话,那么就表示该账号被查封了,系统不允许持有该账号的用户登录。
(2)密码(x):代表加密密码,保存在 /etc/shadow 文件中。
(3)用户 ID(1001):代表用户的 ID 号,每个用户都要有一个唯一的 ID 。UID 号为 0 的是为 root 用户保留的,UID 号 1 到99 是为系统用户保留的,UID 号 100-999 是为系统账户和群组保留的。
(4)群组 ID (100):代表user1用户所属群组的 ID 号,每个群组都要有一个唯一的 GID ,群组信息保存在 /etc/group文件中。
(5)用户信息(用户1):代表描述字段,可以用来描述用户的信息。
(6)家目录(/usr/testUser):代表用户的主目录。
(7)Shell(/bin/bash):代表用户使用的 shell 类型。
找到如下行,把用户ID修改为 0 ,如下所示:
minikube:x:1001:1001::/hminikubekube:/bin/bash
修改后如下
minikube:x:0:1001::/home/minikube:/bin/bash
保存,用minikube账户登录后,直接获取的就是root帐号的权限。
安装与启动minikube
minikube的官网:minikube start | minikube (k8s.io)
官网上的安装minikube网速实在太慢了,推荐使用阿里云的镜像来进行安装minikube,
软件版本说明
- minikube:v1.23.1
- Kubernetes:v1.23.1
- kube-prometheus:v0.11.0
安装minikube
#阿里云镜像
curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.23.1/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
#官方二进制包下载
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
65M
linux 下载太慢,我用浏览器下载后, 放在虚拟机共享目录
然后 复制到 /usr/local/bin
[root@cdh1 ~]# su kube
[root@cdh1 root]# cp /vagrant/minikube-linux-amd64 /usr/local/bin/
[root@cdh1 root]# cp /vagrant/minikube-linux-amd64 /usr/local/bin
[root@cdh1 root]# chmod +x /usr/local/bin/minikube-linux-amd64
[root@cdh1 root]# mv /usr/local/bin/minikube-linux-amd64 /usr/local/bin/minikube
启动minikube
minikube start
执行minikube start
出现 The “docker” driver should not be used with root privileges 的报错.
如果是本地测试环境,根本就不需要考虑那么多,直接执行以下命令,强制使用docker:
minikube start --force --driver=docker
# 或者使用阿里云镜像启动
minikube start --force --driver=docker --image-mirror-country cn --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.5.0.iso --registry-mirror=https://xxxxxx.mirror.aliyuncs.com
minikube start --force --driver=docker --image-mirror-country='cn' --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.5.0.iso --registry-mirror=https://xxxxxx.mirror.aliyuncs.com
还是有问题, docker image 下载不了
命令清单:血泪的安装史,尼恩用过的 命令list
通过下面的命令,可以看出血泪的安装史
建议大家用尼恩的镜像,不用二次安装了
minikube start --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --registry-mirror=https://ovfftd6p.mirror.aliyuncs.com --image-mirror-country='cn' --force --driver=docker
sudo minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=none
su minikube
minikube delete
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --force --driver=docker --cpus 4 --memory 5120
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --force --driver=docker --cpus 4 --memory 5120 --feature-gates=EphemeralContainers=true
minikube start --kubernetes-version=v1.23.1 --force --driver=docker --cpus 4 --memory 5120 --feature-gates=EphemeralContainers=true
minikube start 参数
启动命令:minikube start "参数"
--image-mirror-country cn
将缺省利用registry.cn-hangzhou.aliyuncs.com/google_containers
作为安装Kubernetes的容器镜像仓库,--iso-url=***
利用阿里云的镜像地址下载相应的 .iso 文件--cpus=2
:为minikube虚拟机分配CPU核数--memory=2000mb
:为minikube虚拟机分配内存数--kubernetes-version=***
:minikube 虚拟机将使用的 kubernetes 版本 ,e.g. --kubernetes-version v 1.17.3--docker-env http_proxy
传递代理地址
默认启动使用的是 VirtualBox 驱动,使用 --vm-driver 参数可以指定其它驱动
# https://minikube.sigs.k8s.io/docs/drivers/
- --vm-driver=none 表示用容器;
- --vm-driver=virtualbox 表示用虚拟机;
注意: To use kubectl or minikube commands as your own user, you may need to relocate them. For example, to overwrite your own settings, run:
sudo mv /root/.kube /root/.minikube $HOME
sudo chown -R $USER $HOME/.kube $HOME/.minikube
示例
–vm-driver=kvm2
参考: https://minikube.sigs.k8s.io/docs/drivers/kvm2/
minikube start --image-mirror-country cn --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --registry-mirror=https://ovfftd6p.mirror.aliyuncs.com --driver=kvm2
–vm-driver=hyperv
# 创建基于Hyper-V的Kubernetes测试环境
minikube.exe start --image-mirror-country cn \
--iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.5.0.iso \
--registry-mirror=https://xxxxxx.mirror.aliyuncs.com \
--vm-driver="hyperv" \
--hyperv-virtual-switch="MinikubeSwitch" \
--memory=4096
–vm-driver=none
sudo minikube start --image-mirror-country cn --vm-driver=none
sudo minikube start --vm-driver=none --docker-env http_proxy=http://$host_IP:8118 --docker-env https_proxy=https:// $host_IP:8118
其中$host_IP指的是host的IP,可以通过ifconfig查看;比如在我这台机器是10.0.2.15,用virtualbox部署,则用下列命令启动minikube
sudo minikube start --vm-driver=none --docker-env http_proxy=http://10.0.2.15:8118 --docker-env https_proxy=https://10.0.2.15:8118
sudo minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
sudo minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --extra-config=kubelet.cgroup
解决拉取镜像的问题
错误日志查看
minikube logs
Q1:解决minikube拉取镜像速度缓慢的问题
需要进入minikube进程内部,修改远程镜像仓库
minikube ssh
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
解决 minikube start
过程中拉取镜像慢的问题
之前下载失败后的minikube,想要重新下载记得先删除
minikube delete --all
拉取镜像慢可以拉取国内仓库,minikube start
的时候会帮我们下载新版的kubernetes,但是我这里不太支持最新版的,所以需要指定kubernetes版本
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker --extra-config=kubelet.cgroup-driver=systemd
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.aliyuncs.com/google_containers' --registry-mirror=https://kfwkfulq.mirror.aliyuncs.com --image-mirror-country='cn' --force --driver=docker --extra-config=kubelet.cgroup-driver=systemd
--registry-mirror=https://bjtzu1jb.mirror.aliyuncs.com
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://bjtzu1jb.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker --extra-config=kubelet.cgroup-driver=systemd
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://bjtzu1jb.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker --extra-config=kubelet.cgroup-driver=systemd --base-image="registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.27"
Q2:基础镜像拉不下来
错误日志查看
minikube logs
基础镜像拉不下来
registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.27
镜像地址调整为 registry.aliyuncs.com
registry.aliyuncs.com/google_containers/kicbase:v0.0.27
单独下载
docker pull registry.aliyuncs.com/google_containers/kicbase:v0.0.27
打tag
docker tag registry.aliyuncs.com/google_containers/kicbase:v0.0.27 registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.27
删除老的tag
[root@cdh1 ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.aliyuncs.com/google_containers/kicbase v0.0.27 9fa1cc16ad6d 16 months ago 1.08GB
registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase v0.0.27 9fa1cc16ad6d 16 months ago 1.08GB
[root@cdh1 ~]# docker rmi registry.aliyuncs.com/google_containers/kicbase:v0.0.27
Untagged: registry.aliyuncs.com/google_containers/kicbase:v0.0.27
Untagged: registry.aliyuncs.com/google_containers/kicbase@sha256:89b4738ee74ba28684676e176752277f0db46f57d27f0e08c3feec89311e22de
指定镜像启动
因为 registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.27
自动下载、sha校验失败,而无法启动集群!
手动下载后,打tag后
还有验证环节,需要指定镜像,忽略SHA校验
参数 | 值 |
---|---|
–base-image | 指定镜像,忽略SHA校验 |
使用以下命令启动minikube:
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://bjtzu1jb.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker --extra-config=kubelet.cgroup-driver=systemd --base-image="registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.27"
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://bjtzu1jb.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker --base-image="registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.27"
终于开始创建容器,开始启动了
Q3:新的问题来了:coredns 镜像找不到
X Unable to load cached images: loading cached images: Docker load /var/lib/minikube/images/coredns_v1.8.4: loadimage docker.: /bin/bash -c "sudo cat /var/lib/minikube/images/coredns_v1.8.4 | docker load": Process exited with status 1
直接下载
docker pull coredns/coredns:1.8.4
改tag
docker tag coredns/coredns:1.8.4 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.4
删除旧tag
docker rmi coredns/coredns:1.8.4
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.4 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.4
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.4 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.4
再次启动
Q4:继续下载镜像
#从国内镜像拉取
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0
docker pull coredns/coredns:1.8.6
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.0-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetesui/dashboard:v2.3.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetesui/metrics-scraper:v1.0.7
docker pull k8s-minikube/storage-provisioner:v5
docker pull kubernetesui/dashboard:v2.3.1
docker pull kubernetesui/metrics-scraper:v1.0.7
docker pull registry.aliyuncs.com/k8s-minikube/storage-provisioner:v5
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0
docker pull etcd/etcd:3.5.1-0
改tag
docker tag coredns/coredns:1.8.4 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.4
Q5:使用阿里云代理 http://k8s.gcr.io 镜像仓库
国内根本访问不了k8s的镜像库:k8s.gsc.io
。
比如下载k8s.gcr.io/coredns:1.6.5
镜像,在国内默认是下载失败的!
[root@k8s-vm03 ~]# docker pull k8s.gcr.io/coredns:1.6.5
Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
部署K8S最大的难题是镜像下载,在国内无翻墙环境情况下很难从k8s.gcr.io等镜像源里下载镜像。
这种情况下正确做法是:
- 直接指定国内镜像代理仓库(如阿里云代理仓库)进行镜像拉取下载。
- 成功拉取代理仓库中的镜像后,再将其tag打标签成为k8s.gcr.io对应镜像。
- 最后再删除从代理仓库中拉取下来的镜像。
- 要确保imagePullPolicy策略是IfNotPresent,即本地有镜像则使用本地镜像,不拉取!
或者将下载的镜像放到harbor私有仓库里,然后将image下载源指向harbor私仓地址。
# 阿里云代理仓库地址为:registry.aliyuncs.com/google_containers
# 比如下载
k8s.gcr.io/coredns:1.6.5
# 可以代理为:
registry.aliyuncs.com/google_containers/coredns:1.6.5
下面以阿里云代理仓库为例进行说明:
# 比如下载k8s.gcr.io/coredns:1.6.5镜像,在国内默认是下载失败的!
[root@k8s-vm01 coredns]# pwd
/opt/k8s/work/kubernetes/cluster/addons/dns/coredns
[root@k8s-vm01 coredns]# fgrep "image" ./*
./coredns.yaml: image: k8s.gcr.io/coredns:1.6.5
./coredns.yaml: imagePullPolicy: IfNotPresent
[root@k8s-vm03 ~]# docker pull k8s.gcr.io/coredns:1.6.5
Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
# 这时候去指定国内的阿里云镜像代理仓库进行下载
[root@k8s-vm03 ~]# docker pull registry.aliyuncs.com/google_containers/coredns:1.6.5
1.6.5: Pulling from google_containers/coredns
c6568d217a00: Pull complete
fc6a9081f665: Pull complete
Digest: sha256:608ac7ccba5ce41c6941fca13bc67059c1eef927fd968b554b790e21cc92543c
Status: Downloaded newer image for registry.aliyuncs.com/google_containers/coredns:1.6.5
registry.aliyuncs.com/google_containers/coredns:1.6.5
# 然后打tag,并删除之前从代理仓库下载的镜像
[root@k8s-vm03 ~]# docker tag registry.aliyuncs.com/google_containers/coredns:1.6.5 k8s.gcr.io/coredns:1.6.5
[root@k8s-vm03 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/coredns 1.6.5 70f311871ae1 5 months ago 41.6MB
registry.aliyuncs.com/google_containers/coredns 1.6.5 70f311871ae1 5 months ago 41.6MB
[root@k8s-vm03 ~]# docker rmi registry.aliyuncs.com/google_containers/coredns:1.6.5
Untagged: registry.aliyuncs.com/google_containers/coredns:1.6.5
Untagged: registry.aliyuncs.com/google_containers/coredns@sha256:608ac7ccba5ce41c6941fca13bc67059c1eef927fd968b554b790e21cc92543c
[root@k8s-vm03 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/coredns 1.6.5 70f311871ae1 5 months ago 41.6MB
# 最终发现我们想要的k8s.gcr.io/coredns:1.6.5镜像被成功下载下来了!
# 最后要记得:
# 确定imagePullPolicy镜像下载策略是IfNotPresent,即本地有镜像则使用本地镜像,不拉取!
# 或者将下载好的镜像放到harbor私有仓库里,然后将image下载地址指向harbor仓库地址。
以上总结三个步骤:
docker pull registry.aliyuncs.com/google_containers/coredns:1.6.5
docker tag registry.aliyuncs.com/google_containers/coredns:1.6.5 k8s.gcr.io/coredns:1.6.5
docker rmi registry.aliyuncs.com/google_containers/coredns:1.6.5
Virtual Box 使用的问题
Q1:嵌套虚拟化问题
什么是嵌套 虚拟化特性?
我们知道,在Intel处理器上,Vitural box使用Intel的vmx(virtul machine eXtensions)来提高虚拟机性能, 即硬件辅助虚拟化技术,
现在如果我们需要需要多台具备"vmx"支持的主机,但是又没有太多物理服务器可使用,
如果我们的虚拟机能够和物理机一样支持"vmx",那么问题就解决了,
而正常情况下,一台虚拟机无法使自己成为一个hypervisors并在其上再次安装虚拟机,因为这些虚拟机并不支持"vmx",此时,可以使用 嵌套式虚拟nested
嵌套式虚拟nested是一个可通过内核参数来启用的功能。
它能够使一台虚拟机具有物理机CPU特性,支持vmx或者svm(AMD)硬件虚拟化,
虚拟机启用嵌套VT-x/AMD-V
嵌套 虚拟化特性在VirtualBox虚拟机中默认是不启用的(设置-系统-处理器):
打开Windows Powershell,进入VirtualBox安装目录,将要安装minikube的虚拟机启用嵌套VT-x/AMD-V。
# 进入安装目录
cd 'C:\Program Files\Oracle\VirtualBox\'
# 列出所有虚拟机
C:\Program Files\Oracle\VirtualBox>.\VBoxManage.exe list vms
"cdh1" {309cd81a-248c-4184-9f99-8fe72d01c1f0}
# 打开嵌套虚拟化功能
.\VBoxManage.exe modifyvm "cdh1" --nested-hw-virt on
启用完成后可以看到界面中该选项已勾选:
Q2:conntrack依赖
安装conntrack(后面使用–driver=none启动,依赖此包)
yum install conntrack -y
使用如下命令启动minikube
minikube start --registry-mirror="https://na8xypxe.mirror.aliyuncs.com" --driver=none
使用–driver=none的好处是可以直接使用root运行minikube,无需再配置其他用户。
缺点是安全性降低、稳定性降低、数据丢失风险、无法使用–cpus、–memory进行资源限制等等,
但这不是我们需要考虑的,因为本身安装minikube就是测试学习用的。
关于driver的选择,详细可以参看:none | minikube (k8s.io)
启动时我们看到如下报错:
stderr:
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
根据提示进行解决即可:
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
再次尝试启动,启动成功:
[root@test1 ~]# minikube start --registry-mirror="https://na8xypxe.mirror.aliyuncs.com" --driver=none
* minikube v1.18.1 on Centos 7.6.1810
* Using the none driver based on existing profile
* Starting control plane node minikube in cluster minikube
* Restarting existing none bare metal machine for "minikube" ...
* OS release is CentOS Linux 7 (Core)
* Preparing Kubernetes v1.20.2 on Docker 1.13.1 ...
- Generating certificates and keys ...
- Booting up control plane ...
- Configuring RBAC rules ...
* Configuring local host environment ...
*
! The 'none' driver is designed for experts who need to integrate with an existing VM
* Most users should use the newer 'docker' driver instead, which does not require root!
* For more information, see: https://minikube.sigs.k8s.io/docs/reference/drivers/none/
*
! kubectl and minikube configuration will be stored in /root
! To use kubectl or minikube commands as your own user, you may need to relocate them. For example, to overwrite your own settings, run:
*
- sudo mv /root/.kube /root/.minikube $HOME
- sudo chown -R $USER $HOME/.kube $HOME/.minikube
*
* This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true
* Verifying Kubernetes components...
- Using image registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v4 (global image repository)
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Q3:依赖kubectl、kubelet
kubectl 是和 kubeneters 交互的一个客户端,方便的和 k8s 进行交互,提交作业,查询状态等等。
添加阿里云kubenetes yum源
# /etc/yum.repos.d/kubenetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
生成元数据缓存
# 生成元数据缓存
yum makecache
安装kubectl、kubelet
yum install kubectl -y
yum install kubelet -y
systemctl enable kubelet
带着版本安装
yum list available kubectl
kubectl version
yum remove kubectl
yum install -y kubelet-1.23.1 kubectl-1.23.1 kubeadm-1.23.1
查看版本
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.1", GitCommit:"86ec240af8cbd1b60bcc4c03c20da9b98005b92e", GitTreeState:"clean", BuildDate:"2021-12-16T11:41:01Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"}
The connection to the server localhost:8080 was refused - did you specify the right host or port?
Q4:桥接问题
启动时我们看到如下报错:
stderr:error execution phase preflight: [preflight] Some fatal errors occurred: [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
根据提示进行解决即可:
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
Q5:初始化失败报错,升级内核
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR SystemVerification]: unexpected kernel config: CONFIG_CGROUP_PIDS
[ERROR SystemVerification]: missing required cgroups: pids
[preflight] If you know what you are doing, you can make a check non-fatal with --ignore-preflight-errors=...
To see the stack trace of this error execute with --v=5 or higher
首先,你要在cat /boot/config-uname -r
| grep CGROUP这个文件里面加CONFIG_CGROUP_PIDS=y,
然后你再升级一下内核就可以了。
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
yum --enablerepo=elrepo-kernel install kernel-ml
cp /etc/default/grub /etc/default/grub_bak
vi /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
systemctl enable docker.service
re
查看内核版本
[root@cdh1 ~]# awk -F\' ' $1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
0 : CentOS Linux (6.1.8-1.el7.elrepo.x86_64) 7 (Core)
1 : CentOS Linux (3.10.0-327.4.5.el7.x86_64) 7 (Core)
2 : CentOS Linux (3.10.0-327.el7.x86_64) 7 (Core)
3 : CentOS Linux (0-rescue-e147b422673549a3b4fda77127bd4bcd) 7 (Core)
编辑 /etc/default/grub 文件
设置 GRUB_DEFAULT=0,通过上面查询显示的编号为 0 的内核作为默认内核:
(sed ‘s, release .*$,g’ /etc/system-release)"
GRUB_DEFAULT=0
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT=“console”
GRUB_CMDLINE_LINUX=“crashkernel=auto rd.lvm.lv=cl/root rhgb quiet”
GRUB_DISABLE_RECOVERY=“true”
生成 grub 配置文件并重启
$ grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file …
Found linux image: /boot/vmlinuz-5.12.1-1.el7.elrepo.x86_64
Found initrd image: /boot/initramfs-5.12.1-1.el7.elrepo.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-1160.25.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.25.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-1160.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-16ba4d58b7b74338bfd60f5ddb0c8483
Found initrd image: /boot/initramfs-0-rescue-16ba4d58b7b74338bfd60f5ddb0c8483.img
done
$ reboot
查看内核版本
$ uname -sr
Linux 6.1.8-1.el7.elrepo.x86_64
启动Dashboard
使用如下命令启动dashboard:
$ minikube addons enable dashboard
▪ Using image kubernetesui/dashboard:v2.3.1
▪ Using image kubernetesui/metrics-scraper:v1.0.7
Some dashboard features require the metrics-server addon. To enable all features please run:
minikube addons enable metrics-server
The 'dashboard' addon is enabled
$ minikube addons enable metrics-server
▪ Using image k8s.gcr.io/metrics-server/metrics-server:v0.4.2
The 'metrics-server' addon is enabled
$ minikube dashboard
Verifying dashboard health ...
Launching proxy ...
Verifying proxy health ...
Opening http://127.0.0.1:39887/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...
http://127.0.0.1:39887/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
直接用minikube addons启动Dashboard,提示还需要一并启用metrics-server,都enable下
终于全部启动了
[minikube@cdh1 root]$ kubectl get pod -A
如何从宿主机也就是我们的Windows中访问dashborad呢
从上面输出的信息可以看到,dashboard绑定的IP地址为本地回环地址127.0.0.1,这意味着该地址只能在本地访问。
虚拟机是没有GUI的,那么如何从宿主机也就是我们的Windows中访问dashborad呢?
可以进行如下操作:
使用 nginx、openresty 进行 反向代理
http://127.0.0.1:39887/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
http://k8s:80/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
直接使用minikube
此时的minikube kubectl --
就相当于k8s里的kubectl
命令,当然我们实际不会这样使用,
我们可以minikube的命令给alias一下:
$ alias kubectl="minikube kubectl --"
此时再直接运行kubectl
命令:
$ kubectl
kubectl controls the Kubernetes cluster manager.
Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/
Basic Commands (Beginner):
create Create a resource from a file or from stdin
expose Take a replication controller, service, deployment or pod and expose it as a new
Kubernetes service
run 在集群中运行一个指定的镜像
set 为 objects 设置一个指定的特征
Basic Commands (Intermediate):
explain Get documentation for a resource
get 显示一个或更多 resources
edit 在服务器上编辑一个资源
delete Delete resources by file names, stdin, resources and names, or by resources and
label selector
...
好了,就可以愉快的k8s玩耍了。
minikube重建
如果环境搞乱了想重新部署,很简单就可以实现
$ minikube delete
$ minikube start --driver=docker // 这里指定了用docker,不指定也会自动检测
docker-compose to minikube
需要将docker-compose.yaml转变为k8s deploy、svc、configmap,以swagger-ui为例
docker-compose.yaml
version: "3.0"
services:
swiagger-ui:
image: swaggerapi/swagger-ui
container_name: swagger_ui_container
ports:
- "9092:8080"
volumes:
- ../docs/openapi:/usr/share/nginx/html/doc
environment:
API_URL: ./doc/api.yaml
k8s deploy、svc、configmap
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.minikube.service: swagger-ui
name: swagger-ui
spec:
replicas: 1
selector:
matchLabels:
io.minikube.service: swagger-ui
template:
metadata:
labels:
io.minikube.service: swagger-ui
spec:
containers:
- env:
- name: SWAGGER_JSON
value: /openapi/api.yaml
image: swaggerapi/swagger-ui
name: swagger-ui
ports:
- containerPort: 8080
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /openapi
name: swagger-ui-cm
volumes:
- name: swagger-ui-cm
configMap:
name: swagger-ui-cm
---
apiVersion: v1
kind: Service
metadata:
name: swagger-ui
labels:
io.minikube.service: swagger-ui
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
io.minikube.service: swagger-ui
---
apiVersion: v1
kind: ConfigMap
metadata:
name: swagger-ui-cm
data:
api.yaml: |
openapi: 3.0.0
version: "1.0"
...
部署minikube 遇到的问题
外部访问问题
minikube内的k8s网络明显与host不一样,不论使用不使用Type=NodePort,都无法直接访问,都需要用port-forward
这里查了些资料,可能的一个解释是,minikube使用docker-machine为底层,
实现可以部署到vm、container、host等基础设施上,docker-machine会构建自身的docker环境,与host不同,网络也不在一个平面,所以使用NodePort,从host也无法访问,
需要借助
kubectl port-forward --address=0.0.0.0 service/hello-minikube 7080:8080
。
------------ 2021-11-26 update---------------
可以使用以下命令获取minikube的ip,然后通过该ip+nodeport访问
$ minikube ip
192.168.49.2
也可以通过一下命令直接获取对应service的url
$ minikube service hello-minikube --url
http://192.168.49.2:30660
pull image问题
minikube内的docker daemon与host docker daemon不一样,且k8s不与host上的docker共享信息,
host上的docker images和daemon.json配置对minikube内的docker daemon不可见,
minikube内的docker daemon总是从dockerhub pull image,会遇到
You have reached your pull rate limit.
You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limits.
You must authenticate your pull requests.
解决办法
可以先用host docker pull images
,然后load到minikube
$ docker pull <image name>
$ minikube image load <image name>
注意k8s默认的imagePullPolicy
Default image pull policy
When you (or a controller) submit a new Pod to the API server, your cluster sets theimagePullPolicy
field when specific conditions are met:
if you omit theimagePullPolicy
field, and the tag for the container image is:latest
,imagePullPolicy
is automatically set toAlways
;
if you omit theimagePullPolicy
field, and you don’t specify the tag for the container image,imagePullPolicy
is automatically set toAlways
;
if you omit theimagePullPolicy
field, and you specify the tag for the container image that isn’t:latest
, theimagePullPolicy
is automatically set toIfNotPresent
.
- 如果没有设置imagePullPolicy,但image tag是latest,那么默认就是imagePullPolicy: Always
- 如果没有设置imagePullPolicy,也没有设置image tag,那么默认也是imagePullPolicy: Always
- 如果设置了image tag,默认imagePullPolicy: IfNotPresent
为了不出错,建议直接指定 imagePullPolicy: IfNotPresent
POD 容器的问题
K8s的常用命令
kubectl get pods -A
查看所有的命令空间下的pods
kubectl describe node
查看所有节点的cpu和内存使用情况
kubectl describe node nodename |grep Taints
查看该节点是否可达,是否可以部署内容;一般三种情况
kubectl -n namespace名 logs -f --tail 200 pod名 -n namespace
查看命名空间下的 pods日志(运行后才有日志,此命令查看实时的200条日志)
kubectl exec -it -n namespace名 pod名 sh
进入pod
kubectl get services,pods -o wide
查看所有的pods和services, -o 输出格式为wide或者yaml
kubectl describe pod pod名 -n namespace名
查看pod的描述状态
kubectl describe job/ds/deployment pod名 -n namespace名
查看三个控制器下pod描述
kubectl exec -it pod名 -c 容器名 -- /bin/bash
kubectl get pod pod名 -n namespace名 -oyaml | kubectl replace --force -f -
重启pod命令
kubectl get pods -n namespace名
kubectl get pods pod名 -o yaml -n namespace名
kubectl get ds -n namespace名
查看命名空间下daemonset的信息
kubectl get ds ds名 -o yaml -n namespace名
kubectl get deployment -n namespace名
kubectl get deployment deployment名 -o yaml -n namespace名
后面加–force --grace-period=0;立刻强制删除与下面的一起用
删除当前的应用:kubectl delete ds daemonset名 -n namespace名
、kubectl delete deployment deployment名 -n namespace名
(备注:如果是没删除ds/deployment/job,直接删除对应的pod(kubectl delete pod pod名 -n namespace名
,pod会一直重启)
查看容器实时最新的10条日志 docker logs -f -t --tail 10 容器名
kubectl delete job jobname -n namespace名
(job任务也是如此)
查看所有的pod,看看哪些有问题
kubectl get pods -A
[root@cdh1 ~]# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6d8c4cb4d-grphf 1/1 Running 0 8m16s
kube-system etcd-cdh1 1/1 Running 1 8m29s
kube-system kube-apiserver-cdh1 1/1 Running 1 8m31s
kube-system kube-controller-manager-cdh1 1/1 Running 1 8m29s
kube-system kube-proxy-78trt 1/1 Running 0 8m16s
kube-system kube-scheduler-cdh1 1/1 Running 1 8m29s
kube-system storage-provisioner 0/1 ImagePullBackOff 0 8m28s
kubernetes-dashboard dashboard-metrics-scraper-5496b5d99f-llh9t 0/1 ImagePullBackOff 0 6m28s
kubernetes-dashboard kubernetes-dashboard-58b48666f8-hsn8g 0/1 ImagePullBackOff 0 6m28s
storage-provisioner 的ImagePullBackOff 状态
kubectl get pods -A
kubectl describe pod XXX -n kube-system
通过kubectl describe命令详细查看redis-master-0这个pod:
[root@cdh1 ~]# kubectl describe pod storage-provisioner -n kube-system
Name: storage-provisioner
Namespace: kube-system
Priority: 0
Node: cdh1/10.0.2.15
Start Time: Sun, 29 Jan 2023 05:17:14 +0800
Labels: addonmanager.kubernetes.io/mode=Reconcile
integration-test=storage-provisioner
Annotations: <none>
Status: Pending
IP: 10.0.2.15
IPs:
IP: 10.0.2.15
Containers:
storage-provisioner:
Container ID:
Image: registry.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5
Image ID:
Port: <none>
Host Port: <none>
Command:
/storage-provisioner
State: Waiting
Reason: ImagePullBackOff
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/tmp from tmp (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-l5h2b (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
tmp:
Type: HostPath (bare host directory volume)
Path: /tmp
HostPathType: Directory
kube-api-access-l5h2b:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 27m default-scheduler 0/1 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn't tolerate.
Normal Scheduled 27m default-scheduler Successfully assigned kube-system/storage-provisioner to cdh1
Normal Pulling 26m (x4 over 27m) kubelet Pulling image "registry.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5"
Warning Failed 26m (x4 over 27m) kubelet Failed to pull image "registry.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5": rpc error: code = Unknown desc = Error response from daemon: pull access denied for registry.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Warning Failed 26m (x4 over 27m) kubelet Error: ErrImagePull
Warning Failed 25m (x6 over 27m) kubelet Error: ImagePullBackOff
Normal BackOff 2m39s (x109 over 27m) kubelet Back-off pulling image "registry.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5"
dashboard-metrics-scraper-5496b5d99f-wj2d9
我们查看一下storage-provisioner pod的imagePullPolicy:
# kubectl get pod dashboard-metrics-scraper-5496b5d99f-wj2d9 -n kubernetes-dashboard -o yaml
... ...
spec:
containers:
- command:
- /storage-provisioner
image: registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5
imagePullPolicy: IfNotPresent
name: storage-provisioner
我们发现storage-provisioner的imagePullPolicy为ifNotPresent,这意味着如果本地有storage-provisioner:v5这个镜像的话,minikube不会再去远端下载该image。这样我们可以先将storage-provisioner:v5下载到本地并重新tag为registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5。
启动minikube时指定harber仓库
如果minikube已经创建过、
则需要先 minikube delete
再执行下述语句
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --force --driver=docker --registry-mirror=https://harbor.daemon.io --insecure-registry=192.168.56.121:85
下面的老的启动语句
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --force --driver=docker
kubectl get pods -A
验证:
$ minikube ssh
$ curl http://192.168.56.121:85/v2/_catalog
在里边拉取镜像
docker pull harbor.daemon.io/demo/nginx:latest
docker pull 192.168.56.121:85/demo/nginx:latest
minikube 复制证书
您应该可以使用 minikube ssh 登录机器,然后按照此处的说明进行操作
https://docs.docker.com/engine/security/certificates/#understanding-the-configuration
将 CA 放在适当的目录 (/etc/docker/certs.d/[registry hostname]/) 中。
/etc/docker/certs.d/ <-- Certificate directory
└── localhost:5000 <-- Hostname:port
├── client.cert <-- Client certificate
├── client.key <-- Client key
└── ca.crt <-- Root CA that signed
the registry certificate, in PEM
centos
cp /usr/local/harbor/ssl/harbor.daemon.io.cert /etc/docker/certs.d/harbor.daemon.io/harbor.daemon.io.cert
cp /usr/local/harbor/ssl/harbor.daemon.io.key /etc/docker/certs.d/harbor.daemon.io/harbor.daemon.io.key
您不需要重新启动守护程序即可使其工作。
具体的操作如下:
我通过以下步骤处理了它:
进入minikube的ssh
minikube ssh
使用sudo更改docker密码
sudo passwd docker
并创建新密码,因此现在我知道了docker用户密码 123456
使用scp命令将文件复制到minikube
scp /local/path/to/file/ docker@minikube IP:/your/destination/folder/
minikube ssh
[minikube@centos1 logs]$ minikube ip
192.168.49.2
从 centos 到 minikube
scp -r /etc/docker/certs.d docker@192.168.49.2:/etc/docker/
在 minikube 复制 centos 的文件
scp -r root@192.168.56.121:/etc/docker/certs.d /etc/docker/
minikube 用户需要切换到 root, 密码也是 root
然后才能复制
之后,它只要求minikube docker用户密码,123456
再拉
docker pull harbor.daemon.io/demo/nginx:latest
报证书错误
response from daemon: Get "https://harbor.daemon.io/v2/": x509: certificate is valid for spasipark.ru, not harbor.daemon.io
minikube start --kubernetes-version=v1.23.1 --force --driver=docker
# 进入minikube虚拟机
minikube ssh
sudo su
进入minikube虚拟机
minikube start --kubernetes-version=v1.23.1 --force --driver=docker
# 进入minikube虚拟机
minikube ssh
# 编辑Docker配置文件
sudo su
sudo vi /etc/docker/daemon.json
增加私仓地址配置
增加registry-mirrors属性配置到JSON,其中host.minikube.internal:5000
是宿主电脑搭建的docker私有仓库地址,也可以配置阿里公网或者公司的私有仓库地址
cat << EOF >> /etc/docker/daemon.json
{
"registry-mirrors": [
"http://192.168.56.121:85"
]
}
EOF
cat << EOF >> /etc/docker/daemon.json
{
"registry-mirrors": [
"https://bjtzu1jb.mirror.aliyuncs.com",
"http://f1361db2.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://reg-mirror.qiniu.com",
"https://dockerhub.azk8s.cn",
"https://harbor.daemon.io"
]
}
EOF
在 minikube 复制 centos 的文件
scp root@192.168.56.121:/etc/docker/daemon.json /etc/docker/
cat << EOF >> /etc/hosts
192.168.56.121 harbor.daemon.io
EOF
在 minikube 复制 centos 的文件
scp -r root@192.168.56.121:/etc/docker/certs.d /etc/docker/
重启虚拟机的Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
测试
依旧是在minikube虚拟机里测试,是否可以拉取你push到私有仓库到镜像
docker pull test/springboot:1.0.0
命令清单:尼恩用过的 启动 命令清单 (都是血和泪)
通过下面的命令,可以看出血泪的安装史
建议大家用尼恩的镜像,不用二次安装了
minikube start --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --registry-mirror=https://ovfftd6p.mirror.aliyuncs.com --image-mirror-country='cn' --force --driver=docker
sudo minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-repository='registry.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --image-mirror-country='cn' --force --driver=none
su minikube
minikube delete
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.aliyuncs.com/google_containers' --registry-mirror='https://ovfftd6p.mirror.aliyuncs.com' --force --driver=docker
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --force --driver=docker --cpus 4 --memory 5120
minikube start --kubernetes-version=v1.23.1 --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --force --driver=docker --cpus 4 --memory 5120 --feature-gates=EphemeralContainers=true
minikube start --kubernetes-version=v1.23.1 --force --driver=docker --cpus 4 --memory 5120 --feature-gates=EphemeralContainers=true
minikube常用命令
一、基本命令
- 启动集群:
minikube start
- 获取集群状态:
minikube status
- 停止集群:
minikube stop
- 删除集群:
minikube delete
- 暂停k8s:
minikube pause
- 恢复暂停的k8s:
minikube unpause
二、镜像命令
- 配置环境以使用minikube的Docker守护程序:
minikube docker-env
- 配置环境以使用minikube的Podman服务:
minikube podman-env
- 在minikube中添加、删除或推送本地镜像:
minikube cache add|delete|list|reload
三、配置和管理命令
- 启用或禁用minikube插件:
minikube addons
- 修改持久化的配置值:
minikube config
- 获取或列出当前配置文件(集群):
minikube profile
- 在IP或端口发生更改时更新kubeconfig:
minikube update-context
四、网络和连接命令
- 返回连接到一个服务的URL:
minikube service hello-minikube
- 连接到LoadBalancer服务:
minikube tunnel
五、高级命令
- 将指定目录装入minikube:
minikube mount <source directory>:<target directory>
- 进入minikube虚拟机,整个k8s集群跑在这里面:
minikube ssh
- 运行与集群版本匹配的kubectl二进制文件:
minikube kubectl
- 添加、删除或列出其他节点:
minikube node add|start|stop|delete|list
六、疑难解答命令
- 检索指定群集的ssh标识密钥路径:
minikube ssh-key
- 查看集群IP:
minikube ip
- 查看集群日志:
minikube logs
- 打印当前和最新的版本号:
minikube update-check
- 打印minikube版本信息:
minikube version
七、其它命令
为shell生成命令补全:minikube completion
启动minikube完整的命令清单
harber admin 12345
https://cdh1/harbor/projects
minikube delete
minikube start --kubernetes-version=v1.23.1 --force --driver=docker --cpus 4 --memory 5120
kubectl get pods -A
# 进入minikube虚拟机
minikube ssh
# 切换到root
sudo su
cat << EOF >> /etc/docker/daemon.json
{
"registry-mirrors": [
"https://bjtzu1jb.mirror.aliyuncs.com",
"http://f1361db2.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://reg-mirror.qiniu.com",
"https://dockerhub.azk8s.cn",
"https://harbor.daemon.io"
]
}
EOF
cat << EOF >> /etc/hosts
192.168.56.121 harbor.daemon.io
EOF
在 minikube 复制 centos 的文件
scp -r root@192.168.56.121:/etc/docker/certs.d /etc/docker/
3.重启虚拟机的Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
4.测试
依旧是在minikube虚拟机里测试,是否可以拉取你push到私有仓库到镜像
docker pull test/springboot:1.0.0
exit
minikube addons enable dashboard
minikube addons enable metrics-server
minikube dashboard
使用 nginx、openresty 进行 反向代理
http://127.0.0.1:38225/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
onnect to 127.0.0.1 port 38225: C
niginx 启动
http://k8s:1099/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
kubectl get pods -A
kubectl describe pod kubernetes-dashboard-6ddd477f4f-vhdgg -n kubernetes-dashboard
kubectl get pods --namespace=kubernetes-dashboard | grep dashboard
Helm 的原理、安装、使用
java 使用 maven;前端使用 npm;python 使用 pip;运维使用 yum 或 apt。
分工不同,诉求却相同,都希望有一种资源管理工具,可以方便查找、下载、安装、使用和分发程序包。
helm 也一样,它是 k8s 的资源包管理工具。它使我们操作的对象不再是单个资源,而是一个实体。
比如我们需要一个负载均衡的 web 服务,如果不使用 helm,我们需要写 deployment,service 和 ingress 才可以让集群外部的客户使用。但是如果使用 helm,直接使用一个 install 命令便可以实现相同的功能。
Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来管理 Charts。有点类似于 Ubuntu 中的 APT 或 CentOS 中的 YUM。
Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata,以便于应用程序的分发。
对于应用发布者而言,可以通过 Helm 打包应用、管理应用依赖关系、管理应用版本并发布应用到软件仓库。
对于使用者而言,使用 Helm 后不用需要编写复杂的应用部署文件,可以以简单的方式在 Kubernetes 上查找、安装、升级、回滚、卸载应用程序。
推荐使用 helm 的 3.0 版本。
Helm 组件及相关术语
Helm
Helm 是一个命令行下的客户端工具。主要用于 Kubernetes 应用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。
Tiller
Tiller 是 Helm 的服务端,部署在 Kubernetes 集群中。Tiller 用于接收 Helm 的请求,并根据 Chart 生成 Kubernetes 的部署文件( Helm 称为 Release ),然后提交给 Kubernetes 创建应用。Tiller 还提供了 Release 的升级、删除、回滚等一系列功能。
Chart
Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。
Repoistory
Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
Release
使用 helm install 命令在 Kubernetes 集群中部署的 Chart 称为 Release。
Helm 工作原理
Chart Install 过程
Helm 从指定的目录或者 TAR 文件中解析出 Chart 结构信息。
Helm 将指定的 Chart 结构和 Values 信息通过 gRPC 传递给 Tiller。
Tiller 根据 Chart 和 Values 生成一个 Release。
Tiller 将 Release 发送给 Kubernetes 用于生成 Release。
Chart Update 过程
Helm 从指定的目录或者 TAR 文件中解析出 Chart 结构信息。
Helm 将需要更新的 Release 的名称、Chart 结构和 Values 信息传递给 Tiller。
Tiller 生成 Release 并更新指定名称的 Release 的 History。
Tiller 将 Release 发送给 Kubernetes 用于更新 Release。
Chart Rollback 过程
Helm 将要回滚的 Release 的名称传递给 Tiller。
Tiller 根据 Release 的名称查找 History。
Tiller 从 History 中获取上一个 Release。
Tiller 将上一个 Release 发送给 Kubernetes 用于替换当前 Release。
helm使用
1.创建一个空charts
helm create test
安装Helm
1、先下载helm3压缩包下载地地址
或者执行 wget https://get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz
2、解压
tar -zxvf helm-v3.6.3-linux-amd64.tar.gz
3、拷贝
cp linux-amd64/helm /usr/bin
4、是否安装成功
helm version
5、添加chart源
helm repo add aliyuncs https://apphub.aliyuncs.com
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
添加仓库
helm repo add apphub https://apphub.aliyuncs.com
helm repo add azure http://mirror.azure.cn/kubernetes/charts/
6、查看当前集群有那些chart 库
helm repo list
查看仓库
helm repo list
NAME URL
apphub https://apphub.aliyuncs.com
azure http://mirror.azure.cn/kubernetes/charts/
查询有哪些程序包
[root@web-test-01 k8s]# helm search repo mysql
NAME CHART VERSION APP VERSION DESCRIPTION
apphub/mysql 6.8.0 8.0.19 Chart to create a Highly available MySQL cluster
apphub/mysqldump 2.6.0 2.4.1 A Helm chart to help backup MySQL databases usi...
apphub/mysqlha 1.0.0 5.7.13 MySQL cluster with a single master and zero or ...
apphub/prometheus-mysql-exporter 0.5.2 v0.11.0 A Helm chart for prometheus mysql exporter with...
azure/mysql 1.6.2 5.7.28 Fast, reliable, scalable, and easy to use open-...
azure/mysqldump 2.6.0 2.4.1 A Helm chart to help backup MySQL databases usi...
7、查找安装程序
helm search repo nginx
8、安装一个程序
helm install nginx bitnami/nginx
9、查询 svc
kubectl get svc -n default
10、访问集群
11、查看当前安装的应用
helm list
12、删除应用
helm uninstall nginx
…省略
由于公众号最多可以发布5W字
还有10W字放不下…
以下几个部分的具体内容,
请参见《K8S学习圣经》PDF
请在公众号《技术自由圈》回复“领电子书”
第4部分:Kubernetes 基本概念
第4部分目录
- 1、基础概念理解
- K8S集群
- Node的核心组件
- Pod
- Label
- Deployment
- Service
- Addons
- DNS
- Web UI (Dashboard)
- 2、k8s对象(kubernetes Objects)
- 对象的yaml结构
- 关于 yaml文件的分割
- 2.1 一个简单的Kubernetes API 对象
- 2.1 什么是k8s 资源对象
- kubernetes 对象必需字段
- 2.2 kubernetes API的版本
- 一、查看apiversion 可用版本
- 二、各种apiVersion的含义
- 2.3 获取各个属性字段的含义
- 方式1:从命令行获取方式
- 方式2:官方 API 文档方式
- 2.4、管理k8s对象
- 1、命令式
- 2、指令性
- 3、声明式
- 2.5、对象名称与ID
- Names
- UID
- 2.6 对象规约(Spec)与状态(Status)
- 对象规约(Spec)与状态(Status)
- spec 规约
- status 状态
- 2.7、名称空间
- 名称空间的使用参考:
- 如何访问其他名称空间的东西?
- 查看名称空间
- 在执行请求的时设定namespace
- 设置名称偏好
- 名称空间与DNS
- 名称空间的作用
- 并非所有对象都在命名空间中
- 2.8 、标签和选择器
- 2.9、注解annotation
- 2.8、字段选择器
- 2.10、认识kubectl 客户端命令
- kubectl的所有命令参考:
- 2.11、自动补全
- 2.12、给idea安装kubernetes插件
- 1、plugins kubernetes
- 2、快速生成kubernetes 资源文件模板
- 3、输入
k
即可触发自动命令提示
第5部分:Kubernetes 工作负载
第5部分目录
- 什么是Workloads?
- Pod的原理与生命周期
- 1、什么是Pod
- 2、Pod使用
- 3、Pod生命周期
- “根容器” : Pause 容器
- Pod中容器也有分类
- Pod生命周期的 两个阶段
- Pod的Init 初始化容器 (附Demo)
- Pod 钩子Hook方法 (附Demo)
- Pod 健康检查(探针)机制
- Pod 的状态和重启策略
- Pod 常见的状态
- Pod重启策略
- Pod常见状态转换场景
- 临时容器:线上排错
- 使用方法:
- 通过临时容器查看Java容器log日志
- 临时容器的参数说明:
- 使用临时容器进行 dump 转储
- 基于制作Java Debug 镜像
- 临时容器不能用jmap、jps而只能用jattach
- jattach指令集:
- 临时容器的配置
- 临时容器的使用场景
- 静态Pod
- 如何找到 静态pod 的文件路径
- 静态Pod实操
- Pod 资源需求和限制
- Pod的Probe 探针机制(健康检查机制)
- Probe 探针 背景
- K8S 的3种探针
- livenessProbe和readinessProbe 的区别
- (1)livenessProbe
- (2)readinessProbe
- (3)就绪、存活两种探针的区别
- 存活探针 (liveness)的三种探测方法
- exec 方式示例
- httpGet 方式示例
- TCP 方式示例
- 使用命名的端口
- 就绪探针 (readiness)
- ReadinessProbe 探针使用示例
- ReadinessProbe + LivenessProbe 配合使用示例
- 以上案例中存活探针 参数意思:
- 以上案例中就绪探针 参数意思:
- startupProbe探针
- 1、startupProbe探针介绍
- 2、startupProbe探针与另两种区别
- 3、startupProbe探针方法、属性
- 4、为什么要使用startupProbe、使用场景
第6部分:Kubernetes 的资源控制
第6部分目录
- 动态的扩容缩容的重要性
- 1:Deployment 资源对象
- Deployment的创建
- Deployment 资源、replicaset资源、Pod资源 三者之间的关系
- Deployment 基本操作
- 副本扩容
- 副本缩容
- Deployment 更新机制
- 准备:升级镜像
- 在线修改yaml
- 滚动机制相关的命令
- 暂停和恢复
- 回滚策略
- 记录保留
- 滚动更新数量
- 使用Deployment 进行灰度发布
- 2:副本资源 RC、副本集RS 资源对象
- RC(Replication Controller)
- RS(Replication Set)
- ReplicatSet的三个部分
- RS扩容缩容
- 3:DaemonSet 守护集
- DaemonSet 组成结构详解
- 调度节点的选择
- 方式一:nodeSelector方式
- 方式二:nodeAffinity方式
- 方式三:podAffinity方式
- Toleration
- 4:StatefulSet 有状态集
- StatefulSet 使用场景
- StatefulSet的一些限制和要求
- StatefulSet示例
- DNS解析
- StatefulSet 的几个要点
- (1)pod管理策略(podManagementPolicy)
- (2)updateStrategy: 更新策略
- (3)对应的headless service
- 5:Job 任务、CronJob 定时任务
- Job 任务
- 并行 job 示例
- CronJob 定时任务
- CronJob示例
- 6:HPA(Horizontal Pod Autoscaling)水平自动伸缩
- 收集指标插件
- Metrics API
- 前置条件: 开启聚合路由
- metrics安装方式一:minikube 中启用指标服务器作为插件
- metrics server安装方式二:手动安装
- 执行安装和检查
- 执行安装的命令清单
- 7:使用HPA对SpringCloud微服务进行自动伸缩
- autoscale命令
- Metrics支持的指标
- 创建hpa、查看hpa、删除hpa
- HPA扩容实操
- 基于自定义指标的自动扩容
- 扩展阅读: GC机制
- 什么是垃圾回收
- 什么是OCI、CRI、CNI、CSI
- OCI、CRI、CNI、CSI、CRD、CNM规范基本概念:
- 实现OCI、CRI、CNI、CSI组件介绍
- 1、OCI、CRI组件
- 2、CNI组件
- CNI 和 CNM 的对比:
- 3、CSI组件
- CRI、OCI的关系
- CRD是什么
- CR是什么
- CRD与CR的关系
- CRD在API Server中的设计和实现机制
- 如何创建 CRD?
第7部分:SVC负载均衡底层原理
第7部分目录
- Pod的IP 漂移问题
- service 概念
- 四大service 类型
- kubernetes暴露端口的方式
- 1:集群内部实现访问:Clusterip
- 2:集群外部方式访问:NodePort
- 3: LoadBalancer
- 4: Ingress
- DNS解析案例
- 案例
- SVC 流量分发的底层原理
- VIP 和 Service 代理
- 代理模式分类
- Ⅰ、userspace 代理模式
- Ⅱ、Iptables 代理模式
- Ⅲ、ipvs 代理模式
- ipvs为负载均衡提供算法:
- ipvs 对比 iptables
- iptables/netfilter 介绍
- 1,iptables/netfilter介绍
- 2,iptables 基础:
- 3,链的概念:
- 4,表的概念:
- 5,数据经过防火墙的流程图:
- 6,规则:
- 总结: iptables包含4个表,5个链
- iptables 在 K8s 中的应用剖析
- 路由的流程分析:
- service 的路由分析实例
- 先看iptables 中的DNAT
- 再看SNAT
- 基于客户端地址的会话保持模式的svc负载分发策略
- k8s集群中service的域名解析、pod的域名解析
- service的域名
- 1、创建namespace.yaml文件
- 2、创建deployment.yaml文件
- 3、创建service.yaml文件
- 4、测试
- 总结
- service的域名
- 应用持久化存储(PV和PVC)
- 1、Volume
- 1.1、emptyDir
- 1.2、hostPath
- 1.3、外部存储(以NFS为例)
- 2、PV与PVC
- 持久卷的存储插件类型
- 2.1、Static PV
- 1)先搭建好NFS服务器(192.168.100.172)
- 2)创建PV
- 3)创建PVC
- 4)创建Pod
- 2.2、Dynamic PV
- Dynamic PV属于PV的自动化:
- 什么是StorageClass
- 为什么需要StorageClass
- StorageClass案例
- 运行原理
- 1、Volume
第8部分:K8S Ingress原理和实操
第8部分目录
- 背景:
- svc的作用与不足
- Ingress 的来源
- Ingress的构成
- 什么是Ingress Controller?
- Ingress 资源对象
- ingress-controller组件
- nginx-ingress-controller
- 什么是Ingress Controller?
- 部署ingress-controller
- Minikube安装Ingress
- 手工部署ingress-controller pod及相关资源
- ingress版本的问题
- 调整RBAC api-versions 版本
- 部署 ingress-nginx
- 配置ingress资源
- 报错 failed calling webhook
- 获取 ingress 启动的svc
- 加上本地的host
- 测试访问
- 实操的善后工作
- k8s ingress的工作原理
- (1)Ingress Controller 控制器
- (2) Ingress 资源对象
- 详解ingress资源
- ingress规则
- DefaultBackend
- 资源后端
- 路径类型
- 路径类型示例
- 路径多重匹配
- 主机名通配符
- ingress类
- 名字空间域的参数
- 默认ingress类
- ingress部署的三种模式
- 模式一:NodePort模式的Service
- 模式二:DaemonSet+nodeSelector+HostNetwork
- 模式三:Deployment+LoadBalancer模式的Service
- 模式一的问题:service暴露服务的问题
- DaemonSet+HostNetwork+nodeselector 实操
- nodePort的NAT性能问题
- 指定nginx-ingress-controller运行的node节点
- 修改Deployment为Daemonset,指定节点运行,并开启 hostNetwork
- 启动nginx-ingress-controller
- 查看pod的IP和端口
- 配置ingress资源
- 命令清单
- 生产环境 LVS+keepalive 做高可用和负载均衡
- 边缘节点
- 生产环境可以使用 HA + LB + DaemonSet hostNetwork 架构
- 四种port底层原理:nodePort、port、targetPort、containerPort 的核心
- 1、nodePort
- 2、port
- 3、targetPort
- 4、containerPort
- Ingress 动态域名配置底层原理
- ingress生产建议
- ingress总结
- K8s的常用命令
- kubectl命令 要求
第9部分:蓝绿发布、金丝雀发布、滚动发布、A/B测试 原理和实操
第9部分目录
- 背景:
- 蓝绿发布、金丝雀发布、滚动发布、A/B测试 核心原理
- 蓝绿发布(Blue-green Deployments) 核心原理
- 金丝雀发布(anCanary Releases) 核心原理
- 滚动发布的 核心原理
- A/B测试(A/B Testing) 核心原理
- 蓝绿发布、金丝雀发布、滚动发布实操
- spring cloud 灰度实操
- 反向代理网关灰度实操
- Kubernetes 中的灰度策略
- Deployment金丝雀部署:按照流量比例
- step1 :启动 V1 服务,查看服务是否正确,然后观察一下服务。
- step2:启动 V2 的服务版本:1 个复本
- step3:观察 V2 流量正常的情况的话,那么启动 V2 的 2 个复本。
- step4:删除 V1 的 2 个复本,流量全部到 V2 上。
- 实操总结
- Deployment实现滚动发布
- step1:启动 V1 服务,查看服务是否正确,然后观察一下服务。
- step2:启动 app-v2-rolling 进行滚动发布
- step3:观察所有容器版本变为 V2 版本
- 实操总结
- Deployment实现蓝绿部署
- step1 :启动 V1 服务,查看服务是否正确,然后观察一下服务。
- step2:启动 V2 的服务版本
- step3:将版本 1 服务切换到版本 2,观察服务情况
- patch
- 实操总结
- Ingress Annotations实现金丝雀发布
- Ingress Annotations实现金丝雀发布 实操
- 华为云的金丝雀发布
- 参考
第10部分:服务网格Service Mesh 宏观架构模式
第10部分目录
- 第1大模式:Sidecar (边车)模式 架构
- sidecar的(边车)负责的功能
- sidecar模式好处、坏处
- 如何解决依赖的复杂性和性能问题呢?
- 优化之后的sidecar模式优点:
- 第2大模式:代理模式
- 服务网格 istio 框架微服务与SpringCloud 对比
- SpringCloud 和 istio 中间组件的对比
- 云原生Sidecar分体架构微服务Provider一体架构对比
- 两大基础组件的对比
- 角色sidecar 对应到啥组件?
- 小结:
- Istio 架构
- 控制平和数据面
- Istio 的运转流程
- (1)Sidecar自动注入:
- (2)流量拦截:
- (3)服务发现:
- (4)负载均衡:
- (5)流量治理:
- (6)访问安全:
- (7)服务遥测:
- (8)策略执行:
- (9)外部访问:
- Istio组件介绍
- 2.1 Pilot
- 2.2 Mixer
- 2.3 Citadel
- 2.4 Galley
- 2.5 Sidecar-injector
- 2.6 Proxy(Envoy)
- 2.7 Ingress gateway
- 2.8 其他组件
- Istio安装
- 在本地搭建Istio环境
- Kubernetes集群环境
- 安装Istio
- 快速部署Istio
- 初步感受istio
- 手动注入
- 自动注入sidecar
- istio项目案例:bookinfo
- 什么是bookinfo
- sidecar自动注入到微服务
- 启动bookinfo
- 通过ingress方式访问
- 通过istio的ingress gateway访问
- 确定 Ingress 的 IP 和端口
第11部分:使用K8S+Harber 手动部署 SpringCloud 应用
第11部分目录
- 启动minikube时指定私有仓库
- minikube 复制证书
- 进入minikube虚拟机
- 增加私仓地址配置
- 重启虚拟机的Docker
- 测试
- 完整的命令清单
- Docker构建镜像后通过K8S部署
- 镜像与容器关联
- Docker构建镜像并且推送Harber
- 前提:停止或者重启 Harbor
- 创建Dockerfile
- 镜像构建:将本地镜像打包
- docker build语法
- 镜像打tag:镜像添加版本号
- 镜像推送:镜像推送到远程仓库
- 测试
- 完整的命令清单
- Docker构建镜像并且推送Harber
- k8s的Secrets:
- 创建一个k8s的Secrets:
- 1.Secret对象配置过程
- 2.容器镜像拉取的两种策略
- 2.1 ImagePullPolicy
- 2.2 ImgaePullSecrets
- k8s的configMap对象
- Pod可以通过三种方式来使用ConfigMap,分别为:
- configMap是什么
- 1.单pod使用configmap示例图
- 2.多pod使用configmap示例图
- configmap来配置环境变量
- 步骤1:创建configmap
- 方法1:yaml档来设定configmap
- 方法1:命令行设定configmap
- 步骤3:使用configmap来配置
- 步骤1:创建configmap
- docker-compose to minikube
- 简单案例
- 实操案例
- 参考的原始的docker-compose编排文件
- 设置env环境变量
- k8s向etc/hosts里添加内容
- k8s默认被重写/etc/hosts
- Dockerfile里的配置被覆盖
- 将你的配置写到k8s yml里
- Kubernetes volume hostPath explained with examples
- hostPath
- Example
- 部署和创建服务
- ImagePullBackOff错误排查
- 解决问题:停止后重启 Harbor
- CrashLoopBackOff 错误
- 坑1:镜像拉取是ok,但是依赖包没有
- 坑2:java 进程异常结束了
- 坑3:minikube是套娃虚拟机,套娃里边没有映射目录,远程复制
- 坑4:检查域名和环境变量
- 解决问题有感
- ImagePullBackOff错误排查
- 完整的命令清单
- openresty 镜像
- dockerfile
第12部分:SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
第12部分目录
- 如何进行SpringCloud+Jenkins+ K8s Ingress 灰度发布?
- 回顾Nginx-ingress 架构和原理
- 灰度实操之前的准备
- 部署和测试 stable 版本的 deployment 和 svc
- 部署和测试 canary版本 的 deployment 和 svc
- 基于用户的灰度场景
- 接下来,开始基于 用户的灰度实操
- 基于权重的灰度场景
- 基于权重的 Canary 规则
- 基于权重的发布实操
- 如何进行自动化灰度?
- jenkins安装和pipeline 流水线的使用
- 下载和启动jenkins
- 登录jenkins
- 使用pipeline插件
- 安装Pipeline 插件
- pipeline 的hello world
- pipeline 语法介绍
- Jenkins插件SSH Pipeline Steps
- sshCommand 在远程节点上执行给定的命令并响应输出
- sshGet 从远程主机获取文件或目录
- sshPut 将文件或目录放入远程主机
- sshRemove 删除远程主机上的文件或目录
- sshScript 在远程节点上执行给定的脚本(文件)并响应输出
- 结合 withCredentials 从 Jenkins 凭证存储中读取私钥
- pipeline支持的指令
- ingress 灰度发布流水线设计
- CICD流水线预览
- step1:自动化的制品发布
- 1、克隆 springboot代码项目到本地
- 2、maven构建springboot代码项目
- 3、构建docker镜像
- 4、推送docker镜像到harber上,完成制品发布
- step2:生产环境进行 A/B 测试
- AB测试原理:
- step3:生产环境进行 A/B 测试
- step4:生产环境进行版本正式切换
- 最后总结一下
第13部分:springboot 基于 qps 动态扩缩容
第13部分目录
- 步骤
- 1、springboot安装prometheus依赖并获取metric
- 2、安装prometheus operator 实现 kubernetes的监控指标
- 2.1 helm安装prometheus operator、prometheus adapter(custom metric)
- 2.2 kubernetes的监控指标
- Prometheus Operator 极简配置Prometheus 监控
- Operator
- Operator介绍
- Prometheus Operator vs. kube-prometheus vs. community helm chart
- Prometheus Operator CRD介绍
- 命令清单: 安装的Prometheus
- 查看安装后的CRD、svc、pods:
- 从外部访问promethus
- 访问Prometheus
- 访问Alertmanager
- 访问Grafana
- 移除kube-prometheus
- 解决prometheus-adapter创建失败的问题
- 查看 安装文件
- 解决kube-state-metrics 创建失败的问题
- 解决namespace 删除不来
- 解决prometheus-adapter创建失败的问题
- 配置prometheus -adapter获取应用qps
- prometheus采集到的metrics适配给kubernetes用
- K8s中 kubernetes的监控指标分为两种:
- Metrics-Server 简介
- prometheus-adpater
- 获取 metrics 定制化指标
- checkout 仓库 k8s-prometheus-adapter
- 脚本进行部署 k8s-prometheus-adapter
- 请求metrics.k8s.io的 api
- 直接访问 api 的方式来测试部署是否 ok
- 排错 no matches for kind “APIService” in version "apiregistration.k8s.io/v1
- 查看版本 kubectl api-versions
- Prometheus adapter 的文件介绍
- 配置文件
- resource metrics API
- 命令清单
- 自定义alertmanager的PrometheusRule
- 配置prometheus及adapter获取应用qps
- 启动springboot应用
- 添加自定义指标
- 架构图原理
- 添加一个自定义监控的步骤
- 部署prometheus-adapter
- custom-metrics-server 规则配置
- 指标发现和配置展示(Metrics Discovery and Presentation Configuration)
- http_requests(每秒请求数QPS)监控指标
- 坑: /metrics 路径的定制化修改
- 查询与 http_requests 相关的指标
- 自定义metric rules、配置HPA
- 配置自定义prometheus-adapter-config配置
- 配置 qps 请求量指标
- 查看 “pods/http_server_requests_per_second” 指标
- HPA配置
- 基于Pod做HPA
- 基于cpu或者memory做HPA
- 启动HPA的伸缩控制器
- hpa验证测试
- 配置grafana展示qps监控数据
- hpa命令清单
- 高阶知识:Adapter 的Discovery规则如何配置?
- 以获取Per-pod HTTP Requests为例
- 1 demo问题场景
- 2 配置适配器
- 3 查询api
- 以获取Per-pod HTTP Requests为例
- prometheus operator 不足之处
- 数据持久化
- tsdb 保留天数
- 告警方式不方便
- 加监控target也不方便
第14部分:k8s生产环境容器内部JVM参数配置解析及优化
第14部分目录
- Java Heap基础知识
- 容器环境的Java Heap
- UseContainerSupport
- 最佳实践
- 常用容器内存大小对应的jvm内存配置
- 容器启动常用配置
- 配置项的具体介绍
- 1.堆总内存初始化大小分配和最大值分配
- 2.非堆总内存初始化大小分配和最大值分配(1.8为metaspace)
- 3.堆内存之年轻代年老代大小设置
- 4.线程栈大小
- 5.GC日志输出
- 6.每个线程堆栈大小
- 常用容器内存大小对应的jvm内存配置
- Kubernetes(k8s)配置Java服务自动Dump
- 参考:Go语音解决 java 内存溢出时候 dump 文件的存储问题
- 问题
- 方案
- 其他
说明:由于公众号最多可以发布5W字
还有10W字放不下…
以上几个部分的具体内容,
请参见《K8S学习圣经》PDF
请在公众号《技术自由圈》回复“领电子书”
参考文献:
https://github.com/kubernetes-sigs/prometheus-adapter/blob/master/docs/config.md
https://www.jianshu.com/p/ea5bc56211ee
https://blog.csdn.net/m0_71518373/article/details/127793755
https://blog.csdn.net/huxiutao/article/details/94968889
https://blog.csdn.net/lt_xiaodou/article/details/126666270
Releases · istio/istio (github.com)
https://blog.csdn.net/weixin_40304387/article/details/127800427
https://blog.csdn.net/ohalo/article/details/126290829
http://events.jianshu.io/p/a621d4af6867
https://www.cnblogs.com/liconglong/p/16905844.html
https://www.cnblogs.com/xiao987334176/p/14236554.html
https://kubernetes.io/docs/tasks/tools/
https://minikube.sigs.k8s.io/docs/start/
https://developer.aliyun.com/article/221687
https://blog.csdn.net/fly_leopard/article/details/108790217
https://www.cnblogs.com/yjmyzz/p/install-k8s-on-mac-using-minikube.html
https://blog.csdn.net/qq_38340601/article/details/108437017
https://www.cnblogs.com/zhengchunyuan/p/12598210.html
https://blog.csdn.net/weixin_46108954/article/details/105717399
https://blog.csdn.net/swalikh/article/details/117995440
https://blog.csdn.net/weixin_44729138/article/details/124394257
https://blog.csdn.net/weixin_44729138/article/details/124394257
https://andyoung.blog.csdn.net/article/details/127965449
https://www.jianshu.com/p/8aa4ae9be025
https://zhuanlan.zhihu.com/p/514799248
https://www.qikqiak.com/k8s-book/docs/58.Prometheus%20Operator.html
https://www.cnblogs.com/wangxu01/articles/11652372.html
https://blog.csdn.net/shida_csdn/article/details/81077972
https://blog.csdn.net/u010918487/article/details/119052933
技术自由的实现路径:
实现你的 架构自由:
《阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了》
《峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?》
… 更多架构文章,正在添加中
实现你的 响应式 自由:
这是老版本 《Flux、Mono、Reactor 实战(史上最全)》
实现你的 spring cloud 自由:
《Spring cloud Alibaba 学习圣经》 PDF
《分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)》
《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)》
实现你的 linux 自由:
实现你的 网络 自由:
《网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!》
实现你的 分布式锁 自由:
实现你的 王者组件 自由:
《队列之王: Disruptor 原理、架构、源码 一文穿透》
《缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)》
《Java Agent 探针、字节码增强 ByteBuddy(史上最全)》
实现你的 面试题 自由:
以上尼恩 架构笔记、面试题 的PDF文件,请到《技术自由圈》公众号领取 ↓ ↓ ↓