跳至主要内容

博文

此博客已经弃用,请访问 blog.41tair.org

用了一年左右的 blogger 还是选择放弃
1.我只需要一个可以专心写东西的地方
2.blogger 不支持多种 org,甚至不支持 markdown 写起来十分不舒服
3.在使用自动化的方式部署,blogger 的发布需要首先申请 Google 的 Oauth,十分麻烦
4.已经 2020 年了,blogger 提供的编辑界面依然具有上个世纪的风格

现在采取的方案:
1.私有的 github 仓库用来存储 blog 与 draft
2.公有的 github 仓库用来展示
3.私有的仓库使用 github action 进行 org 至 html 的转换并生成 index
4.通过 github 的 deploy key 发布至公有的仓库
最新博文

当你迷茫时不妨看看这个

吾生也有涯,而知也无涯。以有涯随无涯,殆已!已而为知者,殆而已矣!
                                                                                           -----《庄子·内篇·养生主第三》



与其感慨路难行,不如马上出发
-----《DOTA2·骷髅射手·克林克兹》

kubernetes cloud controller manager

kubernetes cloud controller manager Table of Contents1. 什么是 cloud controller manager(ccm)2. 能用 ccm 干什么2.1. 现有的 ccm2.1.1. In Tree2.1.2. Out of Tree3. 如何实现一个 ccm4. ccm 背后的秘密4.1. Out of Tree ccm 如何工作5. 参考链接 本文所有代码基于 1.16.0-alpha.2 commit: bdde11a664 所以引用文档版本为 1.15.0 1 什么是 cloud controller manager(ccm) 在说 ccm 之前要了解一个 ccm 的前身 – cloud provider
cloud provider 是为了 k8s 更加容易在公有云环境下而提出的一个方案
比如在 aws azure 等环境下可以让 k8s 的资源与云厂商的资源进行匹配
具体的演进路线等可以阅读 这篇文章 2 能用 ccm 干什么 在思索 ccm 可以做什么时,要思考一个问题:kubernetes 的核心价值在于哪里?
云主机厂商的本质上是在售卖计算资源与服务,而 k8s 的价值是在于管理与调度容器
正如 k8s 描述的一样: Production-Grade Container Scheduling and Management
k8s 更加关心容器的调度与管理,其他的资源也都是为了容器而服务的
那么有什么资源对于 k8s 来说是可以被替代的?
负载均衡、路由、主机
k8s 不关心主机是实际在东京还是西雅图,也不关心负载均衡具体是如何实现的
它只需要主机上的 kubelet 在正常运行,可以通过负载均衡访问到暴露的服务
而这些恰恰是云厂商最为关心的事情,主机的配置、主机的位置、负载均衡的实现、路由如何到达
这时候再来看 ccm 的接口
LoadBalancer() (LoadBalancer, bool) Instances() (Instances, bool) Zones() (Zones, bool) Clusters() (Clusters, bool) Routes() (Routes, bool) ProviderName() string HasClusterID() bool 这样就…

在 LSF 中使用 docker 运行任务

LSF + Docker Table of Contents1. 环境信息2. 修改配置文件在 lsf 上启用 docker3. 验证4. 部署常见问题5. 部署参考链接 1 环境信息 docker 18.09.5
Kernel Version: 3.10.0-862.11.6.el7.x86_64
lsf 10.1.0.6
OS CentOs 7.6.1810 2 修改配置文件在 lsf 上启用 docker 1.conf/lsf.conf
添加/修改LSF_PROCESS_TRACKING=Y LSF_LINUX_CGROUP_ACCT=Y LSB_RESOURCE_ENFORCE="cpu memory" 2.conf/lsf.shared
添加docker Boolean () () (Docker container) 3.conf/lsf.cluster
添加$your-host-name ! ! 1 3.5 () () (docker) 4./conf/lsbatch/$clustername/configdir/lsb.applications
添加Begin Application NAME = app1 CONTAINER = docker[image(ubuntu:latest) options(--rm --network=host --ipc=host -v /etc/passwd:/etc/passwd -v /etc/group:/etc/group) starter(root)] DESCRIPTION = Test Docker Application Profile 1 End Application 5.badmin reconfig 验证是否可用 3 验证 在非 root 用户下, bsub -app app1 -I cat /etc/lsb-release
DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS" 4 部署常见问题 1.badmin reconfig 出现 …

kubernetes 源码阅读--垃圾回收

Table of Contents1. 前言1.1. 代码参考1.2. 简要说明1.3. gc 设计文档1.4. gc 触发条件1.5. 代码详解1.5.1. pod 的删除1.5.2. podcontainerdeletor1.5.3. kuberuntimegc 1 前言 k8s 是一个异步的调度系统,当一个资源生命周期结束,内部的垃圾回收机制是如何运行的呢? 1.1 代码参考 v1.14.0-alpha.3 commitid: cd9e590178c9f3812e296484b587de1c79461033 1.2 简要说明 这里仅对 pod 以及 容器 的删除做了简要的说明
k8s 的垃圾回收机制逐渐向 evict 模块移动而不是直接放在 kubelet 中
垃圾回收作为整个系统的分支而不是核心部分,虽然刚刚开始;
之后也许会有 GCI 这种东西出现(虽然 Runtime 这个接口中已经有了) 1.3 gc 设计文档 k8s GC 设计文档可以参考下面链接
https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/proposals/garbage-collection.md
https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ 1.4 gc 触发条件https://kubernetes.io/docs/concepts/cluster-administration/kubelet-garbage-collection/
通过查看这个文档可以发现,旧的 gc 机制正在逐渐被被新的 evict 机制所取代
1.5 代码详解 1.5.1 pod 的删除 kubelet 启动时会启动 syncLoop 来处理 file、apiserver、http 这三个 channel 的变化
详细的变化处理可以看 kubelet.go 的 1872 行 syncLoopIteration 的定义
HandlePodRemoves 作为 SyncHandler 的回调,会调用 deletePod 来删除 pod
这里注意 1728 行注释提及的内容
这里会发送信号给 podKillCh 这个 channel
podKille…

k8s 源码阅读 -- eventf

Table of Contents1. 前言1.1. 代码参考1.2. 代码详解1.2.1. 结构定义1.2.2. 实际使用时的流程1.2.3. Event 在 kubelet 内部的工作流程 1 前言 k8s 是如何记录事件的
在 k8s 中 event 的记录追根溯源都是来自 client-go/tools/record/event.go 下的 EventRecorder 接口 1.1 代码参考 v1.14-alpha.2 k8s.io/kubernetes/staging/src/k8s.io/client-go/tools/record/ 1.2 代码详解 1.2.1 结构定义 在 event.go 中定义了 Eventsink EventRecorder EventBroadcaster 这三个接口
eventBroadcasterImpl 和 recorderImpl 这两个结构体

在 recorderImpl 下实现了几个函数
在 eventBroadcasterimpl 下实现了几个函数
1.2.2 实际使用时的流程 在 kubelet 启动时逐层调用
Newkubeletcommand => Run => run
这段代码可以在 /cmd/kubelet/app/server.go 下找到
这里我们不关心 kubelet 启动时做了什么,直接来看 event 相关的工作逻辑
在 629 行, 使用了 makeEventrecorder 这个函数
先初始化 eventBroadcasterImpl
然后 recorderImpl 初始化,并赋值给 kubeDeps.Recorder
如果需要记录日志,则直接使用 Eventf 记录日志;如下图
1.2.3 Event 在 kubelet 内部的工作流程 内部的工作流程发生在初始化 eventBroadcasterImpl 的时候
默认的参数如下
]
watch.NewBroadcaster(maxQueuedEvents, watch.DropIfChannelFull)
NewBroadcaster 用来创建一个新的 Broadcaster
Broadcaster 开了一个 goroutine 用来将对应的所有的 Broadcasterwatcher 注册进来,而且并不会结束
这样保证 Broad…

我为什么不喜欢 CoreOs/Operator

Table of Contents1. Operator 是什么2. 一3. 二4. 三5. 四6. 五7. 六8. 七9. 参考资料 1 Operator 是什么 如果你还没有看过 coreos 的 operator,可以到 这里 进行一个短暂的阅读 2 一 目前的 operator 是一个处于实验性、尚不成熟的运维经验流程化的方法论 3 二 operator 在文档中描述的能力: 打包、部署、管理 kubernetes 应用
在文档中列出了几个项目:
etcd-operatorrookprometheusvault 4 三 拿 etcd-operator 来说,他实际上做了什么呢
1.输入 版本与集群规模创建/删除一个 etcd 集群
2.调整一个集群的大小
3.在 pod 意外丢失时重现创建
4.oprator 在被删除后的恢复 (与 4 相同)
5.升级 etcd 的版本
6.备份和恢复 etcd 集群
看起来是符合 operator 中描述的能力,但实际呢
实际上他仅能满足字面上的最小能力
如果我需要的的是仅在特定几台机器(小于集群规模且无统一标签)上的 etcd 集群呢?
如果我要在更换 etcd 的证书呢
如果我要将备份的数据存储到非 aws 的存储呢
有太多他做不到的事情了 5 四 可能会有人认为,太多的自定义需求只要实现一个符合自己需求的 operator 不就可以了吗?
那么思考下面几个问题
1.谁来写这个 operator
2.写好了 operator 之后就能满足未来所有的需求吗
3.这个 operator 如何进行交接 6 五 假设有这样一个人,有着丰富的运维经验,又愿意遵循着这样的规范来完成一个 operator
在一个人可以将运维经验抽象成一个 operator 这么长的时间内,他连一个用来简化操作的的脚本都没有写过吗?
当他学习了 operator 的 sdk 然后,将自己平时使用的脚本中的逻辑以 operator 的方式放到了集群中
新来的同事问他,这个服务该怎么运维啊
他会说
A.你看一下这个服务 operator 的使用文档
B.你要先明白这个服务的配置文件该怎么写 7 六 operator 最大的矛盾是减少运维学习成本与保障服务稳定必须足够了解之间的矛盾
开发人员应该对写的代码负责,同样的是运维人员也要对维护的服务负责
operator …