<?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 on Cylon&#39;s Collection</title>
    <link>https://www.161616.top/tags/kubernetes/</link>
    <description>Recent content in Kubernetes on Cylon&#39;s Collection</description>
    <generator>Hugo -- 0.125.7</generator>
    <language>zh</language>
    <lastBuildDate>Fri, 27 Jun 2025 23:00:36 +0800</lastBuildDate>
    <atom:link href="https://www.161616.top/tags/kubernetes/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>记录一次服务器断电引起的etcd无法启动问题处理</title>
      <link>https://www.161616.top/server-power-outage-etcd-panic-lease/</link>
      <pubDate>Fri, 27 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/server-power-outage-etcd-panic-lease/</guid>
      <description>背景 在一次物理机断电回复后，Kubernetes 集群因断电或其他原因导致 etcd 启动时出现 “panic: lease ID must be 8-byte” 错误。本文记录如何诊断和修复 etcd 数据损坏，并恢复 Kubernetes 集群的过程。
问题描述 在尝试启动 etcd 服务时，日志显示以下错误：
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 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 {&amp;#34;level&amp;#34;:&amp;#34;warn&amp;#34;,&amp;#34;ts&amp;#34;:&amp;#34;2025-06-26T08:46:12.</description>
    </item>
    <item>
      <title>Demo - Pod终止的生命周期</title>
      <link>https://www.161616.top/kubernetes-terminate-processing/</link>
      <pubDate>Tue, 29 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-terminate-processing/</guid>
      <description>原理 通常 Pod 体面终止的过程为：kubelet 先发送一个带有体面超时限期的 TERM（又名 SIGTERM，根据参数terminationGracePeriodSeconds来决定） 信号到每个容器中的主进程，将请求发送到容器运行时来尝试停止 Pod 中的容器。 停止容器的这些请求由容器运行时以异步方式处理。 这些请求的处理顺序无法被保证。许多容器运行时遵循容器镜像内定义的 STOPSIGNAL 值， 如果不同，则发送容器镜像中配置的 STOPSIGNAL，而不是 TERM 信号。 一旦超出了体面终止限期，容器运行时会向所有剩余进程发送 KILL 信号，之后 Pod 就会被从 API 服务器上移除。 如果 kubelet 或者容器运行时的管理服务在等待进程终止期间被重启， 集群会从头开始重试，赋予 Pod 完整的体面终止限期。
通常终止流程按照下面约束进行：
如果 Pod 中的容器之一定义了 preStop 回调 且 Pod 规约中的 terminationGracePeriodSeconds 未设为 0， kubelet 开始在容器内运行该回调逻辑。默认的 terminationGracePeriodSeconds 设置为 30 秒.
如果 Pod 未定义 preStop 回调，根据默认的 terminationGracePeriodSeconds 设置为 30 秒。进行 kill -9（无论terminationGracePeriodSeconds 有没有配置）
如果 preStop 回调在体面期结束后仍在运行，kubelet 将请求短暂的、一次性的体面期延长 2 秒。即 30 + 2 s 后删除Pod。</description>
    </item>
    <item>
      <title>深入理解Kubernetes Pod网络原理 - CNI</title>
      <link>https://www.161616.top/deep-dive-k8s-network-cni/</link>
      <pubDate>Sun, 02 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/deep-dive-k8s-network-cni/</guid>
      <description>本文是关于深入理解Kubernetes网络原理系列第3章 深入理解Kubernetes Pod网络原理 - 网络名称空间 深入理解Kubernetes Pod网络原理 - Linux虚拟网络技术 深入理解Kubernetes Pod网络原理 - CNI 深入理解Kubernetes Pod网络原理 - 跟随 flannel 学习CNI原理 深入理解Kubernetes Pod网络原理 - 跟随 flannel + multus 剖析 Chained Plugins 深入理解Kubernetes Pod网络原理 - 从零实现一个 CNI Plugin part 1 (Shell) 深入理解Kubernetes Pod网络原理 - 从零实现一个 CNI Plugin part 2 (libcni) 深入理解Kubernetes Pod网络原理 - Kubernetes网络模型 1 深入理解Kubernetes Pod网络原理 - Kubernetes网络模型 2 深入理解Kubernetes Pod网络原理 - Pod网络排错思路 概述 这是我在 kubernetes 网络之旅中的中的第4部分，主要学习 CNI 规范（5要素，旧版本是4要素）。要深深记住这些，在后面旅程中常常被用到。
Notes 本文讲解均按照 1.</description>
    </item>
    <item>
      <title>使用WSL2安装kind (Win10 &amp; DockerDesktop)</title>
      <link>https://www.161616.top/kind-wsl2-windows10-installation/</link>
      <pubDate>Sun, 12 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kind-wsl2-windows10-installation/</guid>
      <description>本文说明如何使用 Windows 10 创建单节点的 kind 集群 (KinD Kubernetes in Docker)。
先提条件 条件 版本 操作系统：Windows 10 或 Windows 11 May 2020 Update (build 19041) Docker in WSL2 推荐安装Docker Desktop WSL2 distro 镜像 这里采用Debian 内存 至少 8GB 内存 方式1：直接使用 docker desktop进行安装 软件 版本 Docker Desktop 4.8.1 WSL Linux Ubuntu 22 kubectl 使用 wsl ubuntu 22 作为客户端 安装 Docker Desktop 首先完成 Windows 开启 WSL2 和 安装好 Docker Desktop, 可以参考附录1 [1]
安装 kubectl 这里使用和 kind 版本一致的 kubectl 1.</description>
    </item>
    <item>
      <title>debian12 - 高版本系统安装旧版本k8s异常处理</title>
      <link>https://www.161616.top/debian12-install-k8s-1.16/</link>
      <pubDate>Sun, 24 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/debian12-install-k8s-1.16/</guid>
      <description>今日在部署旧版本 k8s 集群 (1.16.10) 时出现错误，主要是在新版本操作系统上部署老版本 k8s，kubelet会出现如下错误
bash 1 2 W1123 22:31:47.383423 3686 server.go:605] failed to get the kubelet&amp;#39;s cgroup: mountpoint for cpu not found. Kubelet system container metrics may be missing. W1123 22:31:47.383572 3686 server.go:612] failed to get the container runtime&amp;#39;s cgroup: failed to get container name for docker process: mountpoint for cpu not found. Runtime system container metrics may be missing. 错误原因 上面的报错是 Kubelet 无法正确访问 Docker 容器运行时的 cgroup 信息，特别是关于 CPU 使用的 cgroup 信息</description>
    </item>
    <item>
      <title>TLS Everywhere - 解密kubernetes集群的安全认证</title>
      <link>https://www.161616.top/k8s-auth-and-regenerate-cert/</link>
      <pubDate>Sun, 24 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/k8s-auth-and-regenerate-cert/</guid>
      <description>本文是关于Kubernetes 4A解析的第5章 深入理解Kubernetes 4A - Authentication源码解析 深入理解Kubernetes 4A - Authorization源码解析 深入理解Kubernetes 4A - Admission Control源码解析 深入理解Kubernetes 4A - Audit源码解析 TLS Everywhere - 解密kubernetes集群的安全认证 所有关于Kubernetes 4A部分代码上传至仓库 github.com/cylonchau/hello-k8s-4A
在 kubernetes 集群中，所有的通讯都是用 TLS 进行加密和认证，本文使用一次老集群（二进制部署集群）证书更换作为记录，通过这种方式深入对 kubernetes 的认证方式来了解更换证书的步骤，以及一次模拟老集群的更换步骤。
本文使用证书生成工具为 “kubernetes-generator” [1] 专用于 k8s 二进制部署生成证书和安装包的工具。
note 本文中的引用文档使用 web.archive 进行保存，避免官方版本更新，其概念与文档中的概念有变动导致，资料引用失败。 Kubernetes认证方式 为了了解证书更换需要做那些步骤，所以必须了解 k8s 的认证方式，这样才能更好的在更换证书时对集群上部署的业务系统的影响降低到最低。
X509 证书 kube-apiserver 的启动参数 --client-ca-file，可以使用客户端办法机构，英文代号就是熟悉的 “CA” (Certificate authority)，当这个证书传递后，可以验证 kube-apiserver 用于验证向 kube-apiserver 提供的客户端证书，这里包含 k8s 中提供的用户种类的两种：
用户名：对应证书的 CN (Common Name) 用户组：对应证书的O (organization)，用于对一个用户组进行授权，例如 “system:masters” 表示一个组 [1]，允许不受限制地访问 kube-apiserver 静态token kube-apiserver 的启动参数 --token-auth-file，是以文件提供给 kube-apiserver，该 Token 会长期有效，并且如果不重启服务 Token 是不会更新。</description>
    </item>
    <item>
      <title>构建集群kubernetes v1.28并使用kine和mysql替换etcd</title>
      <link>https://www.161616.top/kubernetes-without-etcd-step-by-step/</link>
      <pubDate>Sun, 30 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-without-etcd-step-by-step/</guid>
      <description>在本文中，将探讨使用 k3s 的 kine 项目来替换掉 etcd，并通过实验使用 kubeadm 去 run 一个 k8s 集群，并用 k3s 的 kine 项目来替换掉 etcd。
为什么使用 kine etcd 在 Kubernetes 之外基本上没有应用的场景，并且 etcd 迭代也比较慢，由于没有人愿意维护因此一直在衰退 [1]，并且，Kubernetes 集群中，etcd 也是一个影响集群规模的重大因素。并且 K3S 存在一个项目 Kine 可以使用关系型数据库运行，这样对集群维护者来说可以不需要维护复杂的 etcd 集群，由于关系型数据库有很多高可用方案，这将使得 k8s 集群规模变成了无限可能。
Kine 介绍 前文提到，kubernetes (kube-apiserver) 与 etcd 是耦合的，如果我们要使用 RDBMS 去替换 etcd 就需要实现 etcd 的接口，那么这个项目就是 Kine [2]。
Kine 是一个 etcdshim，处于 kube-apiserver 和 RDBMS 的中间层，它实现了 etcdAPI的子集（不是etcd的全部功能），Kine 在 RDBMS 数据库之上实现了简单的多版本并发控制；将所有信息存储在一个表中；每行存储此 key 的修订, key, 当前值, 先前值, 先前修订，以及表示该 Key 是已创建还是已删除的标记，通过这种机制可以作为 shim 层来替换 etcd。</description>
    </item>
    <item>
      <title>深入解析Kubernetes监控体系与prometheus-adapter</title>
      <link>https://www.161616.top/prometheus-adapter-intro/</link>
      <pubDate>Fri, 31 May 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/prometheus-adapter-intro/</guid>
      <description>Kubernetes监控架构设计 k8s监控设计背景说明 根据 Kubernetes监控架构 1，Kubernetes 集群中的 metrcis 可以分为 系统指标 (Core Metrics) 和 服务指标 (service metrics) ; 系统指标(System metrics) 是通用的指标，通常可以从每一个被监控的实体中获得（例如，容器和节点的CPU和内存使用情况）。服务指标(Service metrics) 是在应用程序代码中显式定义并暴露的 (例如，API Server 处理的 500 错误数量)。
Kubernetes将系统指标分为两部分：
核心指标 (core metrics) 是 Kubernetes 理解和用于其内部组件和核心工具操作的指标，例如：用于调度的指标 (包括资源估算算法的输入, 初始资源/VPA (vertical autoscaling)，集群自动扩缩 (cluster autoscaling)，水平Pod自动扩缩 (horizontal pod autoscaling ) 除自定义指标之外的指标)；Kube Dashboard 使用的指标，以及 “kubectl top” 命令使用的指标。 非核心指标 (non-core metrics) 是指不被 Kubernetes 解释的指标。我们一般假设这些指标包含核心指标 (但不一定是 Kubernetes 可理解的格式)，以及其他额外的指标。 所以，kubernetes monitoring 的架构被设计拥有如下特点：
通过标准的主 API (当前为主监控 API) 提供关于Node, Pod 和容器的核心系统指标，使得核心 Kubernetes 功能不依赖于非核心组件 kubelet 只导出有限的指标集，即核心 Kubernetes 组件正常运行所需的指标。 &amp;hellip; 监控管道 Kubernetes 监控管道分为两个：</description>
    </item>
    <item>
      <title>探索kubectl - kubectl诊断命令集合</title>
      <link>https://www.161616.top/kubernetes-kubectl-diagnose/</link>
      <pubDate>Sat, 20 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-kubectl-diagnose/</guid>
      <description>工具命令集合 长期总结 - Linux日志查询命令 长期总结 - Linux网络命令合集 长期总结 - Linux性能分析命令 awk常用案例 bash shell常用示例 探索kubectl - 巧用jsonpath提取有用数据 探索kubectl - kubectl诊断命令集合 Pod 检查 Pod 就绪探针
bash 1 kubectl get pods &amp;lt;pod-name&amp;gt; -n &amp;lt;namespace&amp;gt; -o jsonpath=&amp;#39;{.status.conditions[?(@.type==&amp;#34;Ready&amp;#34;)].status}&amp;#39; 查看 Pod 事件
bash 1 kubectl get events -n &amp;lt;namespace&amp;gt; --field-selector involvedObject.name=&amp;lt;pod-name&amp;gt; 获取 Pod Affinity 和 Anti-Affinity
bash 1 kubectl get pod &amp;lt;pod-name&amp;gt; -n &amp;lt;namespace&amp;gt; -o=jsonpath=&amp;#39;{.spec.affinity}&amp;#39; 列出 Pod 的 anti-affinity 规则
bash 1 kubectl get pod &amp;lt;pod-name&amp;gt; -n &amp;lt;namespace&amp;gt; -o=jsonpath=&amp;#39;{.</description>
    </item>
    <item>
      <title>批量更新harbor版本 1.10 to 2.10</title>
      <link>https://www.161616.top/upgrade-harbor/</link>
      <pubDate>Fri, 29 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/upgrade-harbor/</guid>
      <description>本文将介绍 Harbor 从 v1.10.7 升级到 v2.10.0，以及如何将 Harbor 从 v2.10 回滚到 v1.10.7。
升级条件 Linux服务器 4 个 CPU 和 8 GB 内存（强要求），100G可用空间（跨多版本时存放备份文件以及镜像文件，这部分要求） Docker-compose &amp;gt; 1.19.0+ 备份现有的 Harbor /data/database 目录 本次升级主要是使用了 harbor 内置的数据库，所以升级步骤比较容易。
官方升级路线 harbor 的升级，是不能跨很多版本进行升级，官方对此有详细说明 [1] ，可以看到路线为：
1.10.0 [1] =&amp;gt; 2.4.0 [2] =&amp;gt; 2.6.0 [3] =&amp;gt; 2.8.0 [4] =&amp;gt; 2.10.0 [5]
模拟升级步骤 github release 页下载对应的安装包
解压
bash 1 2 # 命令主要为将harbor压缩包内文件解压到指定目录中，由于 harbor 解压后文件名无论版本如何都为“harbor” $ mkdir ./harbor-v1.10 &amp;amp;&amp;amp; tar -xf harbor-offline-installer-v1.10.0.tgz -C ./harbor-v1.10 --strip-components 1 备份默认的配置文件（仅限于 v1.</description>
    </item>
    <item>
      <title>Kubernetes维护 - secret批量更新</title>
      <link>https://www.161616.top/kubernetes-update-secert/</link>
      <pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-update-secert/</guid>
      <description>tls 证书在 k8s 集群上大量使用的话，当到期时会存在批量替换的难度，比如说每个名称空间，多个业务的使用，在这篇博文中，将尝试批量替换整个集群的证书（前提，在没有使用 vault, cert-manager这类组件的集群之上）。
基本操作 步骤1：首先不知道有多少个名称空间使用了这个证书，所以需要遍历所有的名称空间，这里使用 kubectl 的 json path 实现
bash 1 $ kubectl get ns -o jsonpath=&amp;#39;{range $.items[*]}{.metadata.name}{&amp;#34;\n&amp;#34;}{end}&amp;#39; 步骤2：拿到名称空间的名字后，就需要循环这个名称空间下所有的 secret
bash 1 2 3 4 for ns in `kubectl get ns -o jsonpath=&amp;#39;{range $.items[*]}{.metadata.name}{&amp;#34;\n&amp;#34;}{end}&amp;#39;` do kubectl get secret -n $ns -o jsonpath=&amp;#39;{range $.items[*]}{.metadata.name}{&amp;#34;\n&amp;#34;}{end}&amp;#39; done 步骤3：找到与这个匹配的证书进行替换
把步骤3拆解为下面几个步骤：
拿去到符合要求的secret的名字 匹配名称是否为修改的secret 做替换操作 由于步骤2使用的是 jsonpath 拿到的 secret name，由于 kubectl 并不支持高级jsonpath语法，官方推荐使用jq，那么使用jq获取名字
bash 1 kubectl get secret -n $ns -o json|jq -r .</description>
    </item>
    <item>
      <title>k8s - jsonnet从入门到放弃</title>
      <link>https://www.161616.top/k8s-jsonnet/</link>
      <pubDate>Sun, 18 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/k8s-jsonnet/</guid>
      <description>什么是jsonnet jsonnet是用于app或开发工具的数据模板语言，主要用于json的扩展，具有下面功能：
生成配置数据 无副作用 组织化，简化，统一化 管理无序的配置 jsonnet可以通过面向对象消除重复。或者，使用函数。与现有/自定义应用程序集成。生成 JSON、YAML、INI 和其他格式。
安装jsonnet Jsonnet 有两种实现（C++ 和 Go）
在 Debian/Ubuntu 之上，可以直接使用 apt 源来安装
bash 1 apt install jsonnet -y 安装 go 实现的，可以用下面命令，前提是安装了go
bash 1 go get github.com/google/go-jsonnet/cmd/jsonnet 什么是jsonnet-bundler jsonnet-bundler 是 Jsonnet 的包管理器，用于个简化 jsonnet 项目中依赖关系管理的工具。使用 Jsonnet Bundler 可以带来下面便利之处：
使用 jsonnetfile.json 作为依赖关系管理 自动安装和更新依赖项。 版本选择，使用 jsonnetfile.json 可以确保项目使用正确版本的依赖。 可重复构建， 使用 jsonnetfile.json 管理的项目可以在不同环境中构建并确保结果的一致性。 更方便的与 GitOps 结合， Jsonnet Bundler 提供 与 GitOps 的集成。 jsonnet-bundler 安装 Jsonnet Bundler 有两种安装模式，实际上就是 Go 程序通用的安装方式：</description>
    </item>
    <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>在隔离网络中的多k8s集群中的实现JProfiler的自动化映射方案的设计与实现</title>
      <link>https://www.161616.top/jprofiler-in-k8s-cluster/</link>
      <pubDate>Mon, 11 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/jprofiler-in-k8s-cluster/</guid>
      <description>背景与架构设计 网络中存在的挑战 挑战1：Kubernetes 的每个 Pod 拥有一个独立的 IP 地址。对外部访问则依赖 NodePort、LoadBalancer 或 Ingress，出于安全考虑不可能对每个 Pod 都暴露其 8849 端口 (NodePort) 或者使用 Ingress 配置大量的域名，这样无法连接到单独的某一个 Pod (通过Service)。 挑战2：网络环境是完全隔离的，用户无法通过 Pod IP 直接访问 Pod，所有的用户流量只能通过对应 IDC 的唯一入口进入。 挑战3：出于安全考虑不可能对每一个 Java 服务 (Pod) 在他的工作周期期间所有时间都暴露对应的 Jprofiler 端口，而仅仅想使用时可以连接，用后关闭。 JProfiler网络需求 JProfiler 可以通过加载 JVM 代理（libjprofilerti.so）与远程 GUI 通信，他的实现原理如下：
JVM 启动时加载 JProfiler 代理，绑定到一个特定端口（如 8849）。 本地 JProfiler GUI 通过该端口连接到远程 JVM。 代理与 GUI 之间通过 TCP 传输性能数据。 在 Kubernetes 中，JProfiler 代理运行在 Pod 内部，但由于网络隔离和动态 IP，GUI 无法直接连接到 Pod。因此，我们需要一种机制将 JProfiler 的端口动态映射到可访问的外部端点。
需要实现的架构 下图是基于上面提到的问题从而设计的集群架构</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>K8S Admission Webhook官方扩展版 - ValidatingAdmissionPolicy</title>
      <link>https://www.161616.top/kubernetes-validatingadmissionpolicy/</link>
      <pubDate>Wed, 01 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-validatingadmissionpolicy/</guid>
      <description>相关阅读：深入理解Kubernetes 4A - Admission Control源码解析
准入 (Admission) 是 Kubernetes 提供 4A 安全认证中的一个步骤，在以前版本中 (1,26-)，官方提供了 webhook 功能，使用户可以自行的定义 Kubernetes 资源准入规则，但这些是有成本的，需要自行开发 webhook，下图是 Kubernetes准入控制流程。
图：Kubernetes API 请求的请求处理步骤图 Source：https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/ 在 Kubernetes 1.26 时 引入了 ValidatingAdmissionPolicy alpha 版，这个功能等于将 Admission Webhook controller 作为了一个官方扩展版，通过资源进行自行扩展，通过这种方式带来下面优势：
减少了准入请求延迟，提高可靠性和可用性 能够在不影响可用性的情况下失败关闭 避免 webhooks 的操作负担 ValidatingAdmissionPolicy 说明 验证准入策略提供一种声明式的、进程内的替代方案来验证准入 Webhook。
验证准入策略使用通用表达语言 (Common Expression Language，CEL) 来声明策略的验证规则。 验证准入策略是高度可配置的，使配置策略的作者能够根据集群管理员的需要， 定义可以参数化并限定到资源的策略
下面是一个 ValidatingAdmissionPolicy 的示例，配置 Deployment 必须拥有的副本数的限制
yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: admissionregistration.</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>探索kubectl - 巧用jsonpath提取有用数据</title>
      <link>https://www.161616.top/kubectl-jsonpath/</link>
      <pubDate>Mon, 25 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubectl-jsonpath/</guid>
      <description>工具命令集合 长期总结 - Linux日志查询命令 长期总结 - Linux网络命令合集 长期总结 - Linux性能分析命令 awk常用案例 bash shell常用示例 探索kubectl - 巧用jsonpath提取有用数据 探索kubectl - kubectl诊断命令集合 kubernetes集群工具 kubect 提供了一种强大的数据提取的模式，jsonpath，相对于 yaml 来说，jsonpath 拥有高度的自制提取功能，以及一些更便于提取字段的模式，使得过去 kubernetes 资源信息时更便捷，在本文中将解开 jsonpath 的神秘面纱。
什么是jsonpath JSONPath 是一种用于查询 JSON 数据结构中特定元素的查询语言。它类似于 XPath 用于 XML 数据的查询。JSONPath 允许您以一种简单而灵活的方式从 JSON 对象中提取数据，而不需要编写复杂的代码来解析 JSON 结构。
JSONPath 使用路径表达式来指定您要检索的 JSON 数据的位置。这些路径表达式类似于文件系统中的路径，但用于导航 JSON 结构。以下是一些常见的 JSONPath 表达式示例：
$：表示 JSON 根对象。 $.store：表示从根对象中获取名为 &amp;ldquo;store&amp;rdquo; 的属性。 $.store.book：表示从根对象中获取 &amp;ldquo;store&amp;rdquo; 属性中的 &amp;ldquo;book&amp;rdquo; 属性。 $.store.book[0]：表示获取 &amp;ldquo;store&amp;rdquo; 属性中的 &amp;ldquo;book&amp;rdquo; 属性的第一个元素。 $.store.book[?(@.price &amp;lt; 10)]：表示选择 &amp;ldquo;store&amp;rdquo; 属性中的 &amp;ldquo;book&amp;rdquo; 属性中价格小于 10 的所有元素。 Function Description Example Result text the plain text kind is {.</description>
    </item>
    <item>
      <title>修改ingress-nginx中default backend默认状态码</title>
      <link>https://www.161616.top/ingress-nginx-default-backend-status-code/</link>
      <pubDate>Thu, 21 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ingress-nginx-default-backend-status-code/</guid>
      <description>什么是 default backend default backend 是 ingress-nginx 中的一个服务，主要用于处理 nginx controller 无法识别的而请求的服务
主要提供了两个接口
/healthz that returns 200 /that returns 404 如何改default backend 状态码 需求：修改 default backend 状态码 404 为 403
原理：nginx-controller 启动时指定了一个 default backend 容器，如下所示
bash 1 2 3 4 5 6 7 8 9 10 11 12 containers: - args: - /nginx-ingress-controller # 这里指的是 default-backend 的名称 {namespace_name}/{service_name} - --default-backend-service=$(POD_NAMESPACE)/ingress-nginx-ext-defaultbackend - --publish-service=$(POD_NAMESPACE)/ingress-nginx-ext-controller - --election-id=ingress-controller-leader - --ingress-class=nginx-yewu-ext - --configmap=$(POD_NAMESPACE)/ingress-nginx-ext-controller - --validating-webhook=:8443 - --validating-webhook-certificate=/usr/local/certificates/cert - --validating-webhook-key=/usr/local/certificates/key 通常情况下在通过定义配置文件方式改变是不容易做的，ingress-nginx 提供了一种自定义方式 “custom-error-pages“ 可以完成 ，完成后该 defaultBackend 支持使用 X-code方式自定义任意的错误页即错误码。</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>在Kubernetes集群上安装 Calico cni 的注意事项</title>
      <link>https://www.161616.top/calico-cni-deplyment/</link>
      <pubDate>Wed, 21 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/calico-cni-deplyment/</guid>
      <description>开始前的实验环境 Resources controller worker-1 worker-2 OS CentOS 7.9 CentOS 7.9 CentOS 7.9 Storage 20GB 20GB 20GB vCPU 2 2 2 RAM 4GB 4GB 4GB NIC 10.0.0.4 10.0.0.4 10.0.0.4 Kubernetes Version 1.19.10 1.19.10 1.19.10 选择匹配 Kubernetes 版本的 Calico 版本 通常情况下，查看 Calico 所支持的 Kubernetes 版本，可以通过路径 Install Calico ==&amp;gt; Kubernetes ==&amp;gt; System requirements 可以找到自己的 Kubernetes 集群所支持的 Calico 版本。
例如在实验环境中，Kubernetes 1.19 版本所支持的版本有 Calico 3.20，这个时候直接 apply 这个版本提供的资源清单即可
如何开启纯 BGP 模式 默认情况下下，Calico 使用的是 full mesh 和 IPIP， 如果想通过在部署时就修改关闭 IPIP 模式，可以通过修改资源清单中的环境变量来关闭 CALICO_IPV4POOL_IPIP: Never。</description>
    </item>
    <item>
      <title>Kubernetes中的资源限制 - Request&amp;Limit</title>
      <link>https://www.161616.top/kubernetes-limit-request/</link>
      <pubDate>Sat, 17 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-limit-request/</guid>
      <description>原作者 Javier Martínez
背景 在学习 Kubernetes 调度时，有两个重要的概念，&amp;ldquo;request &amp;ldquo;与 &amp;ldquo;limit&amp;rdquo;，而对应的资源就是“内存” 与 “CPU” ，而这两个决定了 Pod 将如何调度；&amp;ldquo;request &amp;ldquo;与 &amp;ldquo;limit&amp;rdquo; 也是整个调度系统中的基数因子。
什么是 request 和 limit 在 Kubernetes 中，Limit 是容器可以使用的最大资源量，这表示 “容器” 的内存或 CPU 的使用，永远不会超过 Limit 配置的值。
而另一方面，Request 则是为 “容器” 保留的最低资源保障；换句话来说，Request 则是在调度时，容器被允许所需的配置。
图：Kubernetes 中Limit 和 Request 图示 Source：https://sysdig.com/blog/kubernetes-limits-requests/ 如何配置 request 和 limit 下列清单是 Deployment 的部署清单，他将部署一个 redis 与 一个 busybox
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 kind: Deployment apiVersion: extensions/v1beta1 … template: spec: containers: - name: redis image: redis:5.</description>
    </item>
    <item>
      <title>Awesome kubernetes</title>
      <link>https://www.161616.top/awesome-kubernetes/</link>
      <pubDate>Wed, 03 May 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/awesome-kubernetes/</guid>
      <description>Deployment Recommended Cluster Architecture - rancher Hardware recommendations - etcd A simple shell script for backing up etcd v2 and v3 datastores Considerations for large clusters - kubernetes cluster Operating etcd clusters for Kubernetes Recommended performance and scalability practices Binary deploy script pure shell Managing Kubernetes Traffic with F5 NGINX Eraser - Cleaning up Images from Kubernetes Nodes 对于不同规模的 Kubernetes 集群所需要的 etcd 规模推荐 datree: allowing you to scan your k8s configs during development Performance etcd: getting 30% more write/s 蚂蚁集团万级规模 K8s 集群 etcd 高可用建设之路 各组件参数配置调优 万级K8s集群背后etcd稳定性及性能优化实践 K8s 集群稳定性：LIST 请求源码分析、性能评估与大规模基础服务部署调优 Comparing comparing Kubernetes ingress controller Troubleshooting 一次Etcd集群宕机引发的思考 Stern: allows you to tail multiple pods on Kubernetes Diagnosis Kubernetes 自动化诊断工具：k8sgpt-operator ktop: displays useful metrics information about kubernetes cluster Dashboard KDash - A fast and simple dashboard for Kubernetes Security Kubernetes 加固指南 Popeye 扫描实时 Kubernetes 集群并报告已部署资源和配置的潜在问题 Test kube-monkey It randomly deletes Kubernetes (k8s) pods in the cluster encouraging and validating the development of failure-resilient services.</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负载均衡 - 从Ingress聊到LB</title>
      <link>https://www.161616.top/kubernetes-lb/</link>
      <pubDate>Sun, 26 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-lb/</guid>
      <description>概述 在之前有一个系列提到了扩展proxier，但可能细心的同学注意到，作为一个外部的LB，市场上存在一些开源的为kubernetes集群提供的LB，这不是舍近求远吗？而 Google工程师 Adam Dunstan 的 文章 [1] 对比了这些LB的区别（中文翻译备份 [2] ），例如：
MetalLB：最流行的 负载均衡控制器 PureLB：新产品 (文章作者 Adam Dunstan 参与了 PureLB的开发工作) OpenELB：相对较新的产品，最初该LB仅关注路由方向 文章提出了一个LB实现的基本目标为：必要的简单网络组件，与可扩展的集群操作
启动受控的集群service/应用的外部访问 外部资源的预配置 易于整合自动化的工作流程（CI/CD） 那么这些LB与 kube-proxy 甚至于 IPVS/IPTables 有什么区别呢？
这些LB的核心是为集群service提供一个外部IP，而service功能本身还是由 kube-proxy,IPVS 提供，在这点 MetalLB 介绍中提到了这个问题
In layer 2 mode, all traffic for a service IP goes to one node. From there, kube-proxy spreads the traffic to all the service’s pods. [3]
After the packets arrive at the node, kube-proxy is responsible for the final hop of traffic routing, to get the packets to one specific pod in the service.</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驱逐核心 - Pod QoS</title>
      <link>https://www.161616.top/kubernetes-pod-qos/</link>
      <pubDate>Thu, 01 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-pod-qos/</guid>
      <description>服务质量 Quality of Service (QoS)，在Kubernetes是用于解决资源抢占，延迟等方向的一种技术，是服务于调度与抢占之间的条件。
QoS 级别 QoS 与 资源限制紧密相关，正如下属展示，是一个Pod资源限制部分的配置
yaml 1 2 3 4 5 6 7 resources: limits: cpu: 200m memory: 1G requests: cpu: 500m memory: 1G 而Kubernetes 将Pod QoS 根据 CPU 与 内存的配置，将QoS分为三个等级：
Guaranteed：确保的，只设置 limits 或者 requests 与 limits 为相同时则为该等级 Burstable：可突发的，只设置 requests 或 requests 低于 limits 的场景 Best-effort： 默认值，如果不设置则为这个等级 为什么要关心Pod QoS级别 在Kubernetes中，将资源分为两类：可压缩性资源 “CPU”，不可压缩性资源 “内存”。当可压缩性资源用尽时，不会被终止与驱逐，而不可压缩性资源用尽时，即Pod内存不足，此时会被OOMKiller杀掉，也就是被驱逐等操作，而了解Pod 的QoS级别可以有效避免关键Pod被驱逐。
图：Pod QoS分类 Source：https://doc.kaas.thalesdigital.io/docs/BestPractices/QOS
有上图可知，BestEffort 级别的 Pod 能够使用节点上所有资源，浙江导致其他 Pod 出现资源问题。所以这类 Pod 优先级最低，如果系统没有内存，将首先被杀死。
Pod是如何被驱逐的 当节点的计算资源不足时，kubelet 会发起驱逐，这个操作是为了避免系统OOM事件，而QoS的等级决定了驱逐的优先级，没有限制资源的 BestEffort 类型的Pod最先被驱逐，接下来资源使用率低于 Requests 的 Guaranteed 与 Burstable 将不会被其他Pod的资源使用量而驱逐，其次对于此类Pod而言，如果Pod使用了比配置（Requests）更多的资源时，会根据这两个级别Pod的优先级进行驱逐。 BestEffort 与 **Burstable **将按照先优先级，后资源使用率顺序进行驱逐</description>
    </item>
    <item>
      <title>kubernetes概念 - 理解Kubernetes的驱逐机制</title>
      <link>https://www.161616.top/kubernetes-eviction/</link>
      <pubDate>Tue, 29 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-eviction/</guid>
      <description>驱逐 (eviction) 是指终止在Node上运行的Pod，保证workload的可用性，对于使用Kubernetes，了解驱逐机制是很有必要性的，因为通常情况下，Pod被驱逐是需要解决驱逐背后导致的问题，而想要快速定位就需要对驱逐机制进行了解。
Pod被驱逐原因 Kubernetes官方给出了下属Pod被驱逐的原因：
抢占驱逐 (Preemption and Eviction) [1] 节点压力驱逐 (Node-pressure) [2] 污点驱逐 (Taints) [3] 使用API发起驱逐 (API-initiated) [4] 排出Node上的Pod (drain) [5] 被 controller-manager 驱逐 抢占和优先级 抢占是指当节点资源不足以运行新添加的Pod时，kube-scheduler 会检查低优先级Pod而后驱逐掉这些Pod以将资源分配给优先级高的Pod。这个过程称为 “抢占” 例如这个实例是 kube-proxy 被驱逐的场景
节点压力驱逐 节点压力驱逐是指，Pod所在节点的资源，如CPU, 内存, inode等，这些资源被分为可压缩资源CPU (compressible resources) 与不可压缩资源 (incompressible resources) 磁盘IO, 内存等，当不可压缩资源不足时，Pod会被驱逐。对于此类问题的驱逐 是每个计算节点的 kubelet 通过捕获 cAdvisor 指标来监控节点的资源使用情况。
被 controller-manager 驱逐 kube-controller-manager 会定期检查节点的状态，如节点处于 NotReady 超过一定时间，或Pod部署长时间失败，这些Pod由控制平面 controller-manager 创建新的Pod已替换存在问题的Pod
通过API发起驱逐 Kubernetes为用户提供了驱逐的API，用户可以通过调用API来实现自定义的驱逐。
对于 1.22 以上版本，可以通过API policy/v1 进行驱逐
bash 1 2 3 4 5 6 7 8 9 10 11 curl -v \ -H &amp;#39;Content-type: application/json&amp;#39; \ https://your-cluster-api-endpoint.</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>漏桶算法与令牌桶算法</title>
      <link>https://www.161616.top/ch10-token-bucket-algorithm/</link>
      <pubDate>Sun, 28 Aug 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/ch10-token-bucket-algorithm/</guid>
      <description>Principle of token bucket 随着互联网的发展，在处理流量的方法也不仅仅为 first-come，first-served，而在共享网络中实现流量管理的基本机制就是排队。而公平算法则是实现在优先级队列中基于哪些策略来排队的 “公平队列” 。Token Bucket 则是为公平排队提供了替代方案。Fair Queue 与 Token Bucket的区别主要在，对于Fair Queue来讲，如果请求者目前空闲，Queue会将该请求者的带宽分配给其他请求者；而 Token Bucket 则是分配给请求者的带宽是带宽的上限。
通过例子了解算法原理
假设出站带宽是 4个数据包/ms，此时有一个需求为，为一个特定的发送端 A 来分配 1个数据包/ms的带宽。此时可以使用公平排队的方法分给发送 A 25%的带宽。
此时存在的问题是我们希望可以灵活地允许 A 的数据包以无规则的时间间隔发送。例如假设 A 在每个数据包发送后等待1毫秒后再开始下一个数据包的发送。
sence1：此时假设 A 以 1ms 的间隔去发送数据包，而由于某种原因导致应该在 t=6 到达的数据包却在 t=6.5 到达。随后的数据包在 t=7 准时到达，在这种情况下是否应该保留到t=7.5？ sence2：或者是否允许在 t=6.5 发送一个迟到的数据包，在 t=7 发送下一个数据包，此时理论上平均速率仍然还是 1 个数据包/ms？ 显然sence2是合理的，这个场景的解决方法就是令牌桶算法，规定 A 的配额，允许指定平均速率和突发容量。当数据包不符合令牌桶规范，那么就认为其不合理，此时会做出一下相应：
delay，直到桶准备好 drop mark，标记为不合规的数据包 delay 被称为 整形 shaping , shaping 是指在某个时间间隔内发送超过 Bc（Committed Burst）的大小，Bc 在这里指桶的尺寸。由于数据流量是突发性的，当在一段时间内不活动后，再次激活后的在一个间隔内发送的数量大于 Bc ，那么额外的流量被称为Be （burst excess）。
将流量丢弃或标记超额流量，保持在一个流量速率限制称为 “管制” policing。</description>
    </item>
    <item>
      <title>Kubernetes Pod网络排错思路</title>
      <link>https://www.161616.top/pod-network-troubleshooting/</link>
      <pubDate>Wed, 17 Aug 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/pod-network-troubleshooting/</guid>
      <description>本文是关于深入理解Kubernetes网络原理系列第4章 深入理解Kubernetes Pod网络原理 - 网络名称空间 深入理解Kubernetes Pod网络原理 - Linux虚拟网络技术 深入理解Kubernetes Pod网络原理 - CNI 深入理解Kubernetes Pod网络原理 - 跟随 flannel 学习CNI原理 深入理解Kubernetes Pod网络原理 - 跟随 flannel + multus 剖析 Chained Plugins 深入理解Kubernetes Pod网络原理 - 从零实现一个 CNI Plugin part 1 (Shell) 深入理解Kubernetes Pod网络原理 - 从零实现一个 CNI Plugin part 2 (libcni) 深入理解Kubernetes Pod网络原理 - Kubernetes网络模型 1 深入理解Kubernetes Pod网络原理 - Kubernetes网络模型 2 深入理解Kubernetes Pod网络原理 - Pod网络排错思路 Overview 本文将引入一个思路：“在Kubernetes集群发生网络异常时如何排查”。文章将引入Kubernetes 集群中网络排查的思路，包含网络异常模型，常用工具，并且提出一些案例以供学习。
Pod常见网络异常分类 网络排查工具 Pod网络异常排查思路及流程模型 CNI网络异常排查步骤 案例学习 Pod网络异常 网络异常大概分为如下几类：</description>
    </item>
    <item>
      <title>深入理解Kubernetes Pod网络原理 - Kubernetes网络模型 1</title>
      <link>https://www.161616.top/kubernetes-network-model-part1/</link>
      <pubDate>Wed, 17 Aug 2022 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-network-model-part1/</guid>
      <description>本文是关于深入理解Kubernetes网络原理系列第4章 深入理解Kubernetes Pod网络原理 - 网络名称空间 深入理解Kubernetes Pod网络原理 - Linux虚拟网络技术 深入理解Kubernetes Pod网络原理 - CNI 深入理解Kubernetes Pod网络原理 - 跟随 flannel 学习CNI原理 深入理解Kubernetes Pod网络原理 - 跟随 flannel + multus 剖析 Chained Plugins 深入理解Kubernetes Pod网络原理 - 从零实现一个 CNI Plugin part 1 (Shell) 深入理解Kubernetes Pod网络原理 - 从零实现一个 CNI Plugin part 2 (libcni) 深入理解Kubernetes Pod网络原理 - Kubernetes网络模型 1 深入理解Kubernetes Pod网络原理 - Kubernetes网络模型 2 深入理解Kubernetes Pod网络原理 - Pod网络排错思路 概述 本文将简述探讨 Kubernetes 中常见的网络模型，以及对这些网络模型的 route path 进行分析。本章节是作为CNI 原理的前置条件，也为后续的练习提供一些基础知识。</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>
    <item>
      <title>calico网络策略</title>
      <link>https://www.161616.top/calico-network-policy/</link>
      <pubDate>Mon, 15 Feb 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/calico-network-policy/</guid>
      <description>什么是网络策略 在Kubernetes平台中，要实现零信任网络的安全架构，Calico与istio是在Kubernetes集群中构建零信任网络必不可少的组件。
而建立和维护整个集群中的“零信任网络”中，网络策略的功能在操作上大致可以总结为使用资源配置模板来管理控制平面数据流。说白了讲网络策略就是用来控制Pod间流量的规则。
在Calico中如何编写网络策略 要使用网络策略就需要先了解Calico功能**：NetworkPolicy和GlobalNetworkPolicy**。
NetworkPolicy资源，简称np；是命名空间级别资源。规则应用于与标签选择器匹配的endpoint的集合。
GlobalNetworkPolicy资源，简称 gnp/gnps与NetworkPolicy功能一样，是整个集群级别的资源。
GlobalNetworkPolicy 与 NetworkPolicy资源的管理也与calico的部署方式有关，使用etcd作为存储时，资源的管理只能使用 calicoctl进行管理
NetworkPolicy与GlobalNetworkPolicy的构成 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 apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-tcp-90 spec: selector: app == &amp;#39;envoy&amp;#39; # 应用此策略的endpoint types: # 应用策略的流量方向 - Ingress - Egress ingress: # 入口的流量规则 - action: Allow # 流量的行为 protocol: ICMP # 流量的协议 notProtocol: TCP # 匹配流量协议不为 值 的流量 source: # 流量的来源 src与dst的匹配关系为 与，所有的都生效即生效 nets: # 有效的来源IP selector: # 标签选择器 namespaceSelector: # 名称空间选择器 ports: # 端口 - 80 # 单独端口 - 6040:6050	# 端口范围 destination: # 流量的目标 egress: # 出口的流量规则 - action: Allow serviceAccountSelector: # 使用与此规则的serviceAccount NetworkPolicy使用 实例：允许6379流量可以被 role=frontend的pod访问</description>
    </item>
    <item>
      <title>基于混合云模式的calico部署</title>
      <link>https://www.161616.top/calico-deploy-on-hybrid-cloud/</link>
      <pubDate>Mon, 15 Feb 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/calico-deploy-on-hybrid-cloud/</guid>
      <description>开始前准备 确定calico数据存储
Calico同时支持kubernetes api和etcd数据存储。官方给出的建议是在本地部署中使用K8S API，仅支持Kubernetes模式。而官方给出的etcd则是混合部署（Calico作为Kubernetes和OpenStack的网络插件运行）的最佳数据存储。
使用etcd作为calico数据存储的好处：
允许多平台混用calico，如Kubernetes OpenStack上运行Calico Kubernetes资源与Calico资源分离 一个Calico群集，该群集不仅仅包含一个Kubernetes群集，如可与多个kubernetes集群互通。 坏处：
安装步骤繁琐 无法使用Kubernetes RBAC对calico资源的控制 无法使用Kubernetes资源对calico进行管理 下载calico部署清单 text 1 curl https://docs.projectcalico.org/manifests/calico-etcd.yaml -o calico.yaml 修改Pod CIDR Calico默认的Pod CIDR使用的是192.168.0.0/16，这里一般使用与controller-manager中的--cluster-cidr 保持一,取消资源清单内的 CALICO_IPV4POOL_CIDR变量的注释，并将其设置为与所选Pod CIDR相同的值。
calico的IP分配范围 Calico IPAM从ipPool分配IP地址。修改Pod的默认IP范围则修改清单calico.yaml中的CALICO_IPV4POOL_CIDR
配置Calico的 IP in IP 默认情况下，Calico中的IPIP已经禁用，这里使用的v3.17.2 低版本默认会使用IPIP
要开启IPIP mode则需要修改配置清单内的 CALICO_IPV4POOL_IPIP 环境变量改为 always
修改secret yaml 1 2 3 4 5 6 7 8 9 10 11 # Populate the following with etcd TLS configuration if desired, but leave blank if # not using TLS for etcd.</description>
    </item>
    <item>
      <title>基于Kubernetes的PaaS平台提供dashboard支持的一种方案</title>
      <link>https://www.161616.top/pass-base-dashboard-k8s/</link>
      <pubDate>Thu, 28 Jan 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/pass-base-dashboard-k8s/</guid>
      <description>本文转自博客： 我的小米粥分你一半
我一直在负责维护的PaaS平台引入了Kubernetes作为底层支持, 可以借助Kubernetes的生态做更多的事情, 这篇博客主要介绍如何为用户提供dashboard功能, 以及一些可以扩展的想法. 希望读者有一定的kubernetes使用经验, 并且了解rbac的功能。
Dashboard功能 Kubernetes原生提供了Web界面, 也就是Dashboard, 具体的参考可以见官方文档:
​	安装完成后, 我们一般是通过token来使用的, 不同的token有着不同的权限.
​	上面所说的token是Bearer Token, 除了在界面上输入之外, 你可以这么来用, 通过添加header即可.
text 1 curl -H &amp;#34;Authorization: Bearer ${TOKEN}&amp;#34; https://{dashboard}/api/myresource PaaS平台使用Dashboard简要讨论 需求分析 Dashboard本身的功能是十分强大的, 但是给所有人admin权限显然是不现实的. 对于一个普通用户来讲, PaaS平台的将他的应用(代码)部署好并运行, 他所需要关注的就只有属于他自己的项目, 平台也需要做好权限控制, 避免一个用户操作了另一个用户的应用.
权限系统设计 基于以上的需求讨论, 平台需要做的操作就是为每个用户创建属于自己的权限提供, 并限制可以访问到的资源. 考虑这样的情况:
我们有一个用户A, 他拥有自己的一个应用群组(G), 群组中部署了一系列应用程序(a1, a2…). 在Kubernetes中, 这样的群组概念我们将其映射为namespace, 群组(G) &amp;lt;=&amp;gt; 用户空间(NS), 我们需要控制的权限控制策略就变成了用户A在用户空间NS的权限控制.
token分发策略 拥有了权限控制后, 所需要打就是将token分发给用户, 当然这是一种极度不安全的做法, Kubernetes中的token创建之后一般是不会改变的, 分发这样的token会有很大的安全风险, 有两个方面:
1. 用户A将token保存了下来, 那么他就能不经过平台登录Dashboard, 这样不利于审计工作,2. token一旦泄露, PaaS平台很难做到反应(因为token脱离了平台的控制, 无法判断究竟是什么时候发生了泄露, 也无法马上吊销这个token), 安全风险比较高.</description>
    </item>
    <item>
      <title>calico network cni网络方案</title>
      <link>https://www.161616.top/calico-network-cni/</link>
      <pubDate>Mon, 18 Jan 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/calico-network-cni/</guid>
      <description>Calico针对容器、虚拟机的开源网络和网络安全解决方案。是纯三层的数据中心网络方案。
Calico在每一个计算节点利用Linux Kernel实现了一个高效的虚拟路由器vRouter来负责数据转发，而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息向整个Calico网络内传播。（小规模部署可以直接互联 BGP full mesh，大规模下可通过指定的BGP route reflector来完成）。 这样保证最终所有的workload之间的数据流量都是通过IP路由的方式完成互联的。Calico节点组网可以直接利用数据中心的网络结构（无论是L2或者L3），不需要额外的NAT，隧道或者Overlay Network。
Calico还基于iptables还提供了丰富而灵活的网络Policy，保证通过各个节点上的ACLs来提供Workload的多租户隔离、安全组以及其他可达性限制等功能。
calico组件 在Kubernetes平台之上calico/node容器会通过DaemonSet部署到每个节点，并运行三个守护程序：
Felix：用于管理路由规则，负责状态上报。 BIRD：BGP的客户端，用于将Felix的路由信息加载到内核中，同时负责路由信息在集群中的分发。 confd：用于监视Calico存储（etcd）中的配置变更并更新BIRD的配置文件。 calicoctl使用问题
text 1 Failed to create Calico API client: invalid configuration: no configuration has been provided 默认情况下，calicoctl 将使用位于的默认KUBECONFIG从 Kubernetes APIServer 读取$(HOME)/.kube/config 。
如果默认的 KUBECONFIG 不存在，或者想从指定的存储访问信息，则需要单独配置。
bash 1 2 3 export DATASTORE_TYPE=kubernetes export DATASTORE_TYPE=etcdv3 export KUBECONFIG=~/.kube/config reference for
calico 安装配置 开始前准备
确定calico数据存储
Calico同时支持kubernetes api和etcd数据存储。官方给出的建议是在本地部署中使用K8S API，仅支持Kubernetes模式。而官方给出的etcd则是混合部署（Calico作为Kubernetes和OpenStack的网络插件运行）的最佳数据存储。
使用kubernetes api作为数据存储的安装
text 1 2 curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.</description>
    </item>
    <item>
      <title>网络隧道技术</title>
      <link>https://www.161616.top/network-tunnel-technology/</link>
      <pubDate>Mon, 18 Jan 2021 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/network-tunnel-technology/</guid>
      <description>隧道技术概要 隧道技术（Tunneling）是网络基础设置在网络之间传递数据的方式，使用隧道技术传递可以是不同协议的数据包，隧道协议将这些其他协议的数据包重新封装在新的包头中发送。被封装的数据包在隧道的两个端点之间通过网络进行路由，被封装数据包在网络上传递时所经历的逻辑路径称为隧道。
简单来说，隧道技术是一类网络协议，是将一个数据包封装在另一个数据包中进行传输的技术；**使用隧道的原因是在不兼容的网络上传输数据，或在不安全网络上提供一个安全路径。**通过网络隧道技术，可以使隧道两端的网络组成一个更大的内部网络。（把不支持的协议数据包打包成支持的协议数据包之后进行传输）。
隧道协议 要创建隧道，隧道的客户机和服务器双方必须使用相同的隧道技术，隧道协议有二层隧道协议与三层隧道协议两类。
二层隧道协议对应OSI模型中数据链路层，使用 帧 作为数据交换单位，PPTP、L2TP、L2F都属于二层隧道协议。是将数据封装在点对点协议的帧中通过互联网络发送。
三层隧道协议对应OSI模型中网络层，使用 包 作为数据交换单位，GRE、IPSec 都属于三层隧道协议。都是数据包封装在附加的IP包头中通过IP网络传送。
在例如VxLAN，工作在传输层和网络层之间。具体来说，将运行在用户数据报协议 (UDP) 和网络数据报协议 (IP) 之间，以便在网络中建立安全的通信通道。
网络隧道技术应用 隧道在Linux 中应用 IP隧道是指一种可在两网络间进行通信的通道。在该通道里，会先封装其他网络协议的数据包，之后再传输信息。
Linux原生共支持5种IPIP隧道：
ipip: 普通的IPIP隧道，就是在报文的基础上再封装成一个IPv4报文 gre: 通用路由封装（Generic Routing Encapsulation），定义了在任意一种网络层协议上封装其他任意一种网络层协议的机制，所以对于IPv4和IPv6都适用 sit: sit模式主要用于IPv4报文封装IPv6报文，即IPv6 over IPv4 isatap: 站内自动隧道寻址协议（Intra-Site Automatic Tunnel Addressing Protocol），类似于sit也是用于IPv6的隧道封装 vti: 即虚拟隧道接口（Virtual Tunnel Interface），是一种IPsec隧道技术 像IPVS/LVS中的 Virtual Server via IP Tunneling，就是使用了IPIP隧道
SSH隧道技术 SSH提供了一个重要功能，称为转发 forwarding 或者称为隧道传输tunneling，它可以通过加密频道将明文流量导入隧道中，在创建SSH隧道时， SSH客户端要设置并转交一个特定本地端口号到远程机器上；一旦SSH隧道创建，用户可以连到指定的本地端口号以访问网络服务。本地端口号不用与远地端口号一样。
SSH隧道主要使用场景一般为 规避防火墙、加密网络流量
规避防火墙，SSH隧道可以使一个被防火墙阻挡的协议可被包在另一个没被防火墙阻挡的协议里，这技巧可用来逃避防火墙政策。而这种操作符合“数据包封装在另一个数据包中进行传输的技术”，故称为SSH隧道技术。
SSH隧道类型 在ssh连接的基础上，指定 ssh client 或 ssh server 的某个端口作为源地址，所有发至该端口的数据包都会透过ssh连接被转发出去；至于转发的目标地址，目标地址既可以指定，也可以不指定，如果指定了目标地址，称为定向转发，如果不指定目标地址则称为动态转发：
定向转发
定向转发把数据包转发到指定的目标地址。目标地址不限定是ssh client 或 ssh server，既可以是二者之一，也可以是二者以外的其他机器。</description>
    </item>
    <item>
      <title>Kubernetes包管理 - Helm</title>
      <link>https://www.161616.top/helm/</link>
      <pubDate>Wed, 27 Nov 2019 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/helm/</guid>
      <description>什么是 Helm Helm 是一个用于管理 Kubernetes 应用程序的包管理工具。它允许您定义、安装和升级 Kubernetes 应用程序，以简化应用程序部署和管理的过程。
在 Kubernetes 中，应用程序被打包为一个或多个称为 &amp;ldquo;Charts&amp;rdquo; 的 Helm 资源。一个 Chart 是一个预定义的目录结构，包含了用于部署应用程序的 Kubernetes 资源清单模板。Chart 可以包含 Deployment、Service、ConfigMap、Ingress 等 Kubernetes 资源的定义。
使用 Helm，您可以将应用程序打包为一个 Chart，并使用 Helm 客户端来安装和管理 Chart。这使得应用程序的部署过程更加简单、可重复和可扩展。您可以根据需要部署多个实例，轻松地进行升级和回滚操作，并使用 Helm 提供的值覆盖机制来自定义每个实例的配置。
最重要的是，Helm 支持使用 Helm 仓库来共享和发布 Charts。Helm 仓库是一个集中存储 Charts 的地方，供用户从中搜索和安装 Charts。Helm 仓库可以是公共的，也可以是私有的，您可以自己搭建私有仓库来管理自己的 Charts。
Helm 所作的事情 Helm 管理名为 chart 的Kubernetes包的工具。故 Helm 可以做以下的事情：
创建一个新的 chart 将 chart 打包成归档 (tgz) 文件 与存储 chart 的仓库进行交互 在现有的 Kubernetes 集群中安装和卸载 chart 管理与Helm一起安装的 chart 的发布周期 Helm中的术语 chart：类似于rpm包，deb包，包含Kubernetes资源所需要的必要信息。 repo：chart仓库，类似于yum的仓库，chart仓库是一个简单的HTTP服务。 values：提供了自定义信息用来覆盖模板中的默认值。 release ：chart安装后的版本记录。 Helm 与 YAML 资源清单比有什么优势？ 模板化和参数化: Helm 使用 Go 的模板引擎来创建 Kubernetes 资源清单。这使得您可以在 Chart 中使用模板来定义资源配置的部分内容，例如标签、名称、端口等。同时，Helm 还支持使用参数化的值，允许您根据不同的环境或需求来自定义 Chart 的配置。这样一来，您可以根据需要生成不同的 Kubernetes 资源清单，而无需手动编辑每个清单文件。 可重用性: Helm 提供了一种将应用程序打包为 Chart 的方式，可以将 Chart 存储在 Helm 仓库中进行共享和重用。这样，您可以使用其他人创建的 Charts 来快速部署常见的应用程序，避免从头开始编写和管理 Kubernetes 资源清单。同时，您也可以将自己的应用程序打包为 Chart，方便自己和团队在不同环境中部署和管理。 版本管理和升级: 使用 Helm，您可以对已安装的 Chart 进行版本管理和升级。当应用程序的配置或代码发生变化时，您可以通过升级 Chart 来自动应用这些更改，而无需手动修改和重新部署 Kubernetes 资源清单。Helm 还提供了回滚功能，允许您在升级出现问题时快速回退到之前的版本。 依赖管理: Helm 允许您在 Chart 中定义和管理依赖关系。这意味着您可以在部署应用程序时自动解析和安装它所依赖的其他 Charts。这样，您可以轻松地管理应用程序所需的其他资源，减少手动处理依赖关系的工作。 部署的一致性和标准化: Helm 提供了一种标准的部署方式，使得不同团队或开发者之间可以使用相同的工具和流程来管理应用程序的部署。这样可以确保在不同环境中的一致性，并降低由于不同部署方式导致的错误和配置差异。 可管理的 Charts: Helm Charts 是可管理的，您可以在 Chart 中定义预先配置的模板、默认值、钩子和配置验证。这使得管理应用程序的配置和部署过程更加灵活和可控。 社区支持和生态系统: Helm 是一个活跃的开源项目，拥有庞大的用户社区和丰富的生态系统。这意味着您可以轻松地找到文档、示例、教程和问题解答，并从社区中获取支持和贡献。 可扩展性和插件支持: Helm 提供了插件机制，允许您扩展 Helm 的功能。您可以使用插件来添加自定义的命令、功能和工作流程，以满足特定需求或自动化常见的任务。 可视化界面和用户友好性: Helm 可以与各种第三方工具和平台集成，提供可视化界面和用户友好的操作方式。这使得非技术人员或不熟悉命令行的开发人员也能够方便地部署和管理应用程序。 安装helm Helm 安装主要官方提供了几种安装方式</description>
    </item>
    <item>
      <title>kubernetes应用 - Traefik Ingress Controller</title>
      <link>https://www.161616.top/traefik-ingresscontroller/</link>
      <pubDate>Wed, 23 Oct 2019 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/traefik-ingresscontroller/</guid>
      <description>Kubernetes Ingress Kubernetes Ingress是路由规则的集合，这些规则控制外部用户如何访问Kubernetes集群中运行的服务。
在Kubernetes中，有三种方式可以使内部Pod公开访问。
NodePort：使用Kubernetes Pod的NodePort，将Pod内应用程序公开到每个节点上的端口上。 Service LoadBalancer：使用Kubernetes Service，改功能会创建一个外部负载均衡器，使流量转向集群中的Kubernetes Pod。 Ingress Controller： Node Port是在Kubernetes集群中每个节点（Node）上开放端口，Kubernetes直接将流量转向集群中Pod。Kubernetes集群中使用NodePort，则需要编辑防火墙规则，但是NodePort是范围在Kubernetes集群中默认设置的范围为 30000–32767，最终导致流量端口暴露在非标准端口之上。
LoadBalancer一般应用于云厂商提供的Kubernetes服务，如果自行在机器上部署Kubernetes集群，则需要自行配置LoadBalancer的实现，
Kubernetes Ingress，为Kubernetes中的抽象概念，实现为第三方代理实现，这种三方实现集合统称为Ingress Controller。Ingress Controller负责引入外部流量并将流量处理并转向对应的服务。
Kubernetes IngressController功能实现 上面只是说道，在Kubernetes集群中，如何将外部流量引入到Kubernetes集群服务中。
负载均衡 无论在Kubernetes集群中，无论采用什么方式进行流量引入，都需要在外部负载均衡完成，而后负载均衡将流量引入Kubernetes集群入口或内部中，
通常情况下，NodePort方式管理繁琐，一般不用于生产环境。
服务的Ingress选择 Kubernetes Ingress是选择正确的方法来管理引入外部流量到服务内部。一般选择也是具有多样性的。
Nginx Ingress Controller，Kubernetes默认推荐的Ingress，弊端①最终配置加载依赖config reload，②定制化开发较难，配置基本来源于config file。 Envoy &amp;amp; traefik api网关，支持tcp/udp/grpc/ws等多协议，支持流量控制，可观测性，多配置提供者。 云厂商提供的Ingress。AWS ALB，GCP GLBG/GCE，Azure AGIC Traefik介绍 traefik-现代反向代理，也可称为现代边缘路由；traefik原声兼容主流集群，Kubernetes，Docker，AWS等。官方的定位traefik是一个让开发人员将时间花费在系统研发与部署功能上，而非配置和维护。并且traefik官方也提供自己的服务网格解决方案
作为一个 modern edge router ，traefik拥有与envoy相似的特性
基于go语言研发，目的是为了简化开发人员的配置和维护 tcp/udp支持 http L7支持 GRPC支持 服务发现和动态配置 front/ edge prory支持 可观测性 流量管理 &amp;hellip; traefik 术语 要了解trafik，首先需要先了解一下 有关trafik中的一些术语。
EntryPoints 入口点，是可以被下游客户端连接的命名网络位置，类似于envoy 的listener和nginx的listen services 服务，负载均衡，上游主机接收来自traefik的连接和请求并返回响应。 类似于nginx upstream envoy的clusters Providers 提供者，提供配置文件的后端，如file，kubernetes，consul，redis，etcd等，可使traefik自动更新 routers 路由器，承上启下，分析请求，将下游主机的请求处理转入到services middlewares: 中间件，在将下游主机的请求转入到services时进行的流量调整 在Kubernetes中使用traefik网关作为Ingress Traefik于2019年9月发布2.</description>
    </item>
    <item>
      <title>使用二进制文件构建k8s集群</title>
      <link>https://www.161616.top/kubernetes-install-with-binary-files/</link>
      <pubDate>Sun, 20 Jan 2019 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-install-with-binary-files/</guid>
      <description>Kubernetes集群的构成 Master Node (Control plane) Master 是整个 Kubernetes 集群构成的基础，它负责整个集群的管理，例如处理集群的状态；组件包含 API Server, Controller manager, Scheduller, Etcd
API server API 服务器是 Master 的统一前端入口，负责集群内其他组件的 协调 与 通信。该组件用于定义集群的状态。可以通过命令行, HTTP API, 第三方托管平台（dashboard, Rancker, Kuboard等）与 Kubernetes API 进行交互。
Scheduler 调度程序 Scheduler 负责根据可用资源来决定如何去部署容器，部署到哪里？确保所有 Pod（容器组）都分配给某一组节点。
Controller Manager Controller manager，又分为Controller 和 Manager，Controller的组要作用是用于协调各种控制器(Deployment, Daemonset&amp;hellip;)，这些控制器可确保在节点发生故障时采取适当的措施。而 Manager 则管理的众多Controller；更一般地说，CM 负责随时将集群的当前状态调整到所需状态（Kubernetes设计基石）。
etcd etcd 是控制平面内的一个组件，他提供了 Kubernetes 资源的存储，并为集群内组件提供了 Watch 的功能，这将意味着，etcd 在 kubernetes 集群中作为存储与分布式协调的功能。
Worker nodes 每个集群中至少需要存在一个工作节点，但是通常会有大量的节点；而工作节点包括的组件不限于 Kubelet, Kube-proxy, CNI Plugin。
Kubelet kubelet是工作节点中管理运行时的组件，负责整个Pod （容器组）进程的生命周期
Kube-proxy Kube-proxy 为整个集群内提供了 service 的功能，如果这个组件无法正常工作，那么整个集群内的网络通信将不能正常，因为 service 是作为集群内服务的访问入口，包含 Kubernetes API service。</description>
    </item>
    <item>
      <title>etcd二进制安装与配置</title>
      <link>https://www.161616.top/etcd-install-bin/</link>
      <pubDate>Tue, 20 Nov 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/etcd-install-bin/</guid>
      <description>概述 etcd 是兼具一致性和高可用性的键值数据库，为云原生架构中重要的基础组件，由CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现，还可以作为 key-value 存储的中间件。
先决条件 运行的 etcd 集群个数成员为奇数。 etcd 是一个 leader-based 分布式系统。确保主节点定期向所有从节点发送心跳，以保持集群稳定。 保持稳定的 etcd 集群对 Kubernetes 集群的稳定性至关重要。因此，请在专用机器或隔离环境上运行 etcd 集群，以满足所需资源需求]。 确保不发生资源不足。
集群的性能和稳定性对网络和磁盘 IO 非常敏感。任何资源匮乏都会导致心跳超时，从而导致集群的不稳定。不稳定的情况表明没有选出任何主节点。在这种情况下，集群不能对其当前状态进行任何更改，这意味着不能调度新的 pod。 相关术语 Raft：etcd所采用的保证分布式系统强一致性的算法。 Node：节点 ，Raft状态机的一个实例，具有唯一标识。 Member： 成员，一个etcd实例。承载一个Node，且可为客户端请求提供服务。 Cluster：集群，由多个Member构成可以协同工作的etcd集群。 Peer：同伴，Cluster中其他成员。 Proposal ：提议，一个需要完成 raft 协议的请求(例如写请求，配置修改请求)。 Client： 向etcd集群发送HTTP请求的客户端。 WAL：预写式日志，etcd用于持久化存储的日志格式。 snapshot：etcd防止WAL文件过多而设置的快照，存储etcd数据状态。 Proxy：etcd的一种模式，为etcd集群提供反向代理服务。 Leader：Raft算法中通过竞选而产生的处理所有数据提交的节点。 Follower：竞选失败的节点作为Raft中的从属节点，为算法提供强一致性保证。 Candidate：当Follower超过一定时间接收不到Leader的心跳时转变为Candidate开始竞选。 Term：某个节点成为Leader到下一次竞选时间，称为Ubuntu一个Term。 Index：数据项编号。Raft中通过Term和Index来定位数据。 ETCD 部署 源码安装 基于master分支构建etcd
bash 1 2 3 git clone https://github.com/etcd-io/etcd.git cd etcd ./build # 如脚本格式为dos的，需要将其格式修改为unix，否则报错。 启动命令
--listen-client-urls 于 --listen-peer-urls 不能为域名</description>
    </item>
    <item>
      <title>Kubernetes存储卷</title>
      <link>https://www.161616.top/k8s-volumes/</link>
      <pubDate>Sun, 30 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/k8s-volumes/</guid>
      <description>在Kubernetes之上，在节点级提供一个存储卷的方式来持久存储数据的逻辑，这种只具备一定程度上的持久性。为了实现更强大的持久性，应该使用脱离节点而存在的共享存储设备。 为此Kubernetes提供了不同类型的存储卷。
大多数和数据存储服务相关的应用，和有状态应用几乎都是需要持久存储数据的。容器本身是有生命周期的，为了使容器终结后可以将其删除，或者编排至其他节点上去运行。意味着数据不能存储在容器本地。一旦Pod故障就会触发重构。如果将数据放置在Pod自有的容器内名称空间中，数据随着Pod终结而结束。为了突破Pod生命周期的限制，需要将数据放置在Pod自有文件系统之外的地方。
存储卷
对Kubernetes来讲，存储卷不属于容器，而属于Pod。因此，在Kubernetes中同一个Pod内的多个容器可共享访问同一组存储卷。
Pod底部有一个基础容器， ==pause==，但是不会启动。pause是基础架构容器。创建Pod时pause时Pod的根，所有Pod，包括网络命名空间等分配都是分配给pause的。在Pod中运行的容器是pause的网络名称空间的。容器在挂载存储卷时，实际上是复制pause的存储卷。
因此为了真的实现持久性，存储卷应为宿主机挂载的外部存储设备的存储卷。如果需要实现跨节点持久，一般而言需要使用脱离节点本地的网络存储设备（ceph、glusterfs、nfs）来实现。节点如果需要使用此种存储的话，需要可以驱动相应存储设备才可以（在节点级可以访问相应网络存储设备）。
k8s之上可使用的存储卷 Kubernetes支持的存储卷类型
empryDir：只在节点本地使用的，用于做临时目录，或当缓存使用。一旦Pod删除，存储卷一并被删除。empryDir背后关联的宿主机目录可以使宿主机的内存。 hostPath：使宿主机目录与容器建立关联关系。 网络存储 传统的SAN（iSCSI，FC）NAS（常见用法协议 NFS,cifs,http）设备所构建的网络存储设备。 分布式存储（分机系统或块级别），glusterfs，ceph(rbd ceph的块接口存储)，cephfs等。 云存储：EBS（弹性块存储）亚马逊 ,Azure Disk 微软。此模型只适用于Kubernetes集群托管在其公有云之上的场景。 使用kubectl explain pod.spec.volumes查看Kubernetes所支持的存储类型。
emptyDir 语法
emptyDir medium 媒介类型 empty string （disk 默认） or memory sizeLimit 空间上限 定义完存储卷之后，需要在container当中使用volumeMounts指明挂载哪个或哪些个存储卷
yaml 1 2 3 4 5 - container - mountPath 挂载路径 - name 挂载那个卷 - readOnly 是否只读挂载 - subPath 是否挂载子路径之下 yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 apiVersion: v1 kind: Pod metadata: name: my-nginx namespace: default spec: containers: - name: busybox image: busybox imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 command: [&amp;#34;tail&amp;#34;] volumeMounts: # 指明挂载哪一个存储卷 - name: html mountPath: /data/web/html # 指明挂载到容器的哪个路径下 volumes: - name: html emptyDir: {} # 表示空映射，都使用默认值，大小不限制，使用磁盘空间，而不是不定义 在Kubernetes中 $()是变量引用</description>
    </item>
    <item>
      <title>kubernetes概念 - configMap</title>
      <link>https://www.161616.top/k8s-cm/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/k8s-cm/</guid>
      <description>secret、configMap特殊类型的存储卷，多数情况下不是为Pod提供存储空间来用的，而是给管理员或用户提供了从集群外部向Pod内部应用注入配置信息的方式。
工作实现
configMap 在集群内部存在一个名称空间，在名称空间当中拥有一个可正常运行的Pod，当镜像启动时使用的配置文件在做镜像之前就确定了，并且做完镜像就不能修改了。除非在做镜像时使用entryPoint脚本去接受用户启动容器时传入环境变量进来，将环境变量的数据替换到配置文件中去，从而使应用程序在启动之前就能获得一个新的配置文件而后得到新的配置。当需要修改配置文件时是很麻烦的。而配置中心只需将集中的配置文件修改，并通知给相应进程，让其重载配置文件。而Kubernetes的应用也存在此类问题，当配置文件修改后就需要更新整个镜像。因此无需将配置信息写死在镜像中。而是引入一个新的资源，这个资源甚至是整个Kubernetes集群上的一等公民（标准的K8S资源）。这个资源被叫做configMap
configMap当中存放的配置信息，随后启动每一个Pod时，Pod可以共享使用同一个configMap资源，这个资源对象可以当存储卷来使用，也可以从中基于环境变量方式从中获取到一些数据传递给环境变量，注入到容器中去使用。 因此configMap扮演了Kubernetes中的配置中心的功能。但是configMap是明文存储数据的。因此和configMap拥有同样功能的标准资源secret就诞生了。与configMap所不同之处在于，secret中存放的数据是用过编码机制进行存放的。
核心作用：让配置信息从镜像中解耦，从而增强应用的可移植性与复用性。使一个镜像文件可以为应用程序运行不同配置的环境而工作。简单来讲，一个configMap就是一系列配置数据的集合。这些数据可以注入到Pod对象中的容器所使用。
在configMap中，所有的配置信息都保存为key value格式。V只是代表了一段配置信息，可能是一个配置参数，或整个配置文件信息都是没有问题的。
配置容器化应用的方式
自定义命令行参数 args [] 把配置文件直接陪进镜像； 环境变量 Cloud Native的应用程序一般可直接通过环境变量加载配置 通过entrypoint脚本来预处理变量为配置文件中的配置信息。 存储卷 配置文件注入方式：
将configMap做存储卷 使用env docker config
contioners env name 变量名 value 变量值 valueFrom 数据不是一个字符串，而是引用另外一个对象将其传递给这个变量。 configMapKeyRef configMap中的某个键 fieldRef 某个字段。此资源可以是Pod自身的字段。如metadata.labels status.hostIP status.podIP resourceFieldRef 资源需求和资源限制。 secreKeyRef 引用secre configMap无需复杂描述，因此没有spec字段
text 1 2 3 4 apiVersion kind data binaryData 一般情况下data与binaryData只使用其中一种。 创建简单的configMap还可以使用 kubectl create configMap来创建。如需要长期使用，可以定义为配置清单文件。
text 1 2 3 kubectl create configmap nginx-config \ --from-literal=nginx_port=80 \ --from-literal=servername=test.com 使用文件创建</description>
    </item>
    <item>
      <title>kubernetes概念 - Dashboard</title>
      <link>https://www.161616.top/k8s-dashboard/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/k8s-dashboard/</guid>
      <description>基于web的UI前端，认证是由Kubernetes完成的。登陆dashboard的密码是k8s的账号和密码，和dashboard自身没有关系。dashboard自身不做认证。
text 1 kubectl patch svc kubernetes-dashboard -p&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;type&amp;#34;:&amp;#34;NodePort&amp;#34;}}&amp;#39;-n kube-system 如使用域名访问，CN一定要与域名保持一致。
text 1 2 3 4 (umask 077; openssl genrsa -out dashboard.key 2048) openssl req -new -key dashboard.key -out dashboard.csr -subj &amp;#34;/O=test/CN=dashboard&amp;#34; openssl req -in dashboard.csr -noout -text openssl x509 -req -in dashboard.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out dashboard.crt -days 3650 Certificate Attributes
要想穿透集群边界，从集群外访问集群内部某一服务或Pod上的容器的应用，有两种方式 nodePort、NodeBlanc 或ingress
text 1 2 3 4 5 kubectl create secret generic \ dashboard-cert \ -n kube-system \ --from-file=dashboard.</description>
    </item>
    <item>
      <title>kubernetes概念 - ingress</title>
      <link>https://www.161616.top/k8s-ingress/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/k8s-ingress/</guid>
      <description>IngressController比较独特，它与DaemonSet、Deployment、Repliacaset不同，DaemonSet、Deployment等控制器是作为ControllerManager的子组件存在的。Ingress Controller是独立运行的一组Pod资源，通常是拥有七层代理、调度能力的应用程序。
通常在使用IngressController时有三种选择Nginx、Traefik、Envoy。
IngressController nginx运行在Pod中，其配置文件是在Pod中。后端代理的Pod随时会发生变动，IngressController需要watch API当中的后端Pod资源的改变。IngressController自身无法识别目前符合自己关联的（条件的）被代理的Pod资源有哪些，IngressController需借助service来实现。
因此要想定义一个对应的调度功能，还需要创建service，此service通过label selector关联至每一个upstream服务器组，通过此service资源关联至后端的Pod。此service不会被当做被代理时的中间节点，它仅仅是为Pod做分类的。此service关联的Pod，就将其写入upstream中。
在Kubernetes中有一种特殊资源叫做Ingress，当Pod发生改变时，其servcie对应的资源也会发生改变， 依赖于IngressResource将变化结果反应至配置文件中。
Ingress定义期望IngressController如何创建前段代理资源（虚拟主机、Url路由映射），同时定义后端池（upstream）。upstream中的列表数量，是通过service获得。
Ingress可以通过编辑注入到IngressController中，并保存为配置文件，且Ingress发现service选定的后端Pod资源发生改变，此改变会及时反映至Ingress中，Ingress将其注入到前端调度器Pod中，并触发Pod中的container主进程（nginx）重载配置文件。
要想使用Ingress功能，需要有service对某些后端资源进行分类，而后Ingress通过分类识别出Pod的数量和IP地址信息，并将反映结果生成配置信息注入到upstream中。
IngressController根据自身需求方式来定义前端，而后根据servcie收集到的后端Pod IP定义成upstream server，将这些信息反映在Ingress server当中，由Ingress动态注入到IngressController当中。
Ingress也是标准的Kubernetes资源，定义Ingress时同样类似于Pod方式来定义。使用kubectl explain Ingress查看帮助。
spec rules 规则，对象列表 host 主机调度 虚拟主机而非url映射 http paths 路径调度 backend path backend 定义被调度的后端主机，靠service定义，找到后端相关联的Pod资源。 serviceName 后端servcie名称，即用来关联Pod资源的service。 servicePort IngressController部署
namespace.yaml 创建名称空间 configmap.yaml 为nginx从外部注入配置的 rbac.yaml 定义集群角色、授权。必要时让IngressController拥有访问他本身到达不了的名称空间的权限
ingress.yaml
yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-myapp namespace: defualt # 与deployment和要发布的service处在同一名称空间内 annotations: kubernetes.</description>
    </item>
    <item>
      <title>kubernetes概念 - Kubenetes Deployment</title>
      <link>https://www.161616.top/kubenetes-deployment/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubenetes-deployment/</guid>
      <description>Deployment当中借助于ReplicaSet进行更新的策略反映在Deployment的对象定义所需字段可使用kubectl explain deploy，Deployment属于extension群组。在1.10版本中它被移至到apps群组。他与ReplicaSet相比增加了几个字段。
stratgy 重要字段，定义更新策略，它支持两种策略 重建式更新 Recreate与滚动更新RollingUpdate，如果type为RollingUpdate，那么RollingUpdate的策略还可以使用RollingUpdate来定义，如果type为Recreate，那么RollingUpdate字段无效。 默认值为RollingUpdate
stratgy.RollingUpdate控制RollingUpdate更新力度
maxSurge 对应的更新过程当中，最多能超出目标副本数几个。有两种取值方式，为直接指定数量和百分比。在使用百分比时，在计算数据时如果不足1会补位1个。 maxUnavailable 最多有几个副本不可用。 revisionHistoryLimit 滚动更新后，在历史当中最多保留几个历史版本，默认10。
在使用Deployment创建Pod时，Deployment会自动创建ReplicaSet，而且Deployment名称是使用Pod模板的hash值，此值是固定的。
Deployment在实现更新应用时，可以通过编辑配置文件来实现，使用kubectl apply -f更改每次变化。每次的变化通过吧变化同步至apiserver中，apiserver发现其状态与etcd不同，从而改变etcd值来实现修改其期望状态，来实现现有状态去逼近期望状态。
kubectl explain deploy
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 apiVersion: apps/v1 kind: Deployment metadata: name: app-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: deploy release: canary template: metadata: labels: app: deploy release: canary spec: containers: - name: my-deploy image: node01:5000/busybox:v1 ports: - name: http containerPort: 80 command: [&amp;#34;/bin/sh&amp;#34;,&amp;#34;-c&amp;#34;,&amp;#34;/bin/httpd -f -h /tmp&amp;#34;] 使用kubectl apply 声明式更新、创建资源对象。</description>
    </item>
    <item>
      <title>kubernetes概念 - Kubernetes Pod控制器</title>
      <link>https://www.161616.top/kubernetes-pod-controller/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-pod-controller/</guid>
      <description>Kubernetes资源清单 类别 名称 工作负载型资源（workload） 运行应用程序，对外提供服务：Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、Cronjob （ReplicationController在v1.11版本被废弃） 服务发现及负载均衡 service、Ingress 配置与存储 Volume、CSI（容器存储接口 特殊类型存储卷 ConfigMap（当配置中心来使用的资源类型）、Secret（保存敏感数据）、DownwardAPI（把外部环境中的信息输出给容器） 集群级资源 Namespace、Node、Role、ClusterRole、RoleBinding（角色绑定）、ClusterRoleBinding（集群角色绑定） 元数据型资源 HPA、PodTemplate（Pod模板，用于让控制器创建Pod时使用的模板）、LimitRange（用来定义硬件资源限制的） Kubernetes配置清单使用说明 在Kubernetes中创建资源时，除了命令式创建方式，还可以使用yaml格式的文件来创建符合我们预期期望的pod，这样的yaml文件我们一般称为资源清单。资源清单由很多属性或字段所组成。
以yawl格式输出pod的详细信息。
资源清单格式 yaml 1 kubectl get pod clients -o yaml Pod资源清单常用字段讲解 在创建资源时，apiserver仅接收JSON格式的资源定义。在使用kubectl run命令时，自动将给定内容转换成JSON格式。yaml格式提供配置清单，apiserver可自动将其转为JSON格式，（yaml可无损转为json），而后再提交。使用资源配置请清单可带来复用效果。
Pod资源配置清单由五个一级字段组成，通过kubectl create -f yamlfile就可以创建一个Pod
apiVersion: 说明对应的对象属于Kubernetes的哪一个API群组名称和版本。给定apiVersion时由两部分组成group/version，group如果省略表示core（核心组）之意。使用kubectl api-versions获得当前系统所支持的apiserver版本。alpha 内测版、beta 公测版、stable 稳定版
kind: 资源类别，用来指明哪种资源用来初始化成资源对象时使用。
metadata: 元数据，内部嵌套很多2级、3级字段。主要提供以下几个字段。
name，在同一类别当中name必须是唯一的。
namespace 对应的对象属于哪个名称空间，name受限于namespace，不同的namespace中name可以重名。
lables key-value数据，对于key名称及value，最多为63个字符，value，可为空。填写时只能使用字母、数字、_、-、.，只能以字母或数字开头及结尾。
annotations 资源注解。与label不同的地方在于，它不能用于挑选资源对象，仅用于为对象提供“元数据”。对键值长度没有要求。在构建大型镜像时通常会用其标记对应的资源对象的元数据
spec: specification，定义接下来创建的资源对象应该满足的规范（期望的状态 disired state）。spec是用户定义的。不同的资源类型，其所需要嵌套的字段各不相同。如果某一字段属性标记为required表示为必选字段，剩余的都为可选字段，系统会赋予其默认值。如果某一字段标记为Cannot be updated，则表示为对象一旦创建后不能改变字段值。可使用kubectl explain pods.spec查看详情。
containers [required]object list
name [string] 定义容器名称
image [string] 启动Pod内嵌容器时所使用的镜像。可是顶级、私有、第三方仓库镜像。
imagePulLPolicy [string] 镜像获取的策略，可选参数Always（总是从仓库下载，无论本地有无此镜像）、Never（从不下载，无论本地有无此镜像）、IfNotPresent（本地存在则使用，不存在则从仓库拉去镜像）。如果tag设置为latest，默认值则为Always，非latest标签，默认值都为IfNotPresent。</description>
    </item>
    <item>
      <title>kubernetes概念 - kubernetes调度</title>
      <link>https://www.161616.top/kubernetes-schedule/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-schedule/</guid>
      <description>Overview kube-scheduler 是kubernetes控制平面的核心组件，其默认行为是将 pod 分配给节点，同时平衡Pod与Node间的资源利用率。通俗来讲就是 kube-scheduler 在运行在控制平面，并将工作负载分配给 Kubernetes 集群。
本文将深入 Kubernetes 调度的使用，包含：”一般调度”，”亲和度“，“污点与容忍的调度驱逐”。最后会分析下 Scheduler Performance Tuning，即微调scheduler的参数来适应集群。
简单的调度 NodeName [1] 最简单的调度可以指定一个 NodeName 字段，使Pod可以运行在对应的节点上。如下列资源清单所示
yaml 1 2 3 4 5 6 7 8 9 apiVersion: v1 kind: Pod metadata: name: netpod spec: containers: - name: netbox image: cylonchau/netbox nodeName: node01 通过上面的资源清单Pod最终会在 node01上运行。这种情况下也会存在很多的弊端，如资源节点不足，未知的nodename都会影响到Pod的正常工作，通常情况下，这种方式是不推荐的。
bash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $ kubectl describe pods netpod Name: netpod Namespace: default .</description>
    </item>
    <item>
      <title>kubernetes概念 - Service</title>
      <link>https://www.161616.top/kubernetes-service/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-service/</guid>
      <description>在Kubernetes集群中，Pod是有生命周期的，为了能够给对应的客户端提供一个固定访问端点，因此在客户端与服务端（Pod之间）添加了一个固定中间层，这个中间层被称之为Service。Service的工作严重依赖于在Kubernetes集群之上，部署的附件Kubernetes DNS服务。较新版本使用的coreDNS，1.11之前使用的KubeDNS。
service的名称解析是强依赖于DNS附件的。因此在部署完Kubernetes后，需要部署CoreDNS或KubeDNS。 Kubernetes要想向客户端提供网络功能，依赖于第三方方案，在较新版本中，可通过CNI容器网络插件标准接口，来接入任何遵循插件标准的第三方方案。 Service从一定程度上来说，在每个节点之上都工作有一个组件Kube-proxy，Kube-proxy将始终监视apiserver当中，有关service资源的变动状态。此过程是通过Kubernetes中固有的请求方法watch来实现的。一旦有service资源的内容发生变动，kube-proxy都将其转换为当前节点之上的能够实现service资源调度至特定Pod之上的规则。
service实现方式 在Kubernetes中service的实现方式有三种模型。
userspace 用户空间，可以理解为，用户的请求。 1.1之前包括1.1使用此模型。 用户的请求到达当前节点的内核空间的iptables规则（service规则），由service转发至本地监听的某个套接字上的用户空间的kube-proxy，kube-proxy在处理完再转发给service，最终代理至service相关联的各个Pod，实现调度。
iptables 1.10- 客户端IP请求时，直接请求serviceIP，IP为本地内核空间中的service规则所截取，并直接调度至相关Pod。service工作在内核空间，由iptables直接调度。
ipvs 1.11默认使用，如IPVS没有激活，默认降级为iptables 客户端请求到达内核空间后，直接由ipvs规则直接调度至Pod网络地址范围内的相关Pod资源。
使用清单创建service资源 SVC中的kubernetes service是集群中各Pod需要与Kubernetes集群apiserver联系时需要通过此svc地址联系。这个地址是集群内的apiserver服务地址。
service类型 ClusterIP 默认值，表示分配集群IP地址，仅用于集群内通信。自动分配地址，如需固定，需要指定相应地址，在创建后无法修改。当使用ClusterIP时，只有两个端口有用，port与targetPort
NodePort 接入集群外部流量，默认分配的端口是30000~32767
LoadBalancer 表示将Kubernetes部署在虚拟机上，虚拟机是工作在云环境中，云环境支持lbaas（负载均衡及服务的一键调用）。
ExternaName 表示将集群外部服务引用到集群内部中来，在集群内部直接使用。
yaml 1 2 3 4 5 6 7 8 9 10 11 12 spec: ports: # 将哪个端口与后端容器端口建立关联关系。 - port # service对外提供服务的端口 name 指明port的名称 targetPort # 容器的端口 nodePort # 只有类型为NodePort时，才有必要用节点端口，否则此选项是无用的。 protocol 协议，默认TCP seletcor 关联到哪些Pod资源上 app: redis run: redis clusterIP: # clusterIP可以动态分贝可以不配置 type: ClusterIP yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: v1 kind: Service metadata: name: redis namespace: default spec: selector: run: redis clusterIP: 10.</description>
    </item>
    <item>
      <title>kubernetes概念 - serviceaccount</title>
      <link>https://www.161616.top/kubernetes-serviceaccount/</link>
      <pubDate>Fri, 28 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-serviceaccount/</guid>
      <description>在整个Kubernetes集群来讲 apiserver是访问控制的唯一入口。如通过service或ingress暴露之后，是可以不通过apiserver接入的，只需要通过节点的nodePort或者ingress controller daemonset共享宿主机节点网络名称空间监听的宿主机网络地址（节点地址），直接接入。
当请求到达APIServer时，会经历几个阶段，如图所示
图：Kubernetes API 请求的请求处理步骤图Source：https://kubevious.io/blog/post/securing-kubernetes-using-pod-security-policy-admission-controller任何用户（sa与人类用户）在通过任何方式试图操作API资源时，必须要经历下列的操作：
Authentication，这个步骤在建立TLS连接后，验证包含，证书、密码，Token；可以指定多种认证，依次尝试每一个，直到其中一个认证成功。如果认证失败，此时客户端收到的是401。 Authorization，此步骤是在完成 Authentication 后确定了来源用户，此时用户的请求动作必须被授权。如bob用户对pod资源有 get , list 权限操作。如果 Admission Control：此步骤为图3，与 Authorization 不同的时，这里只要有任意准入控制器拒绝，则拒绝；多个准入控制器会按顺序执行 Refer to controlling access
认证 Kubernetes是高度模块化设计的，因此其认证授权与准入控制是各自都通过插件的方式，可由用户自定义选择经由什么样的插件来完成何种控制逻辑。如对称秘钥认证方式、令牌认证。由于Kubernetes提供的是resetful方式的接口，其服务都是通过HTTP协议提供的，因此认证信息只能经由HTTP协议的认证首部进行传递，此认证首部通常被称作认证令牌(token)。
ssl认证，对于Kubernetes访问来讲，ssl证书能让客户端去确认服务器的身份，（要求服务端发送服务端证书，确认证书是否为认可的CA签署的。）在Kubernetes通信过程当中，重要的是服务器还需认证客户端的身份，因此==Kubectl也应有一个证书，并且此证书为server端所认可的CA所签署的证书==。并且客户端身份也要与证书当中标识的身份保持一致。双方需互相做双向证书认证。认证之后双方基于SSL会话实现加密通讯。
注：kubernetes认证无需执行串行检查，用户经过任何一个认证插件通过后，即表示认证通过，无需再经由其他插件进行检查。
授权 kubernetes的授权也支持多种授权插件来完成用户的权限检查，kubernetes 1.6之后开始支持基于RBAC的认证。除此只外还有基于节点的认证、webhook基于http回调机制，通过web的rest服务来实现认证的检查机制。最重要的是RBAC的授权检查机制。基于角色的访问控制，通常只有许可授权，没有拒绝授权。默认都是拒绝。
在默认情况下，使用kubeadm部署Kubernetes集群是强制启用了RBAC认证的。
准入控制 一般而言，准入控制本身只是用来定义对应授权检查完成之后的后续其他安全检查操作的。
用户账号 一般而言用户账号大体上应具有以下信息
user 用户，一般而言由username与userid组成。
group 用户组
extra 用来提供额外信息
API资源 k8sapiserver是分组的，向哪个组，哪个版本的哪个api资源对象发出请求必须进行标识，所有的请求资源通过url path进行标识的。如 /apis/apps/v1/，所有名称空间级别的资源在访问时一般都需指名namespaces关键词，并给出namespaces名称来获取 /apis/apps/v1/namespaces/default/ /apis/apps/v1/namespaces/default/nginx 。
一个完整意义上的url 对象引用url格式 ==/apis/&amp;lt;GROUPS&amp;gt;/&amp;lt;VERSION&amp;gt;/namespaces/&amp;lt;NameSpace_name&amp;gt;/&amp;lt;Kind&amp;gt;/[/object_id]==
bash 1 2 3 $ kubectl api-versions admissionregistration.k8s.io/v1beta1 ... Kubernetes中，所有的api都取决于一个根 /apis
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 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 $ curl -k --cert /etc/k8s/pki/apiserver-kubelet-client.</description>
    </item>
    <item>
      <title>kubernetes概念 - RBAC</title>
      <link>https://www.161616.top/kubernetes-rbac/</link>
      <pubDate>Tue, 21 Aug 2018 00:00:00 +0000</pubDate>
      <guid>https://www.161616.top/kubernetes-rbac/</guid>
      <description>Kubernetes API Object 在Kubernetes线群中，Kubernetes对象是持久化的实体（最终存入etcd 中的数据），集群中通过这些实体来表示整个集群的状态。前面通过kubectl来提交的资源清单文件，将我们的YAML文件转换成集群中的一个API对象的，然后创建的对应的资源对象。
Kubernetes API是一个以JSON为主要序列化方式的HTTP服务，除此之外支持Protocol Buffers序列化方式（主要用干集群内年件间的通信）。为了api的可扩展性，Kubemetes在不同的API路径（/api/v1或/apis/batch）下面支持了多个API版本，不同的API版本就味不同级别稳定性和支持。
Alpha ：例如v1Alpha：默认情况下是禁用的，可以随时删除对功能的支持。 Beta：例如 v2beta1 默认是启用的，表示代码已经经过了很好的测试，但是对象的语义可能会在施后的版本中以不兼咨的方式更改 Stable：例如：v1 表示已经是稳定版本，也会出现在后续的很多版本中。 在Kubernetes集群中，一个API对象在Etcd 里的完整资源路径，是由：group （API组）、 version （API版本） 和 Resource API资源类型）三个部分组成。通过这种的结构，整个Kubernetes 中所有API对象，就可以用如下的树形结构表示出来：
Kubernetes API Object的使用 API对象组成查看：kubectl get --raw /
通常，KubernetesAPI支持通过标准HTTP P0ST、PUT、DELETE 和 GET 在指定PATH路径上创建、更新、删除和检索操作，并使用JSON作为默认的数据交互格式。
如要创建一个Deployment对象，那YAML文件的声明就需：
yaml 1 2 apiVersion: apps/v1 # kind: Deployment Deployment就是这个API对象的资源类型（Resource），apps就是它的组（Group），v1就是它的版本（Version）。API Group、Version 和资源满唯一定义了一个HTTP路径，然后在kube-apiserver 对这个url进行了监听，然后把对应的请求传递给了对应的控制器进行处理。
API对象参考文档
授权插件分类 Node 由节点来认证。
ABAC 基于属性的访问控制，RBAC之前的授权控制的插件算法
RBAC Role-based Access Control。
Webhook 基于http的回调机制来实现访问控制。
RBAC 基于角色的访问控制可以理解为，角色（role）反而是授权的机制，完成了权限的授予、分配等。角色是指一个组织或者任务工作中的位置，通常代表一种权利、资格、责任等。在基于角色的访问控制中还有一种术语叫做 ==许可==（permission）。
简单来讲就如同上图描述，使用户去扮演这个角色，而角色拥有这个权限，所以用户拥有这个角色的权限。所以授权不授予用户而授予角色。
RBAC 使用 rbac.authorization.k8s.ioAPI组来驱动鉴权操作，允许管理员通过 Kubernetes API 动态配置策略。</description>
    </item>
  </channel>
</rss>
