📎Posts
Go 内存模型与分配机制
Go内存模型指定了一个goroutine中变量的读取条件,可以保证观察不同goroutine中对同一变量的写入产生的值。
虚拟内存#
虚拟内存技术是操作系统实现的一种高效的物理内存管理方式

- 虚拟内存通过页表映射到物理内存上,页表记录是否在物理内存上(有效位),以及物理内存页的地址
- 操作系统为每个进程提供了一个独立的页表,因此也就是一个独立的虚拟空间地址,多个虚拟页面可以映射到同一个共享物理页面上。
- 地址翻译:一个N元素的虚拟地址空间的元素和一个M元素的物理地址空间中元素之间的映射
- 虚拟内存:利用磁盘空间虚拟出一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间
- 操作系统内存管理中,一个重要概念虚拟内存:
- 扩大地址空间
- 内存保护
- 公平内存分配
- 当进程通信时,可采用虚存共享的方式实现
- 不需要在实际物理内存的连续空间,**可以利用碎片
- 虚拟内存的代价:
- 管理需要建立很多数据结构,占用额外的内存
- 虚拟地址到物理地址的转换,增加了指令的执行时间
- 页面的换入换出需要磁盘I/O
- 一页中只有部分数据,会浪费内存
Go内存模型#
参考tcmalloc设计,「修改由多个goroutine同时访问的数据的程序必须序列化这种访问。 要序列化访问,请使用channel操作或其他同步原语(sync和sync/atomic)保护数据。 别自作聪明。」
📎Posts
TCP/IP 协议的那些东西
TCP/IP 协议的那些东西#
本文主要是基于《TCP/IP 详解 卷1:协议》以及一些资料的一个学习总结。
概述#
网络中的整体传输流程可以简要总结为:数据首先会封装到TCP的Segment中,然后TCP的Segment封装到IP的Packet中,最后封装为以太网Ethernet的Frame,各个层解析自己的协议以及数据信息,最后将数据交给更高层的协议处理

- 应用层 :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。
- 传输层 :为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。传输层包括两种协议:
- 传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;
- 用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。
- 网络层 :为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组,IP协议
- 数据链路层 :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。
- 物理层 :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。
TCP头格式#

📎Posts
Kubelet StatusManager机制流程分析
Kubelet StatusManager机制流程分析#
主要功能将Pod状态信息同步到ApiServer,并不会主动监控Pod状态,提供接口供其他Manager调用,当其他组件需要改变 pod 的状态时会将 pod 的 status 信息发送到 statusManager 进行同步。主要使用方
probeManager,podWorkers

type manager struct {
kubeClient clientset.Interface
podManager kubepod.Manager
// Map from pod UID to sync status of the corresponding pod.
// statusManager 的 cache,保存 pod 与状态的对应关系;
podStatuses map[types.UID]versionedPodStatus
podStatusesLock sync.RWMutex
// 当其他组件调用 statusManager 更新 pod 状态时,会将 pod 的状态信息发送到podStatusesChannel 中;
podStatusChannel chan podStatusSyncRequest
// Map from (mirror) pod UID to latest status version successfully sent to the API server.
// apiStatusVersions must only be accessed from the sync thread.
apiStatusVersions map[kubetypes.MirrorPodUID]uint64
// 删除 pod 的接口
podDeletionSafety PodDeletionSafetyProvider
podStartupLatencyHelper PodStartupLatencyStateHelper
}
Start#
// 设置定时触发,时间为10s
syncTicker := time.NewTicker(syncPeriod).C
go wait.Forever(func() {
for {
select {
// 监听到一个pod状态变更的场景
case syncRequest := <-m.podStatusChannel:
klog.V(5).InfoS("Status Manager: syncing pod with status from podStatusChannel",
"podUID", syncRequest.podUID,
"statusVersion", syncRequest.status.version,
"status", syncRequest.status.status)
m.syncPod(syncRequest.podUID, syncRequest.status)
-> func (m *manager) needsUpdate(uid types.UID, status versionedPodStatus) bool {
// 1. 判断版本号信息
// 2. 获取pod
// 3. 判断是否处于删除状态
-> PodResourcesAreReclaimed // 检查 pod 在 node 上占用的所有资源是否已经被回收
}
// 触发定时器(定时器,syncPeriod 默认为 10s)
case <-syncTicker:
klog.V(5).InfoS("Status Manager: syncing batch")
// remove any entries in the status channel since the batch will handle them
for i := len(m.podStatusChannel); i > 0; i-- {
<-m.podStatusChannel
}
m.syncBatch()
}
}
}, 0)
syncPod#
- 基本流程
- 判断是否需要同步状态, 判断版本号信息是否已经增加,若不需要同步则继续检查 pod 是否处于删除状态
- 合并状态信息并更新记录到cache
- 如果可以删除pod,执行删除动作
func (m *manager) syncPod(uid types.UID, status versionedPodStatus) {
// 判断是否需要同步状态,以及是否处于删除状态
if !m.needsUpdate(uid, status) {
...
}
// 判断ResolvedPodUID是否一致,不一致则为删除后重建出来的pod,需要删除statusmanager保存的旧状态信息
if len(translatedUID) > 0 && translatedUID != kubetypes.ResolvedPodUID(uid) {
// 删除保存的状态信息,以及启动延时处理的状态
m.deletePodStatus(uid)
return
}
// 根据实际运行状态以及其他组件设置的状态合并出最终状态信息
mergedStatus := mergePodStatus(pod.Status, status.status, m.podDeletionSafety.PodCouldHaveRunningContainers(pod))
// 更新pod状态信息以及所记录状态
// 如果pod处理删除状态,删除pod以及记录信息
if m.canBeDeleted(pod, status.status) {
// 设置GracePeriodSecond为0,同时避免删除一个同名同命名空间的资源,传递Uid做precondition
...
err = m.kubeClient.CoreV1().Pods(pod.Namespace).Delete(context.TODO(), pod.Name, deleteOptions)
...
m.deletePodStatus(uid)
}
}
syncBatch#
定期将statusManager 缓存 podStatuses 中的数据同步到 apiserver,定时同步的时候会清理channel内容
📎Posts
Kubelet VolumeManager机制流程分析
Kubelet VolumeManager机制流程分析#
Kubelet Volume相关逻辑主要在VolumeManager模块

- Mount 阶段则由对应节点的 kubelet 中的 volume manager 处理。
- volume manager 获取 node.Status.VolumesAttached 属性值,发现 volume 已被标记为 attached, 就会进行 mount 操作
- k8s中涉及存储的组件主要有:attach/detach controller、pv controller、volume manager、volume plugins、scheduler。每个组件分工明确:
- attach/detach controller:负责对 volume 进行 attach/detach
- persistent volume controller:负责处理 pv/pvc 对象,包括 pv 的 provision/delete
- kubelet volume manager:主要负责对 volume 进行 mount/unmount
- volume plugins:包含 k8s 原生的和各厂商的的存储插件
挂载流程#
第一步是在准备 volume(宿主机目录),第二步才是真正的挂载操作。
📎Posts
Nginx指南
Nginx 介绍#
“Nginx 是一款轻量级的 HTTP 服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的 IO 性能,时常用于服务端的反向代理和负载均衡。”

- 正向代理
- 正向代理“代理”的是客户端,而且客户端是知道目标的,而目标是不知道客户端是通过VPN访问的。
- 反向代理
- 反向代理“代理”的是服务器端,而且这一个过程对于客户端而言是透明的。
Nginx的Master-Worker模式#
- Master
- 读取并配置nginx.conf, 管理Worker进程
- Worker
- 维护一个线程(避免线程切换),处理连接和请求;注意Worker进程的个数由配置文件决定,一般和CPU个数相关(有利于进程切换),配置几个就有几个Worker进程。
Nginx热部署#
- 修改配置文件nginx.conf后,重新生成新的worker进程,当然会以新的配置进行处理请求,而且新的请求必须都交给新的worker进程,至于老的worker进程,等把那些以前的请求处理完毕后,kill掉
Keepalived+Nginx实现高可用#
- Keepalived是一个高可用解决方案,主要是用来防止服务器单点发生故障
- keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。
- keepalived主要有三个模块,分别是core、check和vrrp。core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查,包括常见的各种检查方式。vrrp模块是来实现VRRP协议的。