云原生学习路线导航页(持续更新中)
- 快捷链接
- Kubernetes架构原则和对象设计
本文对Kubernetes学习中常见的一些问题,进行解答
1.什么时候使用公有云,什么时候使用自建k8s
- 看公司规模,规模小使用公有云,规模足够大使用自建云
2.什么是Job
- 如果你的一个应用24h都在跑,那就是一个Long Time Running的一个作业
- 而Job是一个短时作业,运行完就退出,而且不会重启
- CronJob也是一个短时作业,运行完就退出,而且不会重启
3.Job和Pod的区别
4.一个集群应该设计为多大规模?
一个集群应该设计为多大规模,需要从很多个维度去考虑
- 一个集群应该设计为多大规模,首先应该考虑一个集群的控制面能管理多大规模的集群,比如kubernetes号称能管理5,000节点
- 有的公司进行了优化后,将控制面管理node数量扩大到了10000
- 有的公司觉的 一个集群过大都不一定好。
- 实际上,集群规模过大过小都不好
- 故障域的控制。一个集群规模过大,如果控制面坏了造成的影响将会更大,集群内所有机器的故障转移、扩缩容等都会失效
- 如果集群规模过小,那么可能面临过多的集群,意味着你的维护成本就上去了。
- 因此,需要平衡自己公司的业务情况,决定一个集群的大小
5.有状态应用和无状态应用
- 无状态应用
- 假设一个Web应用,只有一个war包,没有任何本地数据,所有的数据都存在云端数据库中,即数据的存储和应用本身分离了,那么这个应用就是一个无状态应用了
- 无状态应用实例坏了,可以直接启动一个替换它,没有任何本地的依赖
- 还有一些应用,本地会记录一些Session信息,现在也不推荐了,鼓励应用内部无状态,这样能够更好的和Kubernetes等云平台融合
- 目前大多数应用都是无状态应用,之前讲过12 factor的原则,就是鼓励无状态
- https://www.huweihuang.com/kubernetes-notes/paas/12-factor.html
- 有人说90%应用都是无状态的,不知道怎么统计的
- 有状态应用
- 一般来说,有本地数据存储的应用都是有状态的,实例坏了后,依赖本地数据,无法直接启动一个新的实例替代它
- statefulset为什么有时无法满足需求?因为statefulset它本身也比较简单,对于太复杂的应用,它做不了。另一方面,statefulset也有一些故障转移等能力,如果这个能力会破坏你的应用,那就不能用了
- 比如mysql集群,不同实例还需要区分身份,配置和启动脚本也可能有所不同,所以mysql就是没有办法简单描述的,一般都需要单独定制Operator
6.Operator SDK 和 Kubebuilder 怎么选?
- Kubebuilder本身就是operator SDK的封装
- 目前Kubebuilder是作为一个更核心的项目维护的,所以更推荐Kubebuilder
7.什么是云原生
- 应用设计之初就考虑了上云的各种事情
- 以前叫 Cloud Ready,现在统一叫 Cloud Native
8.Aggregated APIServer的使用案例
- 比如 要给pod做 HPA 自动扩缩容,肯定是需要一些cpu、memory等指标数据的,这些指标要在APIServer中取
- 在原生APIServer中是不包含这些指标的,因此可以自己写一个 Metrics APIServer,以 Aggregated APIServer的方式嵌入到APIServer中去,HPA的一些Controller就可以在APIServer中获取这些metrics指标数据了
- 目前kubernetes社区已经有了开源的 metrics APIServer:即 metrics-server
- https://github.com/kubernetes-sigs/metrics-server
- 官方文档
- 安装之后,可以使用kubectl top命令,查看指标
- 比如
kubectl top node
就可以展示node的cpu、memory等使用情况
- 比如
9.Kubernetes的扩展方式
- 扩展方式有很多种,比如:
- Aggregated APIServer:扩展自己的APIServer
- CRD:扩展Operator控制器
10.Kubernetes源码应该阅读哪个版本。
- 生产需要:就看自己需要的版本
- 非生产需要:直接看master最新代码即可
11.什么时候用kubectl apply 和 kubectl create
- 可以优先用kubectl apply,但是有些极端场景下apply会失败
- kubectl create语义更明确,不过不适用于patch
12.中型互联网上云时间大约多久
- 一家中型互联网公司,要从 传统虚拟机应用部署架构 转到 容器微服务架构,一般要以年为计算单位。
- 假设一个公司有 100多个集群,10w 物理计算node ,100w pod数量,一般需要数年才能完全上云,周期很长
13.CRI使用Docker的情况下,为什么还使用CNI,而不用Docker的网络管理CNM?
- CNM太厚重了
14.怎么用Deployment+Service实现生产级高可用?
- Deployment实现冗余部署、故障转移、滚动发布
.spec.raplicas
值>1,即 冗余部署- Deployment 会负责故障转移,pod被删除后会自动重建
- Deployment 的
.spec.strategy
可以设置滚动更新配置
- Service提供多pod的负载均衡,外部访问的时候就有统一的ip+port,不依赖于具体的podIp,当pod重建后Podip改变,也不会影响外部的访问
- 冗余部署 + 负载均衡,其实就实现了一个生产级的高可用。
15.怎么观察Deployment的滚动更新
- kubectl describe,在event中可以看出,滚动更新是启动一个新的ReplicaSet,然后新的+1,旧的-1,不断滚动
16.kubectl 和 kubeconfig 是怎么运作的
- 执行kubectl命令的时候,添加 -v 9,即可开启debug日志,可以看到kubectl到底干了什么
- 可以看到,kubectl命令首先加载了 /root/.kube/config 文件,获取到了当前要连接的集群信息,及user认证信息cert、key
- 然后向apiserver发送get请求
- kubeconfig内容
- kubectl从其中获取当前正在使用的上下文,并使用 该上下文中 指定的user 连接 指定的cluster
- kubeconfig 默认路径:/root/.kube/config,当然你可以通过设置 KUBECONFIG 环境变量或者设置 --kubeconfig参数来指定其他 kubeconfig 文件
- 官方文档:https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/
17.Deployment为什么不直接管理pod
- 就像微服务设计思想,我们更希望让 多个组件各自做自己关心的事情,而不是所有的逻辑都放在一个组件中做
- Deployment直接管理pod当然可以,但是会使得Deployment的逻辑变得很复杂
- 相反,Deployment直接管理ReplicaSet,可以让Deployment直接获得pod的伸缩等基本能力,Deployment可以更专注于 滚动升级 等更高层次的功能
18.Controller的Informer和Lister两个接口的区别
- 一个Kubernetes的Controller,一般都会包括两个接口Informer和Lister
- Lister负责将 所关心资源 全部List过俩
- Informer负责Watch变化,获得增量
19.Deployment的滚动更新maxunavailable有没有经验值?
- 不太有通用的经验值,和你的应用特性、部署时资源预留量 都有关系。
- 假设 部署的时候预留20%资源,即本来需要10个就够了,但是部署的时候启动了12个pod
- 那么maxunavailable就可以设置为20%,当有20%的pod不可用时,暂停升级,且不会影响业务