云原生学习路线导航页(持续更新中)
本文是 知识点积累 系列文章的第四篇,记录日常学习中遇到的 Kubernetes 相关的知识点
1.Kubernetes琐碎知识点
1.1.为什么要有annotations
- annotation中除了能够记录一些额外信息,还可以解决kubernetes的新功能特性的支持和过渡问题
- 每当要添加新功能,不要直接去改配置的组织格式(就是yaml的编排结构)
- 先在annotations中添加一下,让这个功能先加上,等到功能完善之后,再从annotations中取出来,设计成yaml中的结构。
- 优缺点:
- 实验性的新特性、尚未完善的新特性,都可以加入,升级方便
- 啥都往annotations中放,不太美观
- 举例:
- kubernetes1.3中,initContainer引入,先放入的annotations,后来1.8的时候,才引入到pod的spec中
1.2.YAML中多行字符串的配置方法:|+、|、|-、>+、>、>-的区别
- 参考博客:https://blog.csdn.net/a772304419/article/details/126141668
1.3.kubernetes内置的一些标签、注解、污点列表
- https://kubernetes.io/zh-cn/docs/reference/labels-annotations-taints/#topologykubernetesiozone
1.4.kube-apiserver 6443端口、8080端口、443端口的区别
- https://www.apispace.com/news/post/10771.html
1.5.kubectl explain 如何指定版本
- 添加参数 --api-version,举例:
kubectl explain hpa.spec.metrics --api-version=autoscaling/v2beta2
1.6.pod.status中的podIP和podIPs有什么区别
status:...hostIP: 192.168.245.102phase: RunningpodIP: 10.244.2.74podIPs:- ip: 10.244.2.74
-
podIP
- podIP 是一个字符串,表示 Pod 的 IP 地址。每个 Pod 在创建时都会分配一个唯一的 IP 地址,用于在集群内部进行通信。
- 该 IP 地址是 Pod 内部网络的标识符,其他 Pod 可以使用该地址与该 Pod 进行通信。
- 通常情况下,Pod 的 IP 地址是动态分配的,但也可以使用静态 IP 地址。
-
podIPs
- podIPs 是一个 IP 地址列表,表示 Pod 可能具有多个 IP 地址。
- 这种情况通常发生在 Pod 具有多个网络接口或多个网络插件配置的情况下。
- 例如,当使用 CNI 插件时,Pod 可能会分配多个 IP 地址,每个 IP 地址对应于一个网络接口。
1.7.ingress的3个概念:Ingress / IngressController / IngressClass有什么区别
参考文章:5分钟搞懂Ingress / IngressController / IngressClass的区别
下面是一些个人理解:
- ingress:其实就是kubernetes提供的一个资源,本身不代表什么,需要ingressController来将它解析成具体的映射规则,它才能生效
- ingress Controller:其实就是一个角色,一个概念,表示管理ingress的控制器,负责解析ingress的声明,监听对应的service变化,生成最新的 转发规则
- ingress Class:ingress Controller的具体实现,我们平时说安装一个ingressController,其实就是安装一个 具体的ingress Class。比如 nginx-ingress-controller
综上,我们使用ingress,需要先安装一个 ingressController的具体实现,然后再编写ingress yaml文件
1.8.ingress controller的nginx配置文件在哪里
- k8s的nginx配置文件在哪里
1.9.kubernetes的运行时:docker和containerd的关系
- 参考了博客:https://cloud.tencent.com/developer/article/2154031、https://www.51cto.com/article/765823.html,我 梳理了下过程。
- 早期,docker一家独大,kubernetes直接支持docker。后来为了防止docker一家独大,docker被拆分出了几个标准化的模块,为的就是更方便地替换某个模块。
- docker-client
- dockerd
- containerd:纯粹、轻量的容器运行时
- docker-shim
- runc
- K8s社区认可了containerd的优势,将其作为K8s生态系统的标配容器运行时,让containerd在宿主机负责以下功能:
- 管理容器的生命周期(从创建容器到销毁容器)
- 拉取/推送容器镜像
- 存储管理(管理镜像及容器数据的存储)
- 调用 runC 运行容器(与 runC 等容器运行时交互)
- 管理容器网络接口及网络
- 就在docker刚拆出来containerd不久,kubernetes 1.5版本 引入了CRI(container runtime interface)的概念,作为kubelet和容器运行时交互的统一接口规范。至此,kubelet与容器运行时交互就使用CRI,底层可以使用任意符合CRI规范的运行时。
- 不过,docker发展的早,并不支持CRI,为此,kubernetes团队专门为docker开发了一个dockershim(shim:临时的)。通过dockershim适配docker,让docker支持CRI
- dockershim由kubernetes维护,当docker发布新的版本时,kubernetes也需要维护dockershim适配docker新版本,这很耗费精力。
- docker中真正工作的高级运行时是Containerd,kubernetes使用dockershim对接docker,还不如直接对接containerd,所以后来对containerd做了CRI的支持(CRI-Containerd),让kubelet直接对接符合规范的CRI-containerd,这样更加标准,调用的链路也更短
- 所以kubernetes1.24时,kubernetes宣布正式删除和弃用dockershim。因此1.24大家都说不再支持docker,本质上是废弃了内置的 dockershim 功能,而是直接去对接containerd。并不是说以后不能使用docker了
- 发展过程图如下:参考自博客
- 上图中,可以看出containerd后来做了插件化处理,为CRI规范开发了一个插件适配,这样以后如果有其他规范,只需要再开发相应的插件即可。
1.10.如何修改kube-scheduler的调度策略
- 官方文档有详细介绍:https://kubernetes.io/zh-cn/docs/reference/scheduling/config/
1.11.kubernetes API 完整列表
- 1.24版本:
- https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/
- 1.29版本:
- https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/
1.12.kubernetes中的内存单位Mi/M、Gi/G的区别
- 结论:
- Mi表示(1Mi=1024x1024B)
- M表示(1M=1000x1000B)
- 其它单位类推, 如Ki/K Gi/G
- 详细+测试:https://www.jianshu.com/p/f798b02363e8
1.13.kubernetes如何根据Pod找到所属的控制器?
- pod yaml的元数据里,有一个ownerReferences,写了它属于谁
kubectl get pods podName -n ns -oyaml
,就可以看到
1.14.如何在Pod和本地之间复制文件
- pod中文件 复制到 本地。如果pod有多个容器,就指定 -c
kubectl cp <pod_name>:<container_path> <local_file_path> -c <container_name> // 举例 kubectl cp nginx-6ddbbc47fb-sfdcv:/etc/fstab /tmp kubectl cp nginx-6ddbbc47fb-sfdcv:/etc/fstab /tmp -c nginx1
- 本地文件 复制到 pod中。如果pod有多个容器,就指定 -c
kubectl cp <local_file_path> <pod_name>:<container_path> -c <container_name> kubectl cp /tmp nginx-6ddbbc47fb-sfdcv:/etc/fstab kubectl cp /tmp nginx-6ddbbc47fb-sfdcv:/etc/fstab -c nginx1
1.15.kubernetes 中 NodeIP、PodIP、serviceIP、Pod内容器IP 辨析
-
kubernetes 中,涉及到4种ip:NodeIP、PodIP、serviceIP、Pod内容器IP。初学者难以分清他们的区别,容易混淆,下面对它们一一讲解。
-
NodeIP
- 就是你的机器,物理网卡所提供的那个ip,比如我安装的虚拟机,ip是192.168.200.100,那么这个node的nodeIP就是192.168.200.100
-
PodIP
- 我们使用docker作为容器运行时的时候,docker的网络模型中,会创建一个叫做docker0的网桥,docker的网段由docker daemon进程分配,一般是172开头,比如172.17.0.19/32。
- docker0网桥,一个node上就会有一个,所以不同的node上,docker0网桥的网段,可能不一样。
- 同一个node上,所有的podIP,都是由docker0网桥负责分配的,podIP与docker0网桥的网段一致。因此,通过docker0作为中转点,同一台node上的所有pod,都可以直接通信。
- 不同node上的pod,podIP不一定在一个网段,所以不可以直接通信,需要使用一些网络插件(或者手动在机器上维护路由表),将不同node进行打通,这样就可以跨node进行pod通信了。
-
ServiceIP
- kubernetes的核心进程 kube-apiserver,启动的时候,可以指定一些启动参数,其中有一个参数
--service-cluster-ip-range
,用于指定 cluster-ip 的网段。如果不指定,默认网段一般是10.96.0.0/12
- 使用参数
--service-cluster-ip-range
指定service网段的时候,可以指定任意网段,只要不和docker0、物理网卡的网段冲突即可。(能任意指定,就意味着,这个clusterIP根本没想着在外界使用) - 另外,在 kubernetes 中,每个 node 上都有一个 kube-proxy 进程,在创建 service 的时候,kube-proxy 会从 service 的 cluster-ip 网段中,自动分配一个 clusterIP(当然也可以在创建的时候,手动指定确定的clusterIP)
- 创建service的同时,kube-proxy还会给这个service关联一个默认的端口(我这里称他为P1吧),P1端口由kubernetes自动生成,与service的port没有直接关系。
- P1端口的作用是:将该service与kube-proxy关联起来,使得访问service clusterIP+port 的流量,可以通过P1进入kube-proxy,kube-proxy根据负载均衡算法选中某一个pod后,将流量转发给该pod。
- 因此,service仅仅是一个资源,没有真正的功能,真正实现service功能的,是node上的kube-proxy进程。
- kubernetes的核心进程 kube-apiserver,启动的时候,可以指定一些启动参数,其中有一个参数
-
Pod 内容器的 IP
- 为了保证同一个pod中多个容器的通信,并且便于管理网络资源等,其实每一个pod中,除了你创建的业务容器,都额外还有一个 pause容器
- 同一个pod中的所有容器,共用pause容器的网络堆栈,即内部的所有容器,都使用这一个podIP,所以同一个pod中的所有容器,可以使用localhost相互访问
- 因此,从这里来看,并非一个容器是一台独立的机器,更像是一个pod是一台独立的机器,pod内的所有容器,就像是运行在一台机器上的不同进程
- 这是牺牲了部分隔离性,换来管理上的方便。如果你的多个容器,需要完全意义上的隔离性,那么部署成多个pod就可以了
-
大家可以配合上面的图理解
2.Kubernetes进阶内容【TODO】
这部分。是在学习过程中发现的一些扩展点,可以深入学习,或者作为一个专门的方向深入研究
2.1.ReadinessProbe的扩展:Readiness Gate
- 学习博客:https://cloud.tencent.com/developer/article/1661689?pos=comment
- 自定义RG controller:https://github.com/du2016/readnessgate-controller
- TODO:将是很好的扩展方式
2.2.开发并使用自定义调度器完成pod调度
- 学习博客:https://www.qikqiak.com/post/custom-kube-scheduler/
2.3.利用Prometheus+hpa自定义监控指标
2.4.使用headless service实现自定义负载均衡策略
2.5.service的LoadBalancer类型、vpc等
2.6.service和kube-proxy的关系
https://www.cnblogs.com/chadiandianwenrou/p/13860520.html
2.7.自定义一个IngressController,实现转发规则的自动更新
3.待学习的开源项目【TODO】
这里主要是学习过程中发现的一些比较好的开源项目,以后有时间了会深入学习,也会出文章
3.1.CoreDNS
- 地址:https://github.com/coredns/coredns
- CoreDNS 是一个用于 Kubernetes 集群中 DNS 解析的开源项目,是一个轻量级的 DNS 服务器。
- 截至目前(2023年),CoreDNS 的代码库中包含了大约 12,000 行左右的代码。
- CoreDNS 是一个功能强大、可靠且广泛使用的 DNS 解析器,适用于 Kubernetes 集群中的服务发现和网络通信。
3.2.etcd
- etcd(读作 et-see-dee)是一种开源的分布式统一键值存储,用于分布式系统或计算机集群的共享配置、服务发现和的调度协调。
- 为了更深入的掌握kubernetes,有必要学习一下etcd
- github地址:https://github.com/etcd-io/etcd
- 官网地址:https://etcd.io/
- RedHat 为ETCD 开发了一个Operator,可以作为学习Operator的资料
- https://www.redhat.com/zh/topics/containers/what-is-etcd
3.3.go-delve
- go-delve 是一个开源项目,为go语言提供debug能力,简单易用,github地址:https://github.com/go-delve/delve
- go-delve 属于golang语言基础设施的一部分,像vscode的go语言插件、goland调试功能等,底层都是使用了delve。
3.4.cobra
- Cobra 是一款非常流行的命令行生成工具,由 Go 语言实现,比如说著名的博客工具 Hugo , GitHub 命令行等都是用它实现的。kubernetes也大量使用了它。
- github地址:https://github.com/spf13/cobra
3.5.gen-go
- gengo 是 kubernetes 项目中常用的代码生成工具,kubernetes 项目中大量使用了这个工具用于代码生成。
- gengo 更多的设计为一个比较通用的代码生成工具,完成代码表达树解析,生成的工作。
- github地址:https://github.com/kubernetes/gengo
- 学习博客:https://cloud.tencent.com/developer/article/1635822