<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Kubernetes Develop on Cylon&#39;s Collection</title>
    <link>https://www.161616.top/tags/kubernetes-develop/</link>
    <description>Recent content in Kubernetes Develop on Cylon&#39;s Collection</description>
    <generator>Hugo -- 0.125.7</generator>
    <language>zh</language>
    <lastBuildDate>Mon, 20 Jan 2025 23:00:36 +0800</lastBuildDate>
    <atom:link href="https://www.161616.top/tags/kubernetes-develop/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>深入理解Kubernetes - 基于OOMKill的QoS的设计</title>
      <link>https://www.161616.top/ch30-oomkill/</link>
      <pubDate>Tue, 30 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch30-oomkill/</guid>
      <description>Overview 阅读完本文，您当了解
Linux oom kill Kubernetes oom 算法 Kubernetes QoS 本文只是个人理解，如果有大佬觉得不是这样的可以留言一起讨论，参考源码版本为 1.18.20，与高版本相差不大
什么是OOM Kill 当你的Linux机器内存不足时，内核会调用Out of Memory (OOM) killer来释放一些内存。这经常在运行许多内存密集型进程的服务器上遇到。
OOM Killer是如何选择要杀死的进程的？ Linux内核为每个运行的进程分配一个分数，称为 oom_score，==显示在内存紧张时终止该进程的可能性有多大==。该 Score 与进程使用的内存量成比例。 Score 是进程使用内存的百分比乘以10。因此，最大分数是 $100% \times 10 = 1000$。此外，如果一个进程以特权用户身份运行，那么与普通用户进程相比，它的 oom_score 会稍低。
在主发行版内核会将 /proc/sys/vm/overcommit_memory 的默认值设置为零，这意味着进程可以请求比系统中当前可用的内存更多的内存。这是基于以下启发式完成的：分配的内存不会立即使用，并且进程在其生命周期内也不会使用它们分配的所有内存。如果没有过度使用，系统将无法充分利用其内存，从而浪费一些内存。过量使用内存允许系统以更有效的方式使用内存，但存在 OOM 情况的风险。占用内存的程序会耗尽系统内存，使整个系统陷入瘫痪。当内存太低时，这可能会导致这样的情况：即使是单个页面也无法分配给用户进程，从而允许管理员终止适当的任务，或者内核执行重要操作，例如释放内存。在这种情况下，OOM Killer 就会介入，并将该进程识别为牺牲品，以保证系统其余部分的利益。
用户和系统管理员经常询问控制 OOM Killer 行为的方法。为了方便控制，引入了 /proc/&amp;lt;pid&amp;gt;/oom_adj 来防止系统中的重要进程被杀死，并定义进程被杀死的顺序。 oom_adj 的可能值范围为 -17 到 +15。Score 越高，相关进程就越有可能被 OOM-killer Kill。如果 oom_adj 设置为 -17，则 OOM Killer 不会 Kill 该进程。
oom_score 分数为 1 ~ 1000，值越低，程序被杀死的机会就越小。
oom_score 0 表示该进程未使用任何可用内存。 oom_score 1000 表示该进程正在使用 100% 的可用内存，大于1000，也取1000。 谁是糟糕的进程？ 在内存不足的情况下选择要被终止的进程是基于其 oom_score 。糟糕进程 Score 被记录在 /proc/&amp;lt;pid&amp;gt;/oom_score 文件中。该值是基于系统损失的最小工作量、回收的大量内存、不终止任何消耗大量内存的无辜进程以及终止的进程数量最小化（如果可能限制在一个）等因素来确定的。糟糕程度得分是使用进程的原始内存大小、其 CPU 时间（utime + stime）、运行时间（uptime - 启动时间）以及其 oom_adj 值计算的。进程使用的内存越多，得分越高。进程在系统中存在的时间越长，得分越小。</description>
    </item>
    <item>
      <title>client-go - Pod使用in-cluster方式访问集群</title>
      <link>https://www.161616.top/ch07-in-cluster-pod/</link>
      <pubDate>Wed, 15 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch07-in-cluster-pod/</guid>
      <description>在我们基于 Kubernetes 编写云原生 GoLang 代码时，通常在本地调试时，使用 kubeconfig 文件，以构建基于 clientSet 的客户端。而在将代码作为容器部署到集群时，则会使用集群 (in-cluster) 内的配置。
clientcmd 模块用于通过传递本地 kubeconfig 文件构建 clientSet。因此，在容器内使用相同模块构建 clientSet 将需要维护容器进程可访问的 kubeconfig 文件，并设置具有访问 Kubernetes 资源权限的 serviceaccount token。
下面是一个基于 kubeconfig 访问集群的代码模式
go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var ( k8sconfig *string //使用kubeconfig配置文件进行集群权限认证 restConfig *rest.Config err error ) if home := homedir.HomeDir(); home != &amp;#34;&amp;#34; { k8sconfig = flag.String(&amp;#34;kubeconfig&amp;#34;, fmt.Sprintf(&amp;#34;./admin.conf&amp;#34;), &amp;#34;kubernetes auth config&amp;#34;) } flag.</description>
    </item>
    <item>
      <title>Kubernetes集群中的IP伪装 - ip-masq-agent</title>
      <link>https://www.161616.top/ch24-ip-masq/</link>
      <pubDate>Sat, 28 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch24-ip-masq/</guid>
      <description>“IP 伪装” 通常应用于云环境中，例如 GKE, AWS, CCE 等云厂商都有使用 “IP伪装” 技术，本文将围绕 “IP伪装” 技术本身，以及这项技术在 Kubernetes 集群中的实现应用 ip-masq-agent 的源码分析，以及 ”IP伪装“ 能为 Kubernetes 带来什么作用，这三个方向阐述。
什么是IP伪装？ IP 伪装 (IP Masquerade) 是 Linux 中的一个网络功能，一对多 (1 to Many) 的网络地址转换 (NAT) 的功能 。
IP 伪装允许一组计算机通过 “伪装” 网关无形地访问互联网。对于互联网上的其他计算机，出站流量将看起来来自于 IP MASQ 服务器本身。互联网上任何希望发回数据包（作为答复）的主机必须将该数据包发送到网关 （IP MASQ 服务器本身）。记住，网关（IP MASQ 服务器本身）是互联网上唯一可见的主机。网关重写目标地址，用被伪装的机器的 IP 地址替换自己的地址，并将该数据包转发到本地网络进行传递。
除了增加的功能之外，IP Masquerade 为创建一个高度安全的网络环境提供了基础。通过良好构建的防火墙，突破经过良好配置的伪装系统和内部局域网的安全性应该会相当困难。
IP Masquerade 从 Linux 1.3.x 开始支持，目前基本所有 Linux 发行版都带有 IP 伪装的功能
什么情况下不需要IP伪装 已经连接到互联网的独立主机 为其他主机分配了多个公共地址 IP伪装在Kubernetes集群中的应用 IP 伪装通常应用在大规模 Kubernetes 集群中，主要用于解决 “地址冲突” 的问题，例如在 GCP 中，通常是一种 IP 可路由的网络模型，例如分配给 Pod service 的 ClusterIP 只能在 Kubernetes 集群内部可用，而分配 IP CIDR 又是一种不可控的情况，假设，我们为 k8s 分配的 IP CIDR 段如下表所示：</description>
    </item>
    <item>
      <title>kube-proxy参数ClusterCIDR做什么</title>
      <link>https://www.161616.top/ch26-kube-proxy-clustercidr/</link>
      <pubDate>Fri, 15 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch26-kube-proxy-clustercidr/</guid>
      <description>我们可以看到，kube-proxy 有一个 &amp;ndash;cluster-cidr 的参数，我们就来解开这个参数究竟有没有用
bash 1 2 $ kube-proxy -h|grep cidr --cluster-cidr string The CIDR range of pods in the cluster. When configured, traffic sent to a Service cluster IP from outside this range will be masqueraded and traffic sent from pods to an external LoadBalancer IP will be directed to the respective cluster IP instead 可以看到，参数说明是说，如果配置，那么从外部发往 Service Cluster IP 的流量将被伪装，从 Pod 发往外部 LB 将被直接发往对应的 cluster IP。但实际上做了什么并不知道，那么就从源码解决这个问题。
首先我们知道，参数是作为 kube-proxy server 的参数，位于 cmd/kube-proxy 下，而对应的逻辑则位于 pkg/kube-proxy 下，参数很明显，就是 clusterCIDR，那么我们就寻找这个参数的调用即可。</description>
    </item>
    <item>
      <title>深入理解kubelet - VolumeManager源码解析</title>
      <link>https://www.161616.top/ch29-volumemanager/</link>
      <pubDate>Sun, 20 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch29-volumemanager/</guid>
      <description>Overview 阅读完本文，您当了解
Kubernetes 卷 CephFS 在 kubernetes 中的挂载 Kubelet VolumeManager 本文只是个人理解，如果有大佬觉得不是这样的可以留言一起讨论，参考源码版本为 1.18.20，与高版本相差不大
VolumeManager VolumeManager VM 是在 kubelet 启动时被初始化的一个异步进程，主要是维护 “Pod&amp;quot; 卷的两个状态，”desiredStateOfWorld“ 和 ”actualStateOfWorld“； 这两个状态用于将节点上的卷 “协调” 到所需的状态。
VM 实际上包含三个 “异步进程” (goroutine)，其中有一个 reconciler 就是用于协调与挂载的，下面就来阐述 VM 的挂载过程。
VM中的重要组件 actualStateOfWorld mountedPod desiredStateOfWorld VolumeToMount podToMount VM的组成 VM 的代码位于，由图可以看出，主要包含三个重要部分：
reconciler：协调器 populator：填充器 cache：包含 ”desiredStateOfWorld“ 和 ”actualStateOfWorld“ 图：VM的目录组成 在代码结构上，volumeManager 如下所示
go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // volumeManager implements the VolumeManager interface type volumeManager struct { // DesiredStateOfWorldPopulator 用来与 API 服务器通信以获取 PV 和 PVC 对象的 API 客户端 kubeClient clientset.</description>
    </item>
    <item>
      <title>kube-proxy如何保证规则的一致性</title>
      <link>https://www.161616.top/ch24-kube-proxy-performance/</link>
      <pubDate>Thu, 09 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch24-kube-proxy-performance/</guid>
      <description>本文是关于Kubernetes service解析的第5章 深入理解Kubernetes service - 你真的理解service吗? 深入理解Kubernetes service - EndpointSlices做了什么？ 深入理解Kubernetes service - kube-proxy架构分析 深入理解Kubernetes service - 如何扩展现有的kube-proxy架构 kube-proxy如何保证规则的一致性 所有关于Kubernetes service 部分代码上传至仓库 github.com/cylonchau/kube-haproxy
前景 这里谈 kube-proxy 如何保证规则的一致性以及提升 kube-proxy 性能点的地方，这也是 kubernetes 使用稳定性的一部分。
kube-proxy 如何做到的CRUD kube-proxy 实际上与其他内置 controller 架构是相同的，实际上也属于一个 controller ，但它属于一个 service, endpoints 的可读可写的控制器，node的读控制器。对于CRUD方面，kube-proxy，在设计上分为 增/改 两方面。正如下面代码所示 pkg/proxy/ipvs/proxier.go
go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func (proxier *Proxier) OnServiceAdd(service *v1.Service) { proxier.OnServiceUpdate(nil, service) } // OnServiceUpdate is called whenever modification of an existing service object is observed.</description>
    </item>
    <item>
      <title>深入理解Kubernetes service - EndpointSlices做了什么？</title>
      <link>https://www.161616.top/ch18-endpointslices/</link>
      <pubDate>Sat, 25 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch18-endpointslices/</guid>
      <description>本文是关于Kubernetes service解析的第2章 深入理解Kubernetes service - 你真的理解service吗? 深入理解Kubernetes service - EndpointSlices做了什么？ 深入理解Kubernetes service - kube-proxy架构分析 深入理解Kubernetes service - 如何扩展现有的kube-proxy架构 kube-proxy如何保证规则的一致性 所有关于Kubernetes service 部分代码上传至仓库 github.com/cylonchau/kube-haproxy
Endpoint Endpoints 就是 service 中后端的server，通常来说 endpoint 与 service是关联的，例如下面的一个endpoints 资源。
yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: v1 kind: Endpoints metadata: name: nginx subsets: - addresses: - ip: 172.17.0.2 - ip: 172.17.0.3 ports: - port: 80 name: &amp;#34;111&amp;#34; # 多个端口需要用name - port: 88 name: &amp;#34;222&amp;#34; 而 Endpoints 资源是由控制平面的 Endpoints controller 进行管理的，主要用于将外部server引入至集群内时使用的，例如Kube-apiserver 在集群外的地址，以及external service所需要创建的。</description>
    </item>
    <item>
      <title>深入理解Kubernetes service - 如何扩展现有的kube-proxy架构？</title>
      <link>https://www.161616.top/ch23-extend-kube-proxy/</link>
      <pubDate>Sun, 12 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch23-extend-kube-proxy/</guid>
      <description>本文是关于Kubernetes service解析的第4章 深入理解Kubernetes service - 你真的理解service吗? 深入理解Kubernetes service - EndpointSlices做了什么？ 深入理解Kubernetes service - kube-proxy架构分析 深入理解Kubernetes service - 如何扩展现有的kube-proxy架构 kube-proxy如何保证规则的一致性 所有关于Kubernetes service 部分代码上传至仓库 github.com/cylonchau/kube-haproxy
Overview 在前两部分中，学习了一些 service,于kube-proxy在设计架构，但存在扩展问题将引入了一些问题：
为什么需要了解这部分内容呢？ 与传统架构有什么区别呢？ 于eBPF 的 cilium又有什么区别呢？ 既然eBPF可以做到，那为什么要这部分内容呢？ 接下来的内容将围绕这四个问题展开来讲，而不是代码的讲解，代码可以看置顶
IPVS与iptables在kubernetes中应用时的问题 对于在使用了kubernetes用户以及了解 kube-proxy 架构后，知道当集群规模过大时，service必将增多，而一个service未必是一条iptables/ipvs规则，对于kubernetes这种分布式架构来说，集群规模越大，集群状态就越不可控，尤其时kube-proxy。
为什么单指kube-proxy呢？想想可以知道，pod的故障 或 node 的故障对于kubernetes集群来说却不是致命的，因为 这些资源集群中存在 避免方案，例如Pod的驱逐。而kube-proxy或iptables/IPVS问题将导致服务的不可控 『抖动』例如规则生成的快慢和Pod就绪的快慢不一致，部分节点不存在 service 此时服务必然抖动。
再例如 iptables/IPVS 排查的难度对于普通运维工程师或开发工程师的技术水平有很高的要求，网上随处可见分析该类问题的帖子：
kube-proxy源码分析与问题定位
案例分析：怎么解决海量IPVS规则带来的网络延时抖动问题？
ipvs 连接复用引发的系列问题
Investigating Causes of Jitter in Container Networking
ContainerNative network LoadBalancer IPVS jitter
对于上述问题，相信遇到了很难定位处理，虽然现在已fixed，并有eBPF技术的加入减少了此类问题的发生，但是eBPF实际同理于IPVS 都是需要对Linux内核有一定了解后才可以，这也就是为什么需要了解这部分
如果需要自定义proxier为什么会解决这个问题 这里就是放大到kubernetes意外的传统架构中，当直接部署于Linux系统上使用nginx等传统LB时就很少有人提到这些问题了，而这些问题存在一个关键字「Container」；而引发这个问题的则是 service。去除 service 的功能，传统架构于Kubernetes架构部署的应用则是相同的，只是区分了名称空间。</description>
    </item>
    <item>
      <title>深入理解Kubernetes service - kube-proxy架构分析</title>
      <link>https://www.161616.top/ch19-kube-proxy-code/</link>
      <pubDate>Mon, 06 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch19-kube-proxy-code/</guid>
      <description>本文是关于Kubernetes service解析的第3章 深入理解Kubernetes service - 你真的理解service吗? 深入理解Kubernetes service - EndpointSlices做了什么？ 深入理解Kubernetes service - kube-proxy架构分析 深入理解Kubernetes service - 如何扩展现有的kube-proxy架构 kube-proxy如何保证规则的一致性 所有关于Kubernetes service 部分代码上传至仓库 github.com/cylonchau/kube-haproxy
前提概述 kubernetes集群中运行在每个Worker节点上的组件 kube-proxy，本文讲解的是如何快速的了解 kube-proxy 的软件架构，而不是流程的分析，专注于 proxy 层面的设计讲解，而不会贴大量的代码
kube-proxy软件设计 kube-proxy 在设计上分为三个模块 server 于 proxy：
server: 是一个常驻进程用于处理service的事件 proxy: 是 kube-proxy 的工作核心，实际上的角色是一个 service controller，通过监听 node, service, endpoint 而生成规则 proxier: 是实现service的组件，例如iptables, ipvs&amp;hellip;. 如何快速读懂kube-proxy源码 要想快速读懂 kube-proxy 源码就需要对 kube-proxy 设计有深刻的了解，例如需要看 kube-proxy 的实现，我们就可以看 proxy的部分，下列是 proxy 部分的目录结构
bash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $ tree -L 1 .</description>
    </item>
    <item>
      <title>深入理解Kubernetes service - 你真的理解service吗？</title>
      <link>https://www.161616.top/ch17-service-controller/</link>
      <pubDate>Mon, 06 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch17-service-controller/</guid>
      <description>本文是关于Kubernetes service解析的第1章 深入理解Kubernetes service - 你真的理解service吗? 深入理解Kubernetes service - EndpointSlices做了什么？ 深入理解Kubernetes service - kube-proxy架构分析 深入理解Kubernetes service - 如何扩展现有的kube-proxy架构 kube-proxy如何保证规则的一致性 所有关于Kubernetes service 部分代码上传至仓库 github.com/cylonchau/kube-haproxy
前景 对于了解kubernetes架构时，已知的是 service 是kubernetes在设计时为了避免Pod在频繁创建和销毁时IP变更问题，从而给集群内服务（一组Pod）提供访问的一个入口。而Pod在这里的角色是 『后端』( backend ) ，而 service 的角色是 『前端』( frontend )。本文将阐述service的生命周期
为什么需要了解这部分内容呢 对于 without kube-proxy来说，这部分是最重要的部分，因为service的生成不是kube-proxy来完成的，而这部分也就是service ip定义的核心。
控制器 service的资源创建很奇妙，继不属于 controller-manager 组件，也不属于 kube-proxy 组件，而是存在于 apiserver 中的一个被成为控制器的组件；而这个控制器又区别于准入控制器。更准确来说，准入控制器是位于kubeapiserver中的组件，而 控制器 则是存在于单独的一个包，这里包含了很多kubernetes集群的公共组件的功能，其中就有service。这也就是在操作kubernetes时 当 controller-manager 于 kube-proxy 未工作时，也可以准确的为service分配IP。
首先在构建出apiserver时，也就是代码 cmd/kube-apiserver/app/server.go
go 1 2 3 4 serviceIPRange, apiServerServiceIP, err := master.ServiceIPRange(s.PrimaryServiceClusterIPRange) if err !</description>
    </item>
    <item>
      <title>深入理解Kubernetes 4A - Audit源码解析</title>
      <link>https://www.161616.top/ch34-auditing/</link>
      <pubDate>Thu, 24 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch34-auditing/</guid>
      <description>本文是关于Kubernetes 4A解析的第4章 深入理解Kubernetes 4A - Authentication源码解析 深入理解Kubernetes 4A - Authorization源码解析 深入理解Kubernetes 4A - Admission Control源码解析 深入理解Kubernetes 4A - Audit源码解析 TLS Everywhere - 解密kubernetes集群的安全认证 所有关于Kubernetes 4A部分代码上传至仓库 github.com/cylonchau/hello-k8s-4A
Overview 审计是信息系统中非常重要的一部分，Kubernetes 1.11中也增加了审计 (Auditing) 功能，通过审计功能获得 deployment, ns,等资源操作的事件。
objective：
从设计角度了解Auditing在kubernets中是如何实现的 了解kubernetes auditing webhook 完成实验，通过webhook来收集审计日志 如有错别字或理解错误地方请多多担待，代码是以1.24进行整理，实验是以1.19环境进行，差别不大。
Kubernetes Auditing 根据Kubernetes官方描述审计在kubernetes中是有控制平面 kube-apiserver 中产生的一个事件，记录了集群中所操作的资源，审计围绕下列几个维度来记录事件的：
发生了什么 发生的事件 谁触发的 发生动作的对象 在哪里检查到动作的 从哪触发的 处理行为是什么 审计生命周期开始于组件 kube-apiserver 准入控制阶段，在每个阶段内都会产生审计事件并经过预处理后写入后端，目前后端包含webhook与日志文件。
审计日志功能增加了 kube-apiserver 的内存消耗，因为会为每个请求存储了审计所需的上下文。内存的消耗取决于审计日志配置 [1]。
审计事件设计 审计的schema不同于资源API的设计，没有 metav1.ObjectMeta 属性，Event是一个事件的结构体，Policy是事件配置，属于kubernetes资源，在代码 k8s.io/apiserver/pkg/apis/audit/types.go 可以看到
go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 type Event struct { metav1.</description>
    </item>
    <item>
      <title>深入理解Kubernetes 4A - Authorization源码解析</title>
      <link>https://www.161616.top/ch32-authorization/</link>
      <pubDate>Thu, 24 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch32-authorization/</guid>
      <description>本文是关于Kubernetes 4A解析的第2章 深入理解Kubernetes 4A - Authentication源码解析 深入理解Kubernetes 4A - Authorization源码解析 深入理解Kubernetes 4A - Admission Control源码解析 深入理解Kubernetes 4A - Audit源码解析 TLS Everywhere - 解密kubernetes集群的安全认证 所有关于Kubernetes 4A部分代码上传至仓库 github.com/cylonchau/hello-k8s-4A Overview 在 Kubernetes 中，当一个访问请求通过了登录阶段（Authentication），必须还需要请求拥有该对象的访问权限，而授权部分也是Kubernetes API 访问控制中的第二个部分 Authorization .
Authorization 在 Kubernetes中是以评估发起请求的用户，根据其身份特性评估这次请求是被 ”拒绝“ 还是 “允许”，同访问控制三部曲中其他两个插件 (Authentication, Adminssion Control) 一样，Authorization 也可以同时配置多个，当收到用户的请求时，会依次检查这个阶段配置的所有模块，如果任何一个模块对该请求授予权限（拒绝或允许），那么该阶段会直接返回，当所有模块都没有该用户所属的权限时，默认是拒绝，在Kubernetes中，被该插件拒绝的用户显示为HTTP 403。
如有错别字或理解错误地方请多多担待，代码是以1.24进行整理，实验是以1.19环境进行，差别不大
objective：
了解kubernetes Authorization机制 了解授权系统的设计 完成实验，使用 OPA 作为 Kubernetes 外部用户，权限认证模型 RBAC 的替代品 Kubernetes是如何对用户授权的 kubernetes对用户授权需要遵守的shema必须拥有下列属性，代码位于pkg\apis\authorization\types.go
go 1 2 3 4 5 6 7 8 9 type SubjectAccessReview struct { // API必须实现的部分 metav1.</description>
    </item>
    <item>
      <title>深入理解Kubernetes 4A - Authentication源码解析</title>
      <link>https://www.161616.top/ch31-authentication/</link>
      <pubDate>Wed, 16 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch31-authentication/</guid>
      <description>本文是关于Kubernetes 4A解析的第1章 深入理解Kubernetes 4A - Authentication源码解析 深入理解Kubernetes 4A - Authorization源码解析 深入理解Kubernetes 4A - Admission Control源码解析 深入理解Kubernetes 4A - Audit源码解析 TLS Everywhere - 解密kubernetes集群的安全认证 所有关于Kubernetes 4A部分代码上传至仓库 github.com/cylonchau/hello-k8s-4A
Overview 本章主要简单阐述kubernetes 认证相关原理，最后以实验来阐述kubernetes用户系统的思路
objective：
了解kubernetes 各种认证机制的原理 了解kubernetes 用户的概念 了解kubernetes authentication webhook 完成实验，如何将其他用户系统接入到kubernetes中的一个思路 如有错别字或理解错误地方请多多担待，代码是以1.24进行整理，实验是以1.19环境进行，差别不大。
Kubernetes 认证 在Kubernetes apiserver对于认证部分所描述的，对于所有用户访问Kubernetes API（通过任何客户端，客户端库，kubectl 等）时都会经历 验证 (Authentication) , 授权 (Authorization), 和准入控制 (Admission control) 三个阶段来完成对 “用户” 进行授权，整个流程正如下图所示
图：Kubernetes API 请求的请求处理步骤图 Source：https://www.armosec.io/blog/kubernetes-admission-controller/
其中在大多数教程中，在对这三个阶段所做的工作大致上为：
Authentication 阶段所指用于确认请求访问Kubernetes API 用户是否为合法用户，拒绝为401
Authorization 阶段所指的将是这个用户是否有对操作的资源的权限，拒绝为403
Admission control 阶段所指控制对请求资源进行控制，通俗来说，就是一票否决权，即使前两个步骤完成</description>
    </item>
    <item>
      <title>基于Prometheus的Kubernetes网络调度器</title>
      <link>https://www.161616.top/ch22-custom-scheduler/</link>
      <pubDate>Mon, 08 Aug 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch22-custom-scheduler/</guid>
      <description>Overview 本文将深入讲解 如何扩展 Kubernetes scheduler 中各个扩展点如何使用，与扩展scheduler的原理，这些是作为扩展 scheduler 的所需的知识点。最后会完成一个实验，基于网络流量的调度器。
kubernetes调度配置 kubernetes集群中允许运行多个不同的 scheduler ，也可以为Pod指定不同的调度器进行调度。在一般的Kubernetes调度教程中并没有提到这点，这也就是说，对于亲和性，污点等策略实际上并没有完全的使用kubernetes调度功能，在之前的文章中提到的一些调度插件，如基于端口占用的调度 NodePorts 等策略一般情况下是没有使用到的，本章节就是对这部分内容进行讲解，这也是作为扩展调度器的一个基础。
Scheduler Configuration [1] kube-scheduler 提供了配置文件的资源，作为给 kube-scheduler 的配置文件，启动时通过 --onfig= 来指定文件。目前各个kubernetes版本中使用的 KubeSchedulerConfiguration 为，
1.21 之前版本使用 v1beta1 1.22 版本使用 v1beta2 ，但保留了 v1beta1 1.23, 1.24, 1.25 版本使用 v1beta3 ，但保留了 v1beta2，删除了 v1beta1 下面是一个简单的 kubeSchedulerConfiguration 示例，其中 kubeconfig 与启动参数 --kubeconfig 是相同的功效。而 kubeSchedulerConfiguration 与其他组件的配置文件类似，如 kubeletConfiguration 都是作为服务启动的配置文件。
yaml 1 2 3 4 apiVersion: kubescheduler.config.k8s.io/v1beta1 kind: KubeSchedulerConfiguration clientConnection: kubeconfig: /etc/srv/kubernetes/kube-scheduler/kubeconfig Notes: --kubeconfig 与 --config 是不可以同时指定的，指定了 --config 则其他参数自然失效 [2]</description>
    </item>
    <item>
      <title>如何理解kubernetes调度框架与插件？</title>
      <link>https://www.161616.top/ch21-scheduling-algorithm/</link>
      <pubDate>Wed, 27 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch21-scheduling-algorithm/</guid>
      <description>调度框架 [1] 本文基于 kubernetes 1.24 进行分析
调度框架（Scheduling Framework）是Kubernetes 的调度器 kube-scheduler 设计的的可插拔架构，将插件（调度算法）嵌入到调度上下文的每个扩展点中，并编译为 kube-scheduler
在 kube-scheduler 1.22 之后，在 pkg/scheduler/framework/interface.go 中定义了一个 Plugin 的 interface，这个 interface 作为了所有插件的父级。而每个未调度的 Pod，Kubernetes 调度器会根据一组规则尝试在集群中寻找一个节点。
go 1 2 3 type Plugin interface { Name() string } 下面会对每个算法是如何实现的进行分析
在初始化 scheduler 时，会创建一个 profile，profile是关于 scheduler 调度配置相关的定义
go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 func New(client clientset.Interface, .</description>
    </item>
    <item>
      <title>kube-scheduler的调度上下文</title>
      <link>https://www.161616.top/ch20-schedule-workflow/</link>
      <pubDate>Thu, 21 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch20-schedule-workflow/</guid>
      <description>Scheduler Scheduler 是整个 kube-scheduler 的一个 structure，提供了 kube-scheduler 运行所需的组件。
go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 type Scheduler struct { // Cache是一个抽象，会缓存pod的信息，作为scheduler进行查找，操作是基于Pod进行增加 Cache internalcache.Cache // Extenders 算是调度框架中提供的调度插件，会影响kubernetes中的调度策略 Extenders []framework.Extender // NextPod 作为一个函数提供，会阻塞获取下一个ke&amp;#39;diao&amp;#39;du NextPod func() *framework.QueuedPodInfo // Error is called if there is an error. It is passed the pod in // question, and the error Error func(*framework.</description>
    </item>
    <item>
      <title>kubernetes的决策组件 - kube-scheduler原理分析</title>
      <link>https://www.161616.top/ch16-scheduler/</link>
      <pubDate>Mon, 18 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch16-scheduler/</guid>
      <description>Overview [1] kubernetes集群中的调度程序 kube-scheduler 会 watch 未分配节点的新创建的Pod，并未该Pod找到可运行的最佳（特定）节点。那么这些动作或者说这些原理是怎么实现的呢，让我们往下剖析下。
对于新创建的 pod 或其他未调度的 pod来讲，kube-scheduler 选择一个最佳节点供它们运行。但是，Pod 中的每个容器对资源的要求都不同，每个 Pod 也有不同的要求。因此，需要根据具体的调度要求对现有节点进行过滤。
在Kubernetes集群中，满足 Pod 调度要求的节点称为可行节点 （ feasible nodes FN） 。如果没有合适的节点，则 pod 将保持未调度状态，直到调度程序能够放置它。也就是说，当我们创建Pod时，如果长期处于 Pending 状态，这个时候应该看你的集群调度器是否因为某些问题没有合适的节点了
调度器为 Pod 找到 FN 后，然后运行一组函数对 FN 进行评分，并在 FN 中找到得分最高的节点来运行 Pod。
调度策略在决策时需要考虑的因素包括个人和集体资源需求、硬件/软件/策略约束 （constraints）、亲和性 (affinity) 和反亲和性（ anti-affinity ）规范、数据局部性、工作负载间干扰等。
如何为pod选择节点？ kube-scheduler 为pod选择节点会分位两部：
过滤 (Filtering) 打分 (Scoring) 过滤也被称为预选 （Predicates），该步骤会找到可调度的节点集，然后通过是否满足特定资源的请求，例如通过 PodFitsResources 过滤器检查候选节点是否有足够的资源来满足 Pod 资源的请求。这个步骤完成后会得到一个包含合适的节点的列表（通常为多个），如果列表为空，则Pod不可调度。
打分也被称为优选（Priorities），在该步骤中，会对上一个步骤的输出进行打分，Scheduer 通过打分的规则为每个通过 Filtering 步骤的节点计算出一个分数。
完成上述两个步骤之后，kube-scheduler 会将Pod分配给分数最高的 Node，如果存在多个相同分数的节点，会随机选择一个。
kubernetes的调度策略 Kubernetes 1.21之前版本可以在代码 kubernetes\pkg\scheduler\algorithmprovider\registry.go 中看到对应的注册模式，在1.22 scheduler 更换了其路径，对于registry文件更换到了kubernetes\pkg\scheduler\framework\plugins\registry.go ；对于kubernetes官方说法为，调度策略是用于“预选” (Predicates )或 过滤（filtering ） 和 用于 优选（Priorities）或 评分 (scoring)的</description>
    </item>
    <item>
      <title>深入理解Kubernetes 4A - Admission Control源码解析</title>
      <link>https://www.161616.top/ch33-admission-webhook/</link>
      <pubDate>Mon, 11 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch33-admission-webhook/</guid>
      <description>本文是关于Kubernetes 4A解析的第3章 深入理解Kubernetes 4A - Authentication源码解析 深入理解Kubernetes 4A - Authorization源码解析 深入理解Kubernetes 4A - Admission Control源码解析 深入理解Kubernetes 4A - Audit源码解析 TLS Everywhere - 解密kubernetes集群的安全认证 所有关于Kubernetes 4A部分代码上传至仓库 github.com/cylonchau/hello-k8s-4A
如有错别字或理解错误地方请多多担待，代码是以1.24进行整理，实验是以1.19环境进行，差别不大
BACKGROUND admission controllers的特点：
可定制性：准入功能可针对不同的场景进行调整。 可预防性：审计则是为了检测问题，而准入控制器可以预防问题发生 可扩展性：在kubernetes自有的验证机制外，增加了另外的防线，弥补了RBAC仅能对资源提供安全保证。 下图，显示了用户操作资源的流程，可以看出 admission controllers 作用是在通过身份验证资源持久化之前起到拦截作用。在准入控制器的加入会使kubernetes增加了更高级的安全功能。
图：Kubernetes API 请求的请求处理步骤图 Source：https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/ 这里找到一个大佬博客画的图，通过两张图可以很清晰的了解到admission webhook流程，与官方给出的不一样的地方在于，这里清楚地定位了kubernetes admission webhook 处于准入控制中，RBAC之后，push 之前。
图：Kubernetes API 请求的请求处理步骤图（详细） Source：https://www.armosec.io/blog/kubernetes-admission-controller/ 两种控制器有什么区别？ 根据官方提供的说法是
Mutating controllers may modify related objects to the requests they admit; validating controllers may not
从结构图中也可以看出，validating 是在持久化之前，而 Mutating 是在结构验证前，根据这些特性我们可以使用 Mutating 修改这个资源对象内容（如增加验证的信息），在 validating 中验证是否合法。</description>
    </item>
    <item>
      <title>利用kubernetes中的leader选举机制自定义HA应用</title>
      <link>https://www.161616.top/ch28-leader-election-eg/</link>
      <pubDate>Wed, 29 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch28-leader-election-eg/</guid>
      <description>Backgroud 前一章中，对kubernetes的选举原理进行了深度剖析，下面就通过一个example来实现一个，利用kubernetes提供的选举机制完成的高可用应用。
对于此章需要提前对一些概念有所了解后才可以继续看下去
leader election mechanism RBCA Pod runtime mechanism Implementation 代码实现 如果仅仅是使用Kubernetes中的锁，实现的代码也只有几行而已。
go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 package main import ( &amp;#34;context&amp;#34; &amp;#34;flag&amp;#34; &amp;#34;fmt&amp;#34; &amp;#34;os&amp;#34; &amp;#34;os/signal&amp;#34; &amp;#34;syscall&amp;#34; &amp;#34;time&amp;#34; metav1 &amp;#34;k8s.</description>
    </item>
    <item>
      <title>源码分析Kubernetes HA机制 - leader election</title>
      <link>https://www.161616.top/ch27-leader-election/</link>
      <pubDate>Tue, 28 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch27-leader-election/</guid>
      <description>Overview 在 Kubernetes的 kube-controller-manager , kube-scheduler, 以及使用 Operator 的底层实现 controller-rumtime 都支持高可用系统中的leader选举，本文将以理解 controller-rumtime （底层的实现是 client-go） 中的leader选举以在kubernetes controller中是如何实现的。
Background 在运行 kube-controller-manager 时，是有一些参数提供给cm进行leader选举使用的，可以参考官方文档提供的 参数 来了解相关参数。
bash 1 2 3 4 5 6 7 --leader-elect Default: true --leader-elect-renew-deadline duration Default: 10s --leader-elect-resource-lock string Default: &amp;#34;leases&amp;#34; --leader-elect-resource-name string Default: &amp;#34;kube-controller-manager&amp;#34; --leader-elect-resource-namespace string Default: &amp;#34;kube-system&amp;#34; --leader-elect-retry-period duration Default: 2s ... 本身以为这些组件的选举动作时通过etcd进行的，但是后面对 controller-runtime 学习时，发现并没有配置其相关的etcd相关参数，这就引起了对选举机制的好奇。怀着这种好奇心搜索了下有关于 kubernetes的选举，发现官网是这么介绍的，下面是对官方的说明进行一个通俗总结。simple leader election with kubernetes
通过阅读文章得知，kubernetes API 提供了一中选举机制，只要运行在集群内的容器，都是可以实现选举功能的。
Kubernetes API通过提供了两个属性来完成选举动作的
ResourceVersions：每个API对象唯一一个ResourceVersion Annotations：每个API对象都可以对这些key进行注释 注：这种选举会增加APIServer的压力。也就对etcd会产生影响</description>
    </item>
    <item>
      <title>源码分析Kubernetes controller组件 - controller-runtime</title>
      <link>https://www.161616.top/ch15-controller-runtime/</link>
      <pubDate>Mon, 27 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch15-controller-runtime/</guid>
      <description>Overview controller-runtime 是 Kubernetes 社区提供可供快速搭建一套 实现了controller 功能的工具，无需自行实现Controller的功能了；在 Kubebuilder 与 Operator SDK 也是使用 controller-runtime 。本文将对 controller-runtime 的工作原理以及在不同场景下的使用方式进行简要的总结和介绍。
controller-runtime structure controller-runtime 主要组成是需要用户创建的 Manager 和 Reconciler 以及 Controller Runtime 自己启动的 Cache 和 Controller 。
Manager：是用户在初始化时创建的，用于启动 Controller Runtime 组件 Reconciler：是用户需要提供来处理自己的业务逻辑的组件（即在通过 code-generator 生成的api-like而实现的controller中的业务处理部分）。 Cache：一个缓存，用来建立 Informer 到 ApiServer 的连接来监听资源并将被监听的对象推送到queue中。 Controller： 一方面向 Informer 注册 eventHandler，另一方面从队列中获取数据。controller 将从队列中获取数据并执行用户自定义的 Reconciler 功能。 图：controller-runtime structure 图：controller-runtime flowchart 由图可知，Controller会向 Informer 注册一些列eventHandler；然后Cache启动Informer（informer属于cache包中），与ApiServer建立监听；当Informer检测到资源变化时，将对象加入queue，Controller 将元素取出并在用户端执行 Reconciler。
Controller引入 我们从 controller-rumtime项目的 example 进行引入看下，整个架构都是如何实现的。
可以看到 example 下的实际上实现了一个 reconciler 的结构体，实现了 Reconciler 抽象和 Client 结构体</description>
    </item>
    <item>
      <title>扩展Kubernetes API的另一种方式 - APIServer aggregation</title>
      <link>https://www.161616.top/ch04-apiserver-aggregation/</link>
      <pubDate>Wed, 22 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch04-apiserver-aggregation/</guid>
      <description>Overview What is Kubernetes aggregation Kubernetes apiserver aggregation AA 是Kubernetes提供的一种扩展API的方法，目前并没有GA
Difference between CRD and AA 众所周知，kubernetes扩展API的方法大概为三种：CRD、AA、手动扩展源码。根据CNCF分享中Min Kim说的AA更关注于实践，而用户无需了解底层的原理，这里使用过 kubebuilder， code-generator 的用户是很能体会到这点。官方也给出了CRD与AA的区别
API Access Control Authentication CR: All strategies supported. Configured by root apiserver. AA: Supporting all root apiserver&amp;rsquo;s authenticating strategies but it has to be done via authentication token review api except for authentication proxy which will cause an extra cost of network RTT. Authorization CR: All strategies supported. Configured by root apiserver.</description>
    </item>
    <item>
      <title>kubernetes代码生成器 - code-generator</title>
      <link>https://www.161616.top/ch14-code-generator/</link>
      <pubDate>Mon, 20 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch14-code-generator/</guid>
      <description>Overview Kubernetes中提供了多种自定义控制器的方式：
code-generator kubebuilder Operator Controller 作为CRD的核心，这里将解释如何使用 code-generator 来创建自定义的控制器，作为文章的案例，将完成一个 Firewalld Port 规则的控制器作为描述，通过 Kubernetes 规则来生成对应节点上的 iptables规则。
Prerequisites CRD yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: ports.firewalld.fedoraproject.org spec: group: firewalld.fedoraproject.org scope: Namespaced names: plural: ports singular: port kind: PortRule shortNames: - fp versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: name: type: string port: type: integer host: type: string isPermanent: type: boolean code-generator 需要预先下载 code-generator 。因为这个工具不是必需要求的。</description>
    </item>
    <item>
      <title>手写一个kubernetes controller</title>
      <link>https://www.161616.top/ch12-controller/</link>
      <pubDate>Mon, 20 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch12-controller/</guid>
      <description>Overview 根据Kuberneter文档对Controller的描述，Controller在kubernetes中是负责协调的组件，根据设计模式可知，controller会不断的你的对象（如Pod）从当前状态与期望状态同步的一个过程。当然Controller会监听你的实际状态与期望状态。
Writing Controllers go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 package main import ( &amp;#34;flag&amp;#34; &amp;#34;fmt&amp;#34; &amp;#34;os&amp;#34; &amp;#34;time&amp;#34; v1 &amp;#34;k8s.</description>
    </item>
    <item>
      <title>使用CRD扩展Kubernetes API</title>
      <link>https://www.161616.top/ch13-crd/</link>
      <pubDate>Sun, 19 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch13-crd/</guid>
      <description>Kubernetes的主节点或控制面板当中主要有三个组件，其中apiserver是整个系统的数据库，借助于Cluster Store（etcd）服务，来实现所有的包括用户所期望状态的定义，以及集群上资源当前状态的实时记录等。
etcd是分布式通用的K/V系统 KV Store ，可存储用户所定义的任何由KV Store所支持的可持久化的数据。它不仅仅被apiserver所使用，如flannel、calico二者也需要以etcd来保存当前应用程序对应的存储数据。 任何一个分布式应用程序几乎都会用到一个高可用的存储系统。
apiserver将etcd所提供的存储接口做了高度抽象，使用户通过apiserver来完成数据存取时，只能使用apiserver中所内建支持的数据范式。在某种情况之下，我们所期望管理的资源或存储对象在现有的Kubernetes资源无法满足需求时。
Operator本身是建构在StatefulSet以及本身的基本Kubernetes资源之上，由开发者自定义的更高级的、更抽象的自定义资源类型。他可借助于底层的Pod、Service功能，再次抽象出新资源类型。更重要的是，整个集群本身可抽象成一个单一资源。
为了实现更高级的资源管理，需要利用已有的基础资源类型，做一个更高级的抽象，来定义成更能符合用户所需要的、可单一管理的资源类型，而无需去分别管理每一个资源。
在Kubernetes之上自定义资源一般被称为扩展Kubernetes所支持的资源类型，
自定义资源类型 CRD Custom Resource Definition 自定义apiserver 修改APIServer源代码，改动内部的资源类型定义 CRD是kubernetes内建的资源类型，从而使得用户可以定义的不是具体的资源，而是资源类型，也是扩展Kubernetes最简单的方式。
Intorduction CRD 什么是CRD 在 Kubernetes API 中，resources 是存储 API 对象集合的endpoint。例如，内置 Pod resource 包含 Pod 对象的集合。当我们想扩展API，原生的Kubernetes就不能满足我们的需求了，这时 CRD (CustomResourceDefinition) 就出现了。在 Kubernetes 中创建了 CRD 后，就可以像使用任何其他原生 Kubernetes 对象一样使用它，从而利用 Kubernetes 的所有功能、如安全性、API 服务、RBAC 等。
Kubernetes 1.7 之后增加了对 CRD 自定义资源二次开发能力来扩展 Kubernetes API，通过 CRD 我们可以向 Kubernetes API 中增加新资源类型，而不需要修改 Kubernetes 源码来创建自定义的 API server，该功能大大提高了 Kubernetes 的扩展能力。
创建 CRD 前提条件： Kubernetes 服务器版本必须不低于版本 1.</description>
    </item>
    <item>
      <title>源码分析client-go架构 - queue</title>
      <link>https://www.161616.top/ch09-queue/</link>
      <pubDate>Fri, 17 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch09-queue/</guid>
      <description>通用队列 在kubernetes中，使用go的channel无法满足kubernetes的应用场景，如延迟、限速等；在kubernetes中存在三种队列通用队列 common queue ，延迟队列 delaying queue，和限速队列 rate limiters queue
Inferface Interface作为所有队列的一个抽象定义
go 1 2 3 4 5 6 7 8 type Interface interface { Add(item interface{}) Len() int Get() (item interface{}, shutdown bool) Done(item interface{}) ShutDown() ShuttingDown() bool } Implementation go 1 2 3 4 5 6 7 8 9 10 11 12 13 type Type struct { // 一个work queue queue []t // queue用slice做存储 dirty set // 脏位，定义了需要处理的元素，类似于操作系统，表示已修改但为写入 processing set // 当前正在处理的元素集合 cond *sync.</description>
    </item>
    <item>
      <title>源码分析client-go架构 - 什么是informer</title>
      <link>https://www.161616.top/ch08-informer/</link>
      <pubDate>Wed, 25 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch08-informer/</guid>
      <description>之前了解了client-go中的架构设计，也就是 tools/cache 下面的一些概念，那么下面将对informer进行分析
Controller 在client-go informer架构中存在一个 controller ，这个不是 Kubernetes 中的Controller组件；而是在 tools/cache 中的一个概念，controller 位于 informer 之下，Reflector 之上。code
Config 从严格意义上来讲，controller 是作为一个 sharedInformer 使用，通过接受一个 Config ，而 Reflector 则作为 controller 的 slot。Config 则包含了这个 controller 里所有的设置。
go 1 2 3 4 5 6 7 8 9 type Config struct { Queue // DeltaFIFO ListerWatcher // 用于list watch的 Process ProcessFunc // 定义如何从DeltaFIFO中弹出数据后处理的操作 ObjectType runtime.Object // Controller处理的对象数据，实际上就是kubernetes中的资源 FullResyncPeriod time.Duration // 全量同步的周期 ShouldResync ShouldResyncFunc // Reflector通过该标记来确定是否应该重新同步 RetryOnError bool } controller 然后 controller 又为 reflertor 的上层</description>
    </item>
    <item>
      <title>Kubernetes组件核心 - client-go</title>
      <link>https://www.161616.top/ch06-client-go/</link>
      <pubDate>Sun, 22 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch06-client-go/</guid>
      <description>Prepare Introduction 从2016年8月起，Kubernetes官方提取了与Kubernetes相关的核心源代码，形成了一个独立的项目，即client-go，作为官方提供的go客户端。Kubernetes的部分代码也是基于这个项目的。
client-go 是kubernetes中广义的客户端基础库，在Kubernetes各个组件中或多或少都有使用其功能。。也就是说，client-go可以在kubernetes集群中添加、删除和查询资源对象（包括deployment、service、pod、ns等）。
在了解client-go前，还需要掌握一些概念
在客户端验证 API 使用证书和使用令牌，来验证客户端 kubernetes集群的访问模式 使用证书和令牌来验证客户端 在访问apiserver时，会对访问者进行鉴权，因为是https请求，在请求时是需要ca的，也可以使用 -k 使用insecure模式
text 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 $ curl --cacert /etc/kubernetes/pki/ca.crt https://10.0.0.4:6443/version \{ &amp;#34;major&amp;#34;: &amp;#34;1&amp;#34;, &amp;#34;minor&amp;#34;: &amp;#34;18+&amp;#34;, &amp;#34;gitVersion&amp;#34;: &amp;#34;v1.18.20-dirty&amp;#34;, &amp;#34;gitCommit&amp;#34;: &amp;#34;1f3e19b7beb1cc0110255668c4238ed63dadb7ad&amp;#34;, &amp;#34;gitTreeState&amp;#34;: &amp;#34;dirty&amp;#34;, &amp;#34;buildDate&amp;#34;: &amp;#34;2022-05-17T12:45:14Z&amp;#34;, &amp;#34;goVersion&amp;#34;: &amp;#34;go1.16.15&amp;#34;, &amp;#34;compiler&amp;#34;: &amp;#34;gc&amp;#34;, &amp;#34;platform&amp;#34;: &amp;#34;linux/amd64&amp;#34; } $ curl -k https://10.</description>
    </item>
    <item>
      <title>如何通过源码编译Kubernetes</title>
      <link>https://www.161616.top/ch11-code-compile/</link>
      <pubDate>Mon, 16 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch11-code-compile/</guid>
      <description>本地构建 选择要构建的版本 text 1 git checkout tags/v1.19.5 将依赖包复制到对应路径下 text 1 cp staging/src/k8s.io vendor/ 调整makefile 在windows上编译的克隆下可能文件编码变了，需要手动修改下文件编码。比如说出现 \r not found 类似关键词时
这里转换编码使用了 dos2unix，需要提前安装下
text 1 apt install dos2unix 转换原因是因为对于bash 脚本执行识别不了windows的换行
text 1 find . -name &amp;#39;*.sh&amp;#39; -exec dos2unix {} \; 然后将 build/root/ 的文件复制到项目根目录
text 1 cp build/root/Makefile* ./ 编译 查看帮助 make help
编译 make all WHAT=cmd/kube-apiserver GOFLAGS=-v
WHAT=cmd/kube-apiserver 为仅编译单一组件，all 为所有的组件
还可以增加其他的一些环境变量 KUBE_BUILD_PLATFORMS= 如编译的平台
更多的可以 make help 查看帮助
编译中问题 Makefile:93: recipe for target &amp;lsquo;all&amp;rsquo; failed</description>
    </item>
    <item>
      <title>深入理解kubernetes API</title>
      <link>https://www.161616.top/ch02-kubernetes-api/</link>
      <pubDate>Mon, 16 May 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch02-kubernetes-api/</guid>
      <description>APIServer 在kubernetes架构概念层面上，Kubernetes由一些具有不同角色的服务节点组成。而master的控制平面由 Apiserver Controller-manager 和 Scheduler 组成。
Apiserver 从概念上理解可以分为 api 和 object 的集合，api 可以理解为，处理读写请求来修改相应 object 的组件；而 object 可以表示为 kubernetes 对象，如 Pod， Deployment 等 。
基于声明式的API 在命令式 API 中，会直接发送要执行的命令，例如：运行、停止 等命令。在声明式API 中，将声明希望系统执行的操作，系统将不断将自身状态朝希望状态改变。
为什么使用声明式 在分布式系统中，任何组件随时都可能发生故障，当组件故障恢复时，需要明白自己需要做什么。在使用命令式时，出现故障的组件可能在异常时错过调用，并且在恢复时需要其他外部组件进行干预。而声明式仅需要在恢复时确定当前状态以确定他需要做什么。
External APIs 在kubernetes中，控制平面是透明的，及没有internal APIs。这就意味着Kubernetes组件间使用相同的API交互。这里通过一个例子来说明外部APIs与声明式的关系。
例如，创建一个Pod对象，Scheduler 会监听 API来完成创建，创建完成后，调度程序不会命令被分配节点启动Pod。而在kubelet端，发现pod具有与自己相同的一些信息时，会监听pod状态。如改变kubelet则修改状态，如果删除掉Pod（对象资源不存在与API中），那么kubelet则将终止他。
为什么不使用Internal API 使用External API可以使kubernetes组件都使用相同的API，使得kubernetes具有可扩展性和可组合性。对于kubernetes中任何默认组件，如不足满足需求时，都可以更换为使用相同API的组件。
另外，外部API还可轻松的使用公共API来扩展kubernetes的功能
API资源 从广义上讲，kubernetes对象可以用任何数据结构来表示，如：资源实例、配置（审计策略）或持久化实体（Pod）；在使用中，常见到的就是对应YAML的资源清单。转换出来就是RESTful地址，那么应该怎么理解这个呢？即，对资源的动作（操作）如图所示。但如果需要了解Kubernetes API需要掌握一些概念才可继续。
Group 出于对kubernetes扩展性的原因，将资源类型分为了API组进行独立管理，可以通过 kubectl api-resources查看。在代码部分为 vendor/k8s.io/api
也可以通过 kubectl xxx -v 6 来查看 kubectl 命令进行了那些API调用
text 1 2 3 4 5 6 7 8 9 10 11 $ kubectl get pods -v 6 I0513 21:54:33.</description>
    </item>
    <item>
      <title>理解kubernetes listwatch机制原理</title>
      <link>https://www.161616.top/ch05-listwatch-mechanism/</link>
      <pubDate>Sun, 12 Dec 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch05-listwatch-mechanism/</guid>
      <description>overview kubernetes的设计里面大致上分为3部分：
API驱动型的特点 (API-driven) 控制循环（control loops）与 条件触发 （Level Trigger） API的可延伸性 而正因为这些设计特性，才使得kubernetes工作非常稳定。
什么是Level Trigger与 Edge trigger 看到网上有资料是这么解释两个属于的：
条件触发(level-trigger，也被称为水平触发)LT指： 只要满足条件，就触发一个事件(只要有数据没有被获取，就不断通知)。
边缘触发(edge-trigger)ET: 每当状态变化时，触发一个事件。
通过查询了一些资料，实际上也不明白这些究竟属于哪门科学中的理论，但是具体解释起来看的很明白。
LEVEL TRIGGERING：当电流有两个级别，VH 和 VL。代表了两个触发事件的级别。如果将VH 设置为LED在正时钟。当电压为VH时，LED可以在该时间线任何时刻点亮。这称为LEVEL TRIGGERING，每当遇到VH 时间线就会触发事件。事件是在时间内的任何时刻开始，直到满足条件。
Edge TRIGGERING:
如图所示，会看到上升线与下降线，当事件在上升/下降边缘触发时（两个状态的交点），称为边缘触发（Edge TRIGGERING:）。
如果需要打开LED灯，则当时钟从VL转换到VH时才会亮起，而不是一家处在对应的时钟线上，仅仅是在过渡时亮起。
为什么kubernetes使用Level Trigger而不使用Edge trigger 如图所述，两种不同的设计模式，随着时间形状进行相应，当系统在由高转低，或由低转高时，系统处在关闭或者不可控的异常状态下，应如何触发对应的事件呢。
换一种方式来来解释，比如说通过 加法运算，如下，i=3，当给I+4作为一个操作触发事件。
text 1 2 3 4 5 # let i=3 # let i+=4 # let i # echo $i 7 当为Edge trigger时操作的情况下，将看到 i+4 ,而在 level trigger 时看到的是 i=7。这里将会从``i+4` 一直到下一个信号的触发。
信号的干扰 通常情况下，两者是没有区别的，但在大规模分布式网络环境中，有很多因素的影响下，任何都是不可靠的，在这种情况下会改变了我们对事件信号的感知。
如图所示，图为Level Trigger与Edge trigger 的信号发生模拟，在理想情况下，两者间并没有什么不同。</description>
    </item>
    <item>
      <title>理解kubernetes schema</title>
      <link>https://www.161616.top/ch03-kubernetes-schema/</link>
      <pubDate>Mon, 22 Nov 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch03-kubernetes-schema/</guid>
      <description>什么是schema schema一词起源于希腊语中的form或figure，但具体应该如何定义schema取决于应用环境的上下文。schema有不同的类型，其含义与数据科学、教育、营销和SEO以及心理学等领域密切相关。
在维基百科中将schema解释为，图式，在心里学中主要描述一种思维或行为类型，用来组织资讯的类别，以及资讯之间的关系。它也可以被描述为先入为主思想的心理结构，表示世界某些观点的框架，或是用于组织和感知新资讯的系统。
但在计算机科学中，从很多地方都可以看到 schema 这个名词，例如 database，openldap，programing language等的。这里可以简单的吧schema 理解为 元数据集合 （metadata component）数据模型，主要包含元素及属性的声明，与其他数据结构组成。
数据库中的schema 在数据库中，schema 就像一个骨架结构，代表整个数据库的逻辑视图。它设计了应用于特定数据库中数据的所有约束。当在数据建模时，就会产生一个schema。在谈到关系数据库]和面向对象数据库时经常使用schema。有时也指将结构或文本的描述。
数据库中schema描述数据的形状以及它与其他模型、表和库之间的关系。在这种情况下，数据库条目是schema的一个实例，包含schema中描述的所有属性。
数据库schema通常分为两类：定义数据文件实际存储方式的**物理数据库schema ；和逻辑数据库schema **，它描述了应用于存储数据的所有逻辑约束，包括完整性、表和视图。常见包括
星型模式（star schema） 雪花模式（snowflake schema） 事实星座模型（fact constellation schema 或 galaxy schema） 星型模式是类似于一个简单的数据仓库图，包括一对多的事实表和维度表。它使用非规范化数据。
雪花模式是更为复杂的一种流行的数据库模式，在该模式下，维度表是规范化的，可以节省存储空间并最大限度地减少数据冗余。
事实星座模式远比星型模式和雪花模式复杂得多。它拥有多个共享多个维度表的事实表。
Kubernetes中的schema 通过上面的阐述，大概上可以明白 schema究竟是什么东西了，在Kubernetes中也有schema的概念，通过对kubernetes中资源（GVK）的规范定义、相互关系间的映射等，schema即k8s资源对象元数据。
而kubernetes中资源对象即 Group Version Kind 这些被定义在 staging/src/k8s.io/api/type.go中，即平时所操作的yaml文件，例如
yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: apps/v1 kind: Deployment metadata: name: ngx namespace: default spec: selector: matchLabels: app: ngx template: metadata: labels: app: nginx spec: containers: - name: ngx-schema image: nginx ports: - containerPort: 80 而对应的的即为TypeMeta 、ObjectMeta 和 DeploymentSpec,</description>
    </item>
    <item>
      <title>k8s开发环境准备 - 如何配置开发环境</title>
      <link>https://www.161616.top/ch01-k8s-perpare/</link>
      <pubDate>Fri, 19 Nov 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch01-k8s-perpare/</guid>
      <description>下载源码 根据kubernetes github 方式可以
text 1 2 3 4 5 mkdir -p $GOPATH/src/k8s.io cd $GOPATH/src/k8s.io git clone https://github.com/kubernetes/kubernetes cd kubernetes make 如果有需要可以切换到对应的版本进行学习或者修改，一般kubernetes版本为对应tag
text 1 2 3 git fetch origin [远程tag名] git checkout [远程tag名] git branch 配置goland kubernetes本身是支持 go mod 的，但源码这里提供了所有的依赖在 staging/src/k8s.io/ 目录下，可以将此目录内的文件复制到 vendor下。
bash 1 cp -a staging/src/k8s.io/* vendor/k8s.io/ 对于 k8s.io/kubernetes/pkg/ 发红的（找不到依赖的），可以将手动创建一个目录在 vendor/k8s.io/ 将克隆下来的根目录 pkg 复制到刚才的目录下。
goland中，此时不推荐使用go mod模式了，这里goland一定要配置GOPATH的模式。对应的GOPATH加入 {project}/vender即可。 这里可以添加到 goland中 project GOPATH里。</description>
    </item>
  </channel>
</rss>
