知识点积累系列(四)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中多行字符串的配置方法:|+、|、|-、>+、>、>-的区别

1.3.kubernetes内置的一些标签、注解、污点列表

1.4.kube-apiserver 6443端口、8080端口、443端口的区别

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配置文件在哪里

1.9.kubernetes的运行时:docker和containerd的关系

  • 参考了博客:https://cloud.tencent.com/developer/article/2154031https://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的调度策略

1.11.kubernetes API 完整列表

1.12.kubernetes中的内存单位Mi/M、Gi/G的区别

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进程。
  • Pod 内容器的 IP

    • 为了保证同一个pod中多个容器的通信,并且便于管理网络资源等,其实每一个pod中,除了你创建的业务容器,都额外还有一个 pause容器
    • 同一个pod中的所有容器,共用pause容器的网络堆栈,即内部的所有容器,都使用这一个podIP,所以同一个pod中的所有容器,可以使用localhost相互访问
    • 因此,从这里来看,并非一个容器是一台独立的机器,更像是一个pod是一台独立的机器,pod内的所有容器,就像是运行在一台机器上的不同进程
    • 这是牺牲了部分隔离性,换来管理上的方便。如果你的多个容器,需要完全意义上的隔离性,那么部署成多个pod就可以了
  • 大家可以配合上面的图理解

1.16.kubernetes的5个数据结构GV、GR、GVR、GK、GVK

这些概念都与 Kubernetes API 相关,以下是它们的区别和一些例子:

  1. GroupVersionResource

GroupVersionResource 是 Kubernetes API 中定义 REST 路径的结构体。它由三个字段组成:Group、Version 和 Resource。其中,Group 是 API 组的名称,Version 是 API 版本的字符串,Resource 是 API 资源的名称。例如,v1 中的 Deployment 资源的 GroupVersionResource 为 apps/v1/deployments。

  1. GroupVersionKind

GroupVersionKind 是 Kubernetes API 中定义对象类型的结构体。它由三个字段组成:Group、Version 和 Kind。其中,Group 和 Version 的含义与 GroupVersionResource 相同,Kind 是对象类型的名称。例如,Deployment 对象的 GroupVersionKind 为 apps/v1/Deployment。

  1. GroupVersion

GroupVersion 是 Kubernetes API 中定义 API 版本的结构体。它由两个字段组成:Group 和 Version。其中,Group 指定了 API 组的名称,Version 指定了 API 版本的字符串。例如,apps/v1 表示 apps API 组的 v1 版本。

  1. GroupResource

GroupResource 是 Kubernetes API 中定义 REST 路径的结构体。它由两个字段组成:Group 和 Resource。其中,Group 是 API 组的名称,Resource 是 API 资源的名称。例如,apps 的 Deployment 资源的 GroupResource 为 apps/deployments。

  1. GroupKind

GroupKind 是 Kubernetes API 中定义对象类型的结构体。它由两个字段组成:Group 和 Kind。其中,Group 指定了 API 组的名称,Kind 是对象类型的名称。例如,apps 的 Deployment 对象的 GroupKind 为 apps/Deployment。

总的来说,GroupVersionResource 和 GroupResource 主要用于定义 RESTful API 的路径,GroupVersionKind 和 GroupKind 则主要用于定义 Kubernetes 对象的类型。

1.17.kubernetes日志库klog.Info()和klog.V(4).Info()区别

  • klog是Kubernetes项目中使用的日志记录库,它提供了一种灵活、高性能的日志记录解决方案。
  • 其中,klog.V() 是用于指定输出信息的详细程度。
    • V()共有0-9十种取值,详细程度随数字增大而递增
    • klog.Info() 默认的 V=0
  • 我们常用的 V 取值 4,代表debug级别的详细程度
    • klog.V(4).Info()
  • V 所有取值含义如下:

1.18.kubernetes创建CRD报错:invalid: metadata.annotations[api-approved.kubernetes.io]

  • 在kubernetes集群中创建CRD时,可能会报错:
    The CustomResourceDefinition "applications.appcontroller.k8s.io" is invalid: metadata.annotations[api-approved.kubernetes.io]: Required value: protected groups must have approval annotation "api-approved.kubernetes.io", see https://github.com/kubernetes/enhancements/pull/1111
    
  • 解决方法:
    • 这是kubernetes的保护机制,防止外部随意创建crd,破坏环境
    • 报错中已经给了提示,查看github:https://github.com/kubernetes/enhancements/pull/1111
    • 只需要在crd的定义文件中,添加一条 annotation,然后再执行 kubectl apply -f 命令就可以了
    metadata:
      annotations:
        api-approved.kubernetes.io: "https://github.com/kubernetes/kubernetes/pull/78458"
    

2.Kubernetes进阶内容【TODO】

这部分。是在学习过程中发现的一些扩展点,可以深入学习,或者作为一个专门的方向深入研究

2.1.ReadinessProbe的扩展:Readiness Gate

2.2.开发并使用自定义调度器完成pod调度

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

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

相关推荐

  1. 知识积累系列(三)golang框架持续更新

    2024-02-04 23:14:02       65 阅读
  2. 知识积累

    2024-02-04 23:14:02       55 阅读
  3. 持续积累分享金融知识

    2024-02-04 23:14:02       45 阅读
  4. Linux中一些知识积累持续补充)

    2024-02-04 23:14:02       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-04 23:14:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-04 23:14:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-04 23:14:02       82 阅读
  4. Python语言-面向对象

    2024-02-04 23:14:02       91 阅读

热门阅读

  1. PySparNN如何使用?

    2024-02-04 23:14:02       50 阅读
  2. 网络原理TCP/IP(4)

    2024-02-04 23:14:02       48 阅读
  3. Docker 第八章 : Docker 容器端口映射

    2024-02-04 23:14:02       51 阅读
  4. k8s网络详解(一)

    2024-02-04 23:14:02       37 阅读
  5. SQL语句创建数据库

    2024-02-04 23:14:02       54 阅读
  6. 开源软件的影响力

    2024-02-04 23:14:02       54 阅读
  7. UVA-213

    2024-02-04 23:14:02       55 阅读
  8. QCoro: Qt C++ 20 协程库介绍

    2024-02-04 23:14:02       52 阅读
  9. element-ui上传图片组件封装

    2024-02-04 23:14:02       40 阅读
  10. 【如何快速上手Vue.js框架——详细介绍】

    2024-02-04 23:14:02       48 阅读
  11. 【从零开始学设计模式】第三章_工厂模式

    2024-02-04 23:14:02       48 阅读
  12. Spring- FactoryBean接口中的getObject()方法

    2024-02-04 23:14:02       56 阅读