知识点积累系列(四)Kubernetes篇【持续更新】

云原生学习路线导航页(持续更新中)

本文是 知识点积累 系列文章的第四篇,记录日常学习中遇到的 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.102
  phase: Running
  podIP: 10.244.2.74
  podIPs:
  - 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篇【持续更新】_第1张图片

  • 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进程。
  • 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

你可能感兴趣的:(云原生学习专栏,kubernetes,容器,云原生,golang,devops,go)