博文

在 LSF 中使用 docker 运行任务

Table of Contents1. 环境信息2. 修改配置文件在 lsf 上启用 docker3. 验证4. 部署常见问题5. 部署参考链接 1 环境信息 docker 18.09.5
Kernel Version: 3.10.0-862.11.6.el7.x8664
lsf 10.1.0.6
OS CentOs 7.6.1810 2 修改配置文件在 lsf 上启用 docker 1.conf/lsf.conf
添加/修改
LSFPROCESSTRACKING=Y
LSFLINUXCGROUPACCT=Y
LSBRESOURCEENFORCE="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)]
EXECDRIVER = context[user(demo)] starter[/opt/apps/lsf/10.1/linux2.6-glibc2.3-x8664/etc/docker-starter.py] controller[/opt/apps/lsf/10.1/linux2.6-glibc2.3-x8664/etc/docker-control.py] monitor[/opt/apps/lsf/10.1/linux2.6-glibc2.3-x8664/etc/docker-monitor.py]
DESCRIPTION = Test Docker Application Profile 1
End Application
5.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 …

k8s 源码阅读 -- eviction

图片
Table of Contents1. 前言2. 资料3. 代码详解3.1. 代码参考3.2. 详细 1 前言 在某些情况下 k8s 会出现 evicted 的 pod, 然而这并不在 pod 的生命周期中.这就是 k8s 的驱逐机制。
当机器的一些资源(内存、磁盘)过小时,为了保证 node 不会受到影响,会将 pod 驱逐至其他的机器上 2 资料 可以在 这里看到相关资料
来看一下代码中,驱逐策略是怎样实现的 3 代码详解 3.1 代码参考kubernetes release-1.10 3.2 详细 pkg/kubelet/apis/kubeletconfig/v1beta/default.go
定义了这几个默认值作为阈值
pkg/kubelet/kubelet.go
kubelte 初始化了 eviction manager
在 runtime 相关模块被加载时,eviction manager 被加载进来
开始了 evict 相关的控制循环
接下来是 evict 真正工作的代码
代码目录是 pkg/kubelet/eviction/
主要看该目录下的两个文件 evictionmanager.go helpers.go
pkg/kubelet/eviction/evictionmanager.go
Start 是 evict manager 的入口
这里是一个死循环
循环中的主要函数是 synchronize 用来清理 pod、同步信息。这个就是今天的主角
先看一下 synchronize 的参数 diskInfoProvider podFunc
diskInfoProvider 是一个接口,用来提供磁盘的信息,作为是否发生驱逐的依据。实际函数在 pkg/kubelet/stats/ 下
synchronize 中仅用到了 HasDedicatedImageFs
podFunc 用来获取一个待检查的 pod 列表,实际函数在 pkg/kubelet/kubeletpods.go
首先检查 imagesfs, 数据从 cadvisor 中获取
获得容器信息和 kubelet 总计状态
summaryProvider 的实际函数在 /pkg/kubelet/server/stats/summary.go
开始监视当前的系统状态
监视这些数据 Node.Memory al…

计算机网络基础 DNS

图片
什么是 DNS DNS 全称 Domain Name System,即域名系统 域名系统的出现使得人类可以更加方便的到达目的地,而不需要记住 IP。域名更符合人类的语义化,让人更加容易的记住。
常用的记录 A 记录      用于将特定的主机名映射到对应的主机 IP CNAME   用于将某个别名指向某个 A 记录上 AAAA      IPv6 的 A 记录 SRV          记录用来标识某台服务器使用了某个服务  NAPTR    使用正则映射一个域名 DNS 工作原理 在考虑一个域名是如何转换成 IP 之前,先了解几件事情 DNS 本质上是一个层次结构的分布式数据库DNS 的域有着明确的划分目前全球一共有 13 组根域名(TLD)服务器DNS 缓存时间由记录的 TTL 决定
Tips: 在有转发设置时域名有下至上查询在无转发设置时本地域名服务器先向根域名服务器请求,由上向下查询域名服务器存在缓存,优先查找缓存
DNS 污染 GFW 的技术之一就是 DNS 污染 总体来说:是将符合规则的域名解析到虚假的 IP 地址中,导致墙内用户通过域名无法获取到正确的 IP 1.使用加密代理的远程 DNS 2.修改 hosts

从一条简单的 URL 开始

从代码开始 先来看一段代码 from flask import Flask, g, request from functools import wraps app = Flask(__name__) def set_g(f): @wraps(f) def decorator(*args, **kwargs): g.auth = 'zadmin' g.scope = 5 g.num = 0 return f(*args, **kwargs) return decorator def check_auth(f): @wraps(f) def decorator(*args, **kwargs): auth = g.auth if auth != "admin": print "Failed in auth" g.num = 20 return f(*args, **kwargs) return decorator def check_scope(f): #@wraps(f) def decorator(*args, **kwargs): ''' This check scope docker string ''' scope = g.scope if scope not in [1, 2, 3]: print "Failed in scope" g.num = 10 return f(*args, **kwargs) return decorator @app.route('/test') @set_g @check_auth @check_scope def test(): ''' This is function test''' …