作者:乔克
公众号:运维开发故事
知乎:乔克叔叔
大家好,我是乔克,一名一线运维实践者。
Kubernetes 越来越流行,也有越来越多的公司,越来越多的人加入 Kubernetes 的队伍,经常也有网友问我“对于菜鸟应该如何学习 Kubernetes”,今天我总结一下自己的学习方法,希望对大家有所帮助。
本篇文章主要从以下三个方面来做介绍。
看完本篇文章,你将对 Kubernetes 有一个整体的认识,并且能够在脑海里形成一个简单的学习流程图。
启航:如何进入 Kubernetes
Kubernetes 的基础理论特别多,而且涉及的范围比较广,除了自身的组件,还涉及一些网络、存储等相关知识,整体的基础知识如下:
在整个知识链路上,容器是重要的一环,它是整个组织结构中的基石。
容器知识
说明:这里阐述的容器主要是指 Docker。
对于容器的学习,如果只是从使用上来说,学习的东西并不多,如下:
看起来很多,但是整体的知识结构相对比较简单,基本只要掌握 Docker 命令的基础用法,镜像的制作方式就可以了,如果要深入一点,就可以研究一下 Docker 的实现原理还有安全相关的知识。
基础组件
学习一个新的事物,首先看到的是整体的一个架子,然后慢慢向里面参透。对于 Kubernetes 也是这样,我们要先学习 Kubernetes 的基础组件,看看它们到底有哪些以及相互之间是什么关系,这样就可以对 Kubernetes 有一个整体的认识。如下:
这里主要掌握这些基础组件是什么以及它们各自的功能,还有它们之间是如何协作的。这里贴一个简单的架构图,更多的知识需要自己深一步专业系统的学习,如下:
到这里是不是对 Kubernetes 有了一个简单的认识了?原来 Kubernetes 是由 Master 节点和 Node 节点组成,Master 节点主要有 kube-scheduler、kube-controller-manager、kube-apiserver 组成,Node 节点主要由 kube-proxy、kubelet 组成,它们都通过 kube-apiserver 和存储 ectd 进行交互。
关键对象
对基础组件有一个系统的认识过后,就来看看 kubernetes 有哪些重要的对象,这些对象到底承担了何作用。
这里主要掌握以下 6 种关键对象。
这几个对象应该怎么学习呢?主要从以下三个步骤来:
- 是什么
- 有什么
- 怎么做
就拿 Service 来说,如下:
- Service 是为 Pod 提供负载的入口,它通过 Label 标签来选择后端 Pod,不会因为 Pod 的 IP 地址变更而受影响,从而为 Pod 提供一个稳定的入口。
- Service 有三种模式,分别是 UserSpace、Iptables、Ipvs,并且还有四种类型,分别是 Cluster IP,LoadBalance,NodePort,ExternalName。
- 在定义 Service 的时候,确定好类型,然后定义好 LabelSelector,就可以正确代理后端 Pod 了。
通过这几步,其实就可以大概了解 Service 了,其他对象也是一样,这里不再赘述,需要自己系统的学习和整理。
控制器
在学完关键对象中的 Pod 后,就会发现 Pod 其实就是应用的主体,如果仅仅只有 Pod,在维护的时候是不是会很麻烦?比如要多副本,我们是不是就要创建多个 Pod,并且 Pod 名还不能重复。
所以社区就不断延伸出控制器的概念,用控制器来控制 Pod 的生命周期。
主要要学习的控制器如下。
对于控制器,主要从以下三个方面进行学习:
- 功能是什么
- 如何配置
- 使用场景
在实际的工作中,接触最多的就是这些控制器,熟练掌握它们的功能以及使用场景,就可以在需要的时候灵活进行配置了。
存储
存储是万恶之源,也是重中之重。
Kubernetes 为了能更好的支持有状态应用的数据存储问题,除了基本的 HostPath 和 EmptyDir 提供的数据持久化方案之外,还提供了 PV,PVC 和 StorageClass 资源对象来对存储进行管理。
这里重点学习 PV、PVC、StorageClass,在实际工作中是经常使用的。主要从以下几个方面进行掌握:
- 功能、逻辑是什么
- 实现的方式、步骤是什么
- 配置方法是什么
然后再了解一下访问模式以及回收策略,通过这样的方式这三个对象基本就能掌握了。
然后再学习一下常用的存储软件,比如:
其中 Ceph 的学习难度相对比较大一点,其他几个轻松一些,具体怎么选择就看怎么需要了。
网络
互联网离不开网络,Kubernetes 也是一样。
如果仅是简简单单的把 Kubernetes 的架子搭好,没有网络进行连通,Kubernetes 就是一个中看不中用的东西,足以可见,只要有网络,就可以连通这个世界是多么正确。
首先要掌握整体的一个网络模型,然后再掌握 1-2 种网络插件,目前用的比较多的是 Flannel 和 Calico,Cilium 目前的势头也很猛,有时间可以多学习学习,它是基于 eBPF 的高性能容器网络方案。
最后可以了解一下网络策略这个事,也许你用不到。
资源管理、调度
上面的基础知识学习完后,基本可以简单使用 Kubernetes 了,然后再来学习一下资源管理和调度相关的知识。
在 Kubernetes 中,Pod 是最小的调度单元,所以跟资源和调度相关的属性都是 Pod 对象的字段,而其中最重要的就是 CPU 和内存,最重要的两个字段就是 requests 合 limites,如下:
由这两个字段又引出了 QoS 模型,相应的就可以具体去了解一下这三种模型的具体定义以及使用场景。
学习资源管理的时候,发现配置资源都是针对与 Pod,如果有很多资源,这些资源如果不配置是不是可以设置一个默认的 resources/limits?这时候就可以再去了解一下 LimitRange
,看看如何为 namespace 做一个整体的配置。
在学习基础组件的时候会了解一个叫 kube-scheduler 的东西,现在就可以来具体学习一下,可以了解一下基本的调度策略以及调度算法。然后再深入学习高级调度的方式方法,在实际工作中会经常用到。
使用一段 Kubernetes 后,有时候会发现不论怎么设置调度,总有调度不均衡的情况,这时候怎么办呢?
- 使用 DeScheduler 进行临时性的处理
- 仔细分配测试,合理配置亲和性以及反亲和性,合理配置 Pod 的 requests 和 limits
权限管理
Kubernetes 在权限管理方面经过一系列的迭代升级,这里学习 RBAC(基于角色的访问控制)就足够了。
学习它们的授权机制以及配置方法就可以使用了。
到此,启航之路就已经完成了,如果严格按照这种路线来进行学习,到目前位置,你对 Kubernetes 其实有一个比较全面的认识了,可以开始基本使用。
领航:如何用好 Kubernetes
但是在企业中,光会用是不够的,要学会用好。
要怎么才能用好 Kubernetes 呢?
在进入 Kubernetes 的世界之后,会发现这个世界没那么简单。Kubernetes 仅仅是给我们提供了一个平台,这个平台提供了一些基础能力,但是更多的是需要用户自己往里加的,比如集群监控、日志管理等,如下:
集群管理
集群管理包括哪些呢?
这里简单整理下面三个方面。
1)关于部署
现在集群部署的方式多种多样,有开源的工具,也有官方的工具,也有二进制方式,还有云平台的服务,那究竟应该选哪种呢?
这里说说我自己的一点想法。
如果是自建的测试环境,我还比较推荐使用 kubeadm
的方式进行部署,这种方式目前比较成熟,维护起来也相对简单。
如果使用公有云,比如阿里云、腾讯云这些,建议使用它们的服务,这种方式可以给我们节约很大人力成本和维护成本,我个人是比较推荐的。
2)关于备份
你对集群进行备份了吗?
我之前有问过一些朋友,发现很多人都不备份,这并不是一个好习惯。
你对集群有多尊重,集群就对你有多尊重。
备份的作用主要是为系统可用提供一种保障,对于 Kubernetes,我们可以做哪些备份?我简单整理如下:
Etcd 是 Kubernetes 的唯一存储,所有的信息都保存在 etcd 中,可见其重要程度,它目前有如下两种方式进行备份。
日常情况下,可以直接使用内置快照进行备份,命令也比较简单,如下:
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb
大多数情况下,备份 Etcd 集群就够了,但是保不齐有时候恢复 Etcd 快照异常,这时候如果有集群所以资源的备份,就可以提供双重保险。
需要备份的主要资源有:
- Deployment
- Namespace
- Secret
- ConfigMap
- StatefuleSet
- DaemonSet
- …
备份的工具可以自己写脚本,也可以使用开源的工具。如果使用开源的工具,推荐使用 velero
,它是一个比较成熟的开源工具。
3)关于恢复
备份和恢复其实是一家子,但是很多时候,我们只备份,从不恢复,直到出问题。如果能正常恢复就万事大吉,如果不能,那就怨天尤人。
所以我们需要时常做一些恢复演练,这样才能把它盘活,自己心里也才有底。
日志管理
Kubernetes 给我们提供了一个平台,我们可以把应用部署到集群中,它也给了简单的日志查看命令,但是它的日志是临时的,应用重建或者删除,它对应的日志也就没有了,这时候就要考虑应用日志管理的问题。
日志管理无外乎日志收集、存储、展示以及告警,目前的方案大概有以下 4 种。
1)开源 ELK
开源的 ELK 是一个比较成熟的开源方案,也是大部分互联网公司的首选,如果你不知道用什么,就用 ELK 好了。
ELK 的部署方式比较灵活,在网上的解决方案也比较多。可以通过 helm 包,也可以通过 eck,选择自己熟悉的就好。
并且可以使用 ElastAlert 进行日志告警,便于发现和查找问题。
2)开源 Loki
Loki 是一个轻量级的日志集中系统,与其他日志系统不同,Loki 是基于仅索引有关日志的元数据的想法而构建的:标签(就像 Prometheus 标签一样)。 然后,日志数据本身被压缩并存储在对象存储(例如 S3 或 GCS)中的块中,甚至存储在文件系统本地。 小索引和高度压缩的块简化了操作,并大大降低了 Loki 的成本。相较于 EKL,Loki 就显得很轻量级了。
然后其通过 Grafana 进行日志检索、展示,如果对这种操作方式比较熟悉的可以选择学习以及尝试。
3)公有云日志服务
如果 Kubernetes 集群是在公有云上,我还比较推荐使用公有云的日志服务,它在索引建立、日志搜索以及日志告警方面做的比较好,然后还有一些监控面板做展示,最主要的一点是降低了运维的维护成本。
4)第三方日志服务
第三方日志服务我用的比较少,这里不做多的阐述,自己酌情选择。
监控系统
不论是 Kubernetes 还是运行在 Kubernetes 中的应用,对外都是黑盒,我们不知道它们到底怎么样了,健不健康,如果不健康是哪里出问题了。
当我们对这一切都未知的时候,我们的恐惧的。
所以我们就有必要对这些资源进行监控,便于查看它们的状态以及问题。
监控系统涉及的方面比较多,这里仅做一些简单的整理归纳,如下。
1)主机监控
Kubernetes 运行在主机之上,所以对主机的监控是必要的,主要的监控指标如下。
2)事件监控
通过事件监控可以监控一些被资源监控忽略的问题,比如:
目前阿里开源的 kube-eventer 是专门用于 Kubernetes 集群的事件监控。
3)链路监控
链路监控是针对应用系统,通过链路监控可以发现以下问题。
目前市面上开源的链路监控工具比较多,我使用最多的是 Skywalking。
4)站点监控
站点监控主要是针对应用站点,通过白盒的方式进行监控,如果应用出现故障,可以通过拨测的方式发现问题。
有很多商业的站点监控系统,比如公有云的站点监控工具,其主要有以下功能。
5)kubernetes 集群监控
上面说的这些监控没有涉及到 Kubernetes 集群本身的组件监控,但是这些又是必须的,列出如下:
通过对这些进行监控,可以发现集群的整体健康程度。
6)应用监控
这里的应用监控主要是指中间件的应用,因为业务系统依赖这些中间件,所以我们需要对它们进行有效监控,保障其稳定性。
7)日志监控
日志监控在日志管理
章节有做监控的介绍。对日志的监控便于我们能够查找、定位应用故障。
对于日志监控最重要的点在于关键字的设定,开发人员不要设定一些模拟两可的关键字,要定义那些能直接反应问题的关键字。
8)告警
上面一直在说监控,虽然我们监控了,但是我们也不会时时去盯着监控系统,这时候就需要告警系统,当系统出问题能够通过一些方式通知到相关人员。
关于告警主要关注以下几点:
DevOps
上面说的更多的是保障稳定性相关的问题,这里主要说说效率提升的问题。
最近几年,国内都在宣讲 DevOps,也因此专门有一个 DevOps 工程师的职业,我们这里肯定达不到专业的程度,但是 DevOps 中的 CI/CD 还是要做的。
现在对于 CI/CD,主要有两个方向:
- 开源工具集成
- 自研平台
开源的工具有很多,我一般使用 Jenkins 和 GitlabCI,主要是这两种在国内的使用度比较高,有问题方便处理。当然也有更贴近云原生的工具比如 Tekton、Argo Workflow 等。
我之前也写过一些 jenkins 和 Argocd 进行结合的方式,有兴趣的可以去《运维开发故事》公众号进行搜索学习。
到目前为止,掌握如上的技能或者要点,可以在很多企业正常工作了。
远航:如何深入 Kubernetes
通过启航和领航的过程,我们基本可以熟练运用 Kubernetes 了,那我们还可以怎么深入呢?这里简单的做一下总结,因为我也还不深入。
要深入了解一个东西,就要把它摸透。
1)深入原理
要明白一个事物,就必须要懂其原理。所以我们可以要深入学习 Kubernetes 的原理,吃透其整个过程。
2)源码学习
源码学习的成本还是比较高,首先先会 Go 语言,其次要会阅读源码,再次是要有耐心。
Kubernetes 的源码很多,单纯的自己去看估计会看懵逼,可以借助《Kubernetes 源码剖析》这本书进行辅助学习。
3)Operator 开发
Operator 开发其实并不需要先学习源码,只要会 Go 语言即可。目前有两个比较成熟的脚手架:
- kubebuilder
- operator-sdk
用哪一个都差不多,只要自己熟悉即可。
4)参与开源项目
最好的学习,就是参与其中。
如果比较热爱开源项目,也有这方面的技术实力和经验,其实可以多参与,这样的效果更明显。
以上就是个人对深入 Kubernetes 的一点理解,写的比较简单,因为我的理解也比较简单。
总结
好了,总结一下这篇文章的重点。
1、学习 Kubernetes,应该从简入繁,通过阶梯式的学习,学习效果会比较明显。
2、要用好 Kubernetes,需要去了解它的整个生态,还要通过不同的方式方法去提高稳定性和效率,包括但不限于日志管理、监控系统建设、DevOps 体系建设等。
3、除了上升式的学习,还有下沉式的学习。通过一些原理的学习、源码的学习可以对 Kubernetes 进行更深的了解,然后可以参与一些项目开发来提升自己的认知。
写这篇文章的初衷是整理一下自己的知识体系,在整理的过程中发现有些地方还是值得分享,所以就写下了这篇文章,同时也发现了自己许多的不足,希望本篇文章对你也所有帮助。
最后附一张全景图。