diff --git a/2024/01/06/cloud-native/envoy/index.html b/2024/01/06/cloud-native/envoy/index.html index 58d6d4f..265922b 100644 --- a/2024/01/06/cloud-native/envoy/index.html +++ b/2024/01/06/cloud-native/envoy/index.html @@ -159,13 +159,13 @@ diff --git a/2024/01/07/cloud-native/istio/index.html b/2024/01/07/cloud-native/istio/index.html index a85cd69..a98a8b1 100644 --- a/2024/01/07/cloud-native/istio/index.html +++ b/2024/01/07/cloud-native/istio/index.html @@ -155,13 +155,13 @@ diff --git a/2024/01/13/cloud-native/dragonfly/index.html b/2024/01/13/cloud-native/dragonfly/index.html index 0c64ecb..c82813c 100644 --- a/2024/01/13/cloud-native/dragonfly/index.html +++ b/2024/01/13/cloud-native/dragonfly/index.html @@ -157,13 +157,13 @@ diff --git a/2024/01/13/cloud-native/nydus/index.html b/2024/01/13/cloud-native/nydus/index.html index f4bec3d..6b0669d 100644 --- a/2024/01/13/cloud-native/nydus/index.html +++ b/2024/01/13/cloud-native/nydus/index.html @@ -162,13 +162,13 @@ diff --git a/2024/01/14/cloud-native/oci/index.html b/2024/01/14/cloud-native/oci/index.html index 8b539fa..73025bb 100644 --- a/2024/01/14/cloud-native/oci/index.html +++ b/2024/01/14/cloud-native/oci/index.html @@ -162,13 +162,13 @@ diff --git a/2024/01/16/cloud-native/containerd/index.html b/2024/01/16/cloud-native/containerd/index.html index e0681e8..f0e5218 100644 --- a/2024/01/16/cloud-native/containerd/index.html +++ b/2024/01/16/cloud-native/containerd/index.html @@ -163,13 +163,13 @@ diff --git a/2024/01/16/papers/lazy-docker/index.html b/2024/01/16/papers/lazy-docker/index.html index f030ec8..573bc8f 100644 --- a/2024/01/16/papers/lazy-docker/index.html +++ b/2024/01/16/papers/lazy-docker/index.html @@ -158,13 +158,13 @@ diff --git a/2024/01/18/cloud-native/karmada/index.html b/2024/01/18/cloud-native/karmada/index.html index 3d269b0..55e8b72 100644 --- a/2024/01/18/cloud-native/karmada/index.html +++ b/2024/01/18/cloud-native/karmada/index.html @@ -30,7 +30,7 @@ - + @@ -143,7 +143,7 @@
+
diff --git a/2024/01/26/cloud-native/CNCF/index.html b/2024/01/26/cloud-native/CNCF/index.html new file mode 100644 index 0000000..794151f --- /dev/null +++ b/2024/01/26/cloud-native/CNCF/index.html @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CNCF视频清单 | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ CNCF视频清单 +

+ + +
+ + + + +

CNCF视频清单

+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/01/28/Go/GMP and Scheduler/index.html b/2024/01/28/Go/GMP and Scheduler/index.html new file mode 100644 index 0000000..9c84470 --- /dev/null +++ b/2024/01/28/Go/GMP and Scheduler/index.html @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Go GMP and Scheduler | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ Go GMP and Scheduler +

+ + +
+ + + + +

资料

+

结构

原理

    +
  • G:协程,P:processor,M:系统线程,M绑定一个P才能执行G;
  • +
  • P的数据是控制着Go的并发能力,由环境变量GOMAXPROCESS控制数量,线程数一般不配置,但也有一个底层的函数可设置(SetMaxThreads),M默认上限是10000;
  • +
  • P的存在是为了实现G的调度和M/G之间M:N的关系;
  • +
  • P有一个local queue,无锁,当P的local queue无G时,会从Global queue取,此时需要用锁,而如果Global queue也无G时,会走work stealing,尝试从其它P的local queue上找G运行;
  • +
  • G的抢占调度是基于时间片,即如果G长时间连续运行超过10ms,则会通过系统信号SIGURG强制调度该协程;
  • +
  • 当G发生阻塞,如系统调用IO操作时,会创建一个新的线程或利用一个空闲的线程来绑定当前P,以继续执行P上的G,而旧线程进入阻塞睡眠状态;
  • +
  • P的local queue放的G的数量上限为256;
  • +
  • 当因IO阻塞进入idle状态的线程,在G系统调用结束时,因此时M上没有P了,而G的执行一定需要P,所以会尝试先去获取一个idle的P来执行,如找到了,则会将该G放到该P的local queue中,如果没有,则M会进入idle线程队列,G会放到Global queue中;
  • +
+ + + + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/01/28/Go/Go GC/index.html b/2024/01/28/Go/Go GC/index.html new file mode 100644 index 0000000..905022b --- /dev/null +++ b/2024/01/28/Go/Go GC/index.html @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Go GC | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ Go GC +

+ + +
+ + + + +

Go1.5 标记删除(Mark and Sweep)

原理

    +
  • 进入STW(Stop The World)阶段
  • +
  • 遍历整个heap,排查未被引用的对象,并标记;
  • +
  • 暂停STW
  • +
  • 执行Sweep清除
  • +
+

缺点

    +
  • STW会让Go程序暂停,程序出现卡顿
  • +
  • 标记需要扫描整个heap
  • +
  • 清除数据会产生heap碎片
  • +
+

Go1.8 三色标记法 + 写入屏障

三色标记法

原理

    +
  • 维护三个标记表:白色灰色黑色
  • +
  • 程序初始时,所有对象标记为白色
  • +
  • 从Root Set开发,每次只遍历一层,标记该层的对象为灰色(对象从白色表中移到灰色表)
  • +
  • 然后,以灰色标记表开始,遍历该表中的对象,将从这些对象开始的可达到对象(走一步),标记为灰色,同时灰色表中已经遍历过的对象,标记为黑色(对象从灰色表中移到黑色表)
  • +
  • 循环上一步,继续遍历灰色表,直到灰色表中无任何对象
  • +
  • 剩下的白色即为需要删除的对象
  • +
+
+

上述过程,仍然需要STW,否则会出现并发导致的引用关系错乱,导致资源被错误的GC删除

+
+ + +

写入屏障

原理

    +
  • 三色标记被破坏的情况有两种:

    +
      +
    1. 一个白色对象被黑色对象引用
    2. +
    3. 灰色对象与它的可达白色对象关系遭到破坏(灰色同时丢失了该白色)
    4. +
    +
  • +
  • 谷歌提出了两个三色不变色:

    +
      +
    1. 强三色不变性:强制性不允许黑色引用白色
    2. +
    3. 弱三色不变性:黑色可以引用白色,但白色对像存在其它灰色(可非直接上级节点)引用该白色对象
    4. +
    +
  • +
  • 只要三色不变色满足上述条件之一,即可解决三色标记必须使用STW问题

    +
  • +
+

插入写屏障

插入屏障原理

    +
  • 对堆对象,在对象被引用时触发,A引用B时,B对象标记为灰色
  • +
  • 对栈对象,对象被引用时,不触发该过程以避免该标记过程对程序性能的影响;
  • +
  • 此时在GC过程,遍历灰色表的过程,不需要STW,直到灰色表为空结束
  • +
  • 而此时栈上黑色对象可能引用白色对象,为解决这个问题,需要在上一步灰色表为空时,执行一些STW,并将栈上所有对象都标记为白色,并对这些对象重新执行一遍扫描;
  • +
+
+

缺点:在结束时,还需要额外扫描一次栈上的对象引用链,这会引入10-100ms;

+
+

删除屏障原理

    +
  • 被删除对象,如果自身为灰色白色,则会被标记为灰色
  • +
  • 该过程是满足弱三色不变式,保证灰色对象到白色对象的路径不会断;
  • +
+
+

缺点:被删除对象,当前这一轮GC不会被删掉(因为会被转换成黑色),但会在下轮GC中删掉;

+
+

混合写屏障

原理

    +
  • GC开始时,扫描栈上的可达对象全部标记为黑色(期间不需要STW)
  • +
  • GC期间,任何在栈上创建的新对象,均为黑色
  • +
  • 被删除对象,被标记为灰色
  • +
  • 被添加的对象标记为灰色
  • +
+
+

满足变形的弱三色不变色,混合了插入,删除写屏障的优点

+
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/01/28/Go/channel/index.html b/2024/01/28/Go/channel/index.html new file mode 100644 index 0000000..4b45d2a --- /dev/null +++ b/2024/01/28/Go/channel/index.html @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Go Channel | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ Go Channel +

+ + +
+ + + + +

原理

    +
  • 本质上,channel是一个包含:发送Go队列,接收Go队列,由循环数组实现的缓存数据队列,锁这几个元素组成的结构体实现;
  • +
  • sendmsg阶段:
      +
    • 如果接收Go队列有值,则直接进行值元素的内存拷贝,并唤醒接收队列;
    • +
    • 如有缓冲队列且未满,则将值复制到循环队列中;
    • +
    • 如果有缓冲队列且满了或无缓冲队列,将协程放到channel的sendqueue中;
    • +
    +
  • +
  • recvmsg阶段:
      +
    • 如果缓冲,且无数据,则进入recvqueue中,协程挂起(gopack);
    • +
    • 如果缓冲队列中数据,由从队列中将值拷贝给当前接收者;
    • +
    • 如果sendqueue有协程,则说明缓冲队列已满,则从缓冲队列中取值,并将sendqueue中取一个协程,将其值拷贝到缓冲循环数组中;
    • +
    +
  • +
  • 上述操作是在mutex锁下进行,所以channel是协程安全的;
  • +
+ + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/01/28/Go/mem/go-mem-arch.png b/2024/01/28/Go/mem/go-mem-arch.png new file mode 100644 index 0000000..af175a2 Binary files /dev/null and b/2024/01/28/Go/mem/go-mem-arch.png differ diff --git a/2024/01/28/Go/mem/go-mem-arch2.png b/2024/01/28/Go/mem/go-mem-arch2.png new file mode 100644 index 0000000..6c3e1bc Binary files /dev/null and b/2024/01/28/Go/mem/go-mem-arch2.png differ diff --git a/2024/01/28/Go/mem/index.html b/2024/01/28/Go/mem/index.html new file mode 100644 index 0000000..c97ebe0 --- /dev/null +++ b/2024/01/28/Go/mem/index.html @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Go 内存模型 | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ Go 内存模型 +

+ + +
+ + + + +

架构

分层架构

    +
  • Go的页单元大小 :8KB,linux操作系统:4KB;
  • +
  • 如下图所示,分了三层来管理
      +
    • mcache: 每个P一个,为每个mspan额外缓存了一个,无锁;
    • +
    • mcentral: 分了67个span,从8B-32B,细粒度锁;
    • +
    • mheap: 全局唯一;go-mem-arch + +go-mem-arch2
    • +
    +
  • +
+

三类对象

    +
  • tiny 微对象,<=8B,通过P的专属tinyAllocator分配,依次从:mcache tiny -> mcache span -> mcentral -> mheap -> VM分配;
  • +
  • small 小对象,<=32KB, 依次从:mcache span -> mcentral -> mheap -> VM分配;
  • +
  • large 大对象,>32KB,依次从:mcentral -> mheap -> VM分配;
  • +
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/01/28/Python/Python GC/index.html b/2024/01/28/Python/Python GC/index.html new file mode 100644 index 0000000..1600ccc --- /dev/null +++ b/2024/01/28/Python/Python GC/index.html @@ -0,0 +1,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Python GC | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ Python GC +

+ + +
+ + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/02/18/cloud-native/cni/basic-concepts.png b/2024/02/18/cloud-native/cni/basic-concepts.png new file mode 100644 index 0000000..8845da9 Binary files /dev/null and b/2024/02/18/cloud-native/cni/basic-concepts.png differ diff --git a/2024/02/18/cloud-native/cni/calico-communicate.png b/2024/02/18/cloud-native/cni/calico-communicate.png new file mode 100644 index 0000000..bc278b6 Binary files /dev/null and b/2024/02/18/cloud-native/cni/calico-communicate.png differ diff --git a/2024/02/18/cloud-native/cni/calico.png b/2024/02/18/cloud-native/cni/calico.png new file mode 100644 index 0000000..5c2b45f Binary files /dev/null and b/2024/02/18/cloud-native/cni/calico.png differ diff --git a/2024/02/18/cloud-native/cni/docker-bridge.png b/2024/02/18/cloud-native/cni/docker-bridge.png new file mode 100644 index 0000000..72e7a08 Binary files /dev/null and b/2024/02/18/cloud-native/cni/docker-bridge.png differ diff --git a/2024/02/18/cloud-native/cni/index.html b/2024/02/18/cloud-native/cni/index.html new file mode 100644 index 0000000..ca4a5f7 --- /dev/null +++ b/2024/02/18/cloud-native/cni/index.html @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +cni | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ cni +

+ + +
+ + + + +

容器网络

+ +
+

docker网络模式

    +
  • 默认创建如下三种:bridge, host, none
    hbb@hbb:~$ docker network ls
    NETWORK ID NAME DRIVER SCOPE
    3c92bea4cc95 bridge bridge local
    3d964312d0b5 host host local
    07d5e640e74f none null local
  • +
  • 默认容器均采用bridge网桥模式,所有容器均会创建一对虚拟网络接口,容器内一个eth0,容器外一个vethXXX,vethXXX属于docker0,通过docker0实现对外网的访问;
  • +
  • host模式即与主机共享网络空间,不使用私有的容器网络空间;
  • +
  • none模式即容器内没有eth0网口,因此无法与容器外通信;
  • +
+

network namespace, veth pair, bridge

    +
  • 下图所示为相关概念:
    network namespace vs veth pair vs bridge
  • +
+

bridge

    +
  • docker0 bridge即纯软件实现的虚拟交换机,可实现与物理交换机同样的功能,如二层交换,ARP寻找MAC地址;
  • +
+

network namespace

    +
  • 即将一个物理的网络协议栈进行逻辑隔离,形成网络空间,不同的拷贝协议栈有自己独立的网络接口,ip,route tables, iptables等,而进程可以设置使用不同的network namespace,多个进程也可以属于同一个ns,一个pod有一个独立的ns,pod内的容器属于同一个ns;
  • +
+

容器网络通信模型

    +
  • pod内容器属于同一个网络空间,所以可直接相互访问;
  • +
  • 同机不同容器之间,通过虚拟以太网veth network互联,docker安装后,会默认创建一个docker0作为虚拟以太网的bridge网桥,在容器创建时会在容器内外创建一对虚拟网络接口,容器内为eth0,容器外即主机上会对应创建一个vethXXX名的接口名,如下图所示:
      +
    • 该图为docker容器内eth0,与docker0属于同一网段:
      veth in C
    • +
    • 该图为上面容器在主机上对应的veth网口,其master为docker0:
      veth on host
    • +
    +
  • +
  • 在主机上通过docker inspect network bridge命令可查看docker列出的当前docker默认bridge网桥docker0下的容器网络信息:
    docker bridge
  • +
+ +
    +
  • 因此,同主机上的容器之间是通过网桥来实现互联,其为2层网络通信;
  • +
  • k8s跨节点的网络通信,需要对应的CNI插件来创建和维护,其原理是通过IP包路由来实现;
  • +
  • 因为k8s的容器编排会导致pod频繁变化,对应的IP也会频繁变化,因此实现更新对应的网络信息是需要对应的CNI插件来实现,不同插件实现的跨节点的网络通信方式不一样,如通过TUN隧道等;
    k8s network
  • +
+

pod网络创建过程

    +
  • kubelet -> CRI plugin -> pod net ns, pause sandox -> CNI plugin
  • +
  • 如下图所示:
    pod network
  • +
+

vxlan网络与flannel CNI

    +
  • 如图所示,为vxlan原理:
    vxlan

    +
  • +
  • flannel CNI插件会为每个node分配一个子网IP段,上面的pod会从该网段范围取一个IP;

    +
  • +
  • 默认,flannel跨节点通信是通过vxlan实现,即通过隧道技术L2 Oery UDP

    +
  • +
+

calico CNI

    +
  • calico是一个运行在纯三层的组件,基于BGP协议和Linux自身的路由转发机制,容器通信也不依赖iptables NAT或Tunnel 等技术,因此相对于flannel会少一些封包与拆包的过程,效率更高:
    calico

    +
  • +
  • 其跨主机的通信模型如下所示:
    calico communicate

    +
  • +
  • 当容器创建时,calico为容器生成veth pair,一端作为容器网卡加入到容器的网络命名空间,并设置IP和掩码,一端直接暴露在宿主机上,并通过设置路由规则,将容器IP暴露到宿主机的通信路由上。于此同时,calico为每个主机分配了一段子网作为容器可分配的IP范围,这样就可以根据子网的CIDR为每个主机生成比较固定的路由规则。

    +
  • +
  • 当容器需要跨主机通信时,主要经过下面的简单步骤:

    +
      +
    • 容器流量通过veth pair到达宿主机的网络命名空间上。
    • +
    • 根据容器要访问的IP所在的子网CIDR和主机上的路由规则,找到下一跳要到达的宿主机IP。
    • +
    • 流量到达下一跳的宿主机后,根据当前宿主机上的路由规则,直接到达对端容器的veth pair插在宿主机的一端,最终进入容器。
    • +
    +
  • +
+

集群网络

    +
  • 通过service来维护pod IP的抽象,管理与负载均衡;
  • +
  • 通过环境变量或DNS来实现服务发现;
  • +
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/02/18/cloud-native/cni/k8s-network.png b/2024/02/18/cloud-native/cni/k8s-network.png new file mode 100644 index 0000000..0644d30 Binary files /dev/null and b/2024/02/18/cloud-native/cni/k8s-network.png differ diff --git a/2024/02/18/cloud-native/cni/pod-network.png b/2024/02/18/cloud-native/cni/pod-network.png new file mode 100644 index 0000000..6d345bd Binary files /dev/null and b/2024/02/18/cloud-native/cni/pod-network.png differ diff --git a/2024/02/18/cloud-native/cni/vethInC.png b/2024/02/18/cloud-native/cni/vethInC.png new file mode 100644 index 0000000..5a64fc6 Binary files /dev/null and b/2024/02/18/cloud-native/cni/vethInC.png differ diff --git a/2024/02/18/cloud-native/cni/vethOnHost.png b/2024/02/18/cloud-native/cni/vethOnHost.png new file mode 100644 index 0000000..7b8ae8a Binary files /dev/null and b/2024/02/18/cloud-native/cni/vethOnHost.png differ diff --git a/2024/02/18/cloud-native/cni/vxlan.png b/2024/02/18/cloud-native/cni/vxlan.png new file mode 100644 index 0000000..b363cc0 Binary files /dev/null and b/2024/02/18/cloud-native/cni/vxlan.png differ diff --git a/2024/02/19/k8s/client-go/index.html b/2024/02/19/k8s/client-go/index.html new file mode 100644 index 0000000..3bddcca --- /dev/null +++ b/2024/02/19/k8s/client-go/index.html @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +k8s client-go | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ k8s client-go +

+ + +
+ + + + +

client

    +
  • k8s client-go提供4个client:RESTClient, ClientSet, DynamicClient, DiscoveryClient
  • +
+

RESTClient

    +
  • 作为另外三类client的基类,提供与k8s apiserver的底层API请求构造与请求;
  • +
+

ClientSet

    +
  • 用于方便访问k8s内置api group资源的client,如deployment, pod等;
  • +
+

DynamicClient

    +
  • 通过指定资源组,资源版本即可操作k8s中的任务资源,包括CRD和内置资源;
  • +
  • DynamicClient使用嵌套的map[string]interface{}结构来存储k8s apiserver的返回资源结构,通过反射机制,在运行时进行数据绑定;
  • +
+

DiscoveryClient

    +
  • 与前面三种client不同,该client不是用于管理k8s资源对象的,该client是用于查询k8s支持的GVR资源类型的,与kubectl api-versionskubectl api-resources返回的资源内容相关;
  • +
+ + +

Informer

Reflector and List-Watch

    +
  • List: 通过k8s apiserver Restful API获取全量数据列表,并同步到本地缓存中,该操作基于HTTP短连接实现;
  • +
  • Watch负责监听资源变化,并调用相应事件处理函数进行处理,如更新本地缓存,使本地缓存与ETCD保持一致,该操作基于HTTP长连接实现;
  • +
  • Reflector是client-go中用于监听指定资源的组件,当资源发生变化时,会以事件的形式存储到本地队列,然后触发后续的相应处理函数;
  • +
  • Reflector核心逻辑有三部分:
      +
    • List: 全量同步指定资源;
    • +
    • Watch: 监听资源的变更;
    • +
    • 定时同步:定时更触发同步机制,定时更新缓存数据,可配置定时同步的周期;
    • +
    +
  • +
  • 当Watch断开时,Reflector会重新走List-Watch流程;
  • +
+

DeltaFIFO

    +
  • 增量的本地阶段,记录了资源的变化过程;
  • +
  • FIFO即为先入先出的本地队列;
  • +
  • Delta为资源的变化事件,存储的数据结构Deltas有两个属性:Type, Object,分别表示事件类型(增删改),资源类型;
  • +
  • FIFO负责接收来自Reflector的事件,将按顺序存储,多个相同事件只会被处理一次;
  • +
+

Indexer

    +
  • 本身是一个本地存储,并扩展了一定的索引能力;
  • +
  • Reflector通过DeltaFIFO的操作后,数据会被存储到Indexer中;
  • +
  • Indexer中的数据与ETCD完全一致;
  • +
+

几个重要概念

+
    +
  • IndexFunc: 索引函数,用于计算一个资源对象的索引值列表,可以根据需要自定义,如通过label, annotation来生成索引列表;
  • +
  • Index:存储数据,如要查找某个ns下的pod,就要让pod按ns空间进行索引,对应的Index类型即为map[ns]pods
  • +
  • Indexers:存储索引器,key为索引器名称,value为索引器实现函数(IndexFunc),如map[ns]XXXIndexFunc
    +

    即存储索引的存储器

    +
    +
  • +
  • Indices:存储缓存器,key为索引器名称,value为缓存的数据(Index),如map[ns]map[ns]sets.pod
    +

    即存储缓存数据的存储器

    +
    +
  • +
+
index := cache.NewIndexer(
cache.MetaNamespaceKeyFunc, // 资源key生成函数
cache.Indexers{ // 索引存储器名 => 索引生成函数
"namespace": XXXNsIndexFunc,
"nodeName": XXNodeNameIndexFunc,
})
pod1 := &v1.Pod{...}
pod2 := &v1.Pod{...}
pod3 := &v1.Pod{...}

_ = index.Add(pod1)
_ = index.Add(pod2)
_ = index.Add(pod3)

// 查询
pods, err := index.ByIndex("namespace", "xxx")
pods, err = index.ByIndex("nodeName", "xxx")
+ +

SharedInformer

    +
  • 通过SharedInformer为多个Controller提供缓存资源对象的informer共享,避免重复缓存;
  • +
  • SharedInformer一般是使用SharedInformerFactory来管理控制器需要的资源对象的informer,使用map结构来存储资源对象的informer;
  • +
+

SharedIndexInformer

    +
  • 继承了SharedInformer,并扩展了添加和获取Indexers的能力;
  • +
+

SharedInformerFactory

    +
  • SharedInformerFactory为所有已知GVR提供共享的informer;
  • +
  • 其有一个Start方法,用于启动所有Reflector的Informer;
  • +
  • WaitForCacheSync函数会不断调用factory持有的informer的HasSynced方案直接全部返回true,表示所有informer关注的资源对象已经全部缓存到了本地;
  • +
  • InformerFor方法,是用于返回SharedInformerFactory中指定资源类型所对应的informer,如果不存在则会先创建;
  • +
  • k8s client-go已经提供了内置的常用informer,如PodInforer, ServiceInformer等;
  • +
+
sharedInformerFactory := informers.NewSharedInformerFactory(clientSet, 0)
podInformer := sharedInformerFactory.Core().V1().Pods()
// 生成一个indexer便于查询数据
indexer := podInformer.Lister()

// 启动informer
sharedInformerFactory.Start(nil)
sharedInformerFactory.WaitForCacheSync(nil)

// 查询pod
pods, err := indexer.List(labels.Everything())
+ + + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/02/19/raft/index.html b/2024/02/19/raft/index.html new file mode 100644 index 0000000..f68ecfd --- /dev/null +++ b/2024/02/19/raft/index.html @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +raft | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ raft +

+ + +
+ + + + +

资料

+

特点

    +
  1. 随机超时:避免同时发起选举请求

    +raft random timeout +
  2. +
  3. 任期Term:用于标记选举任期,可用于让故障回复后的leader变成follower,任期小的选举请求会被拒绝;

    +
  4. +
  5. 角色:leader, follower, candidate

    +
  6. +
  7. leader选择出来后,leader会定时向follower发起心跳,如心跳超时,则最先timeout的节点会发起选举请求,此时该节点会从follower转变成cadidate;

    +
  8. +
+ + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/02/19/raft/raft-random-timeout.png b/2024/02/19/raft/raft-random-timeout.png new file mode 100644 index 0000000..b66c49d Binary files /dev/null and b/2024/02/19/raft/raft-random-timeout.png differ diff --git a/2024/02/20/k8s/probe/index.html b/2024/02/20/k8s/probe/index.html new file mode 100644 index 0000000..bf13c1f --- /dev/null +++ b/2024/02/20/k8s/probe/index.html @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +probe | so2bin + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + +

so2bin

+ +
+

青山一道同云雨,明月何曾是两乡

+
+ + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + +
+ + + + + + + +
+

+ probe +

+ + +
+ + + + +

Readiness, Liveness, StartupProbe

执行原理

    +
  • 均支持三种检测探针:TCP, HTTP, Exec Shell
  • +
  • 探针的执行均由kubelet组件执行;
  • +
+

Exec探针执行

    +
  • 由kubelet组件调用CRI接口的ExecSync接口,在对应的容器内执对应的cmd命令,获取其返回值;
  • +
+ + +
func (pb *prober) runProbe(p *v1.Probe, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID) (probe.Result, string, error) {
...
command := kubecontainer.ExpandContainerCommandOnlyStatic(p.Exec.Command, container.Env)
return pb.exec.Probe(pb.newExecInContainer(container, containerID, command, timeout))
...
}

func (pb *prober) newExecInContainer(container v1.Container, containerID kubecontainer.ContainerID, cmd []string, timeout time.Duration) exec.Cmd {
return execInContainer{func() ([]byte, error) {
return pb.runner.RunInContainer(containerID, cmd, timeout)
}}
}


func (m *kubeGenericRuntimeManager) RunInContainer(id kubecontainer.ContainerID, cmd []string, timeout time.Duration) ([]byte, error) {
stdout, stderr, err := m.runtimeService.ExecSync(id.ID, cmd, 0)
return append(stdout, stderr...), err
}

func (pr execProber) Probe(e exec.Cmd) (probe.Result, string, error) {
data, err := e.CombinedOutput()
glog.V(4).Infof("Exec probe response: %q", string(data))
if err != nil {
exit, ok := err.(exec.ExitError)
if ok {
if exit.ExitStatus() == 0 {
return probe.Success, string(data), nil
} else {
return probe.Failure, string(data), nil
}
}
return probe.Unknown, "", err
}
return probe.Success, string(data), nil
}
+ +

HTTP探针执行

    +
  • 由kubelet请求容器指定的URL,根据response status来判断,status属于[200-400)即判断成功:
    func DoHTTPProbe(url *url.URL, headers http.Header, client HTTPGetInterface) (probe.Result, string, error) {
    req, err := http.NewRequest("GET", url.String(), nil)
    ......
    if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest {
    glog.V(4).Infof("Probe succeeded for %s, Response: %v", url.String(), *res)
    return probe.Success, body, nil
    }
    ......
  • +
+

TCP探针执行

    +
  • 由kubelet执行Dail操作判断端口是否可连接:
    func DoTCPProbe(addr string, timeout time.Duration) (probe.Result, string, error) {
    conn, err := net.DialTimeout("tcp", addr, timeout)
    if err != nil {
    // Convert errors to failures to handle timeouts.
    return probe.Failure, err.Error(), nil
    }
    err = conn.Close()
    if err != nil {
    glog.Errorf("Unexpected error closing TCP probe socket: %v (%#v)", err, err)
    }
    return probe.Success, "", nil
    }
  • +
+

StartupProbe作用

startupProbe

+
    +
  • 对于一些服务场景,服务启动时间较长,以往的做法是调大LivenessProbeinitialDelaySecondsfailureThreshold值,但如果超过这个时间范围还没启动,服务会进入重启,并进入循环卡死的过程;
  • +
  • 因此,StartupProbe就是用于解决这种场景下的问题,在StartupProbe成功之前,是不是为执行LivenessProbeReadinessProbe的;
  • +
+

LivenessProbe作用

    +
  • 可以恢复 运行过程pod出现卡死的情况;
  • +
  • 如果pod的该探针失败,则k8s会触发该pod的删除与重建流程;
  • +
+

ReadinessProbe作用

    +
  • 影响pod的流量开关;

    +
  • +
  • 负责判断pod是否就绪,只有就绪状态后,才会将pod IP放到service的endpoints上,并开始接收流量;

    +
  • +
  • kubelet会通过SetContainerReadiness将container的condition设置为true:

    +
    func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontainer.ContainerID, ready bool) {
    ......
    containerStatus.Ready = ready
    ......
    readyCondition := GeneratePodReadyCondition(&pod.Spec, status.ContainerStatuses, status.Phase)
    ......
    m.updateStatusInternal(pod, status, false)
    }
    +
  • +
  • k8s v1.12之前,pod是否处于ready是由kubelet根据容器状态来判断的,如果pod中容器全部处于ready,则pod处于ready状态;

    +
  • +
  • k8s v1.12之后,提供了一个readinessGates的功能来满足用于对于pod ready状态的控制需求,此时判断pod是否ready有两个前提条件:

    +
      +
    • Pod中所有容器全部ready,即ContainersReadyTrue
    • +
    • pod.spec.readinessGates中定义一个或多个conditionType,需要这些conditionType都为True,pod才能为ready;
      apiVersion: v1
      kind: Pod
      spec:
      readinessGates:
      - conditionType: MyDemo
      status:
      conditions:
      - type: MyDemo
      status: "True"
      - type: ContainersReady
      status: "True"
      - type: Ready
      status: "True"
    • +
    +
  • +
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + 0% +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2024/02/20/k8s/probe/startupProbe.png b/2024/02/20/k8s/probe/startupProbe.png new file mode 100644 index 0000000..175b642 Binary files /dev/null and b/2024/02/20/k8s/probe/startupProbe.png differ diff --git a/about/index.html b/about/index.html index beb6f8c..7d7b14b 100644 --- a/about/index.html +++ b/about/index.html @@ -153,13 +153,13 @@ diff --git a/archives/2024/01/index.html b/archives/2024/01/index.html index ccf1d76..34b2c93 100644 --- a/archives/2024/01/index.html +++ b/archives/2024/01/index.html @@ -150,13 +150,13 @@

so2bin

@@ -192,7 +192,7 @@

so2bin

- 嗯..! 目前共计 9 篇日志。 继续努力。 + 嗯..! 目前共计 19 篇日志。 继续努力。
@@ -200,6 +200,126 @@

so2bin

2024
+
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
+ +
+ + +
+
+