SlideShare a Scribd company logo
1 of 49
容器集群编排与
Kubernetes 原理剖析
LARGE-SCALE CONTAINER CLUSTER MANAGEMENT
& DEEP DIVE INTO KUBERNETES
About Me
• @resouer
• Lei (Harry) Zhang
• Phd & Researcher @ZJU
• Contributor
• Former: Baidu, VMware
• Publish:
– Docker & Kubernetes Under The Hood
Contents
• 深入理解容器(以 runc 实现为
例)
• Borg 的大规模集群管理经验
• Kubernetes 的原理与实现
深入理解容器
第一部分
注:除非特殊说明,“容器”均指代 OpenContainer 组织的 runc 实现
进程 101
• 静态视角
– 程序:代码和数据的集合
• 表现为:磁盘上的可执行镜像( Executable
Image )
• 动态视角
– 进程:程序运行起来的执行环境的总和
• 表现为:指令与数据、寄存器值、堆栈、被打开文
件数、 I/O 设备状态等信息的动态变化
容器 101
• 静态视角
– 镜像:程序、数据以及它们所依赖的所有文件、目录和配置的集合
– 表现为: rootfs
• 文件系统结构和 library
• 目录: /dev /proc /bin /etc /lib /usr /tmp
• 指令: sh ls cp mv etc...
• 配置: rc inittab fstab etc...
• 设备: /dev/hd* /dev/tty* /dev/fd0 etc...
– 为了避免每个进程都需要 build 一个 rootfs :“层”和 unionfs
• 动态视角
– 容器:程序运行起来的执行环境的视图和边界
– 表现为:?
容器 201 : docker run
Docker DaemonDocker Daemon
Container
•镜像 ID
•网络配置
•Volumes
•其他 docker run 参数
Container
•镜像 ID
•网络配置
•Volumes
•其他 docker run 参数
Command
•Resources : cgroup 配置
•InitPath : dockerinit 的位置
•Process :
• Entrypoint + Args
• e.g. /bin/sh –c echo hello
•Rootfs
•其他容器参数,比如网络, Mounts
等
Command
•Resources : cgroup 配置
•InitPath : dockerinit 的位置
•Process :
• Entrypoint + Args
• e.g. /bin/sh –c echo hello
•Rootfs
•其他容器参数,比如网络, Mounts
等
生
成
生
成
Libcontainer(runc)Libcontainer(runc)
linuxContainer
•dockerinit
•Config
• Cgroups
• Namespaces
• 默认 NS
• 用户指定的 NS
• Mounts
• 其他 Command 中的容
器相关参数
linuxContainer
•dockerinit
•Config
• Cgroups
• Namespaces
• 默认 NS
• 用户指定的 NS
• Mounts
• 其他 Command 中的容
器相关参数
Process
•Entrypoint + Args
•Env
•User
•Work dir
Process
•Entrypoint + Args
•Env
•User
•Work dir
$ docker run ubuntu “echo hello”
Docker DaemonDocker Daemon
容器 201 : docker run
libcontainerlibcontainer
initProcess (父进程)
•Pipes : childPipe, parentPipe
•Cmd
• dockerinit
• childPipe
• Cloneflags
•Cgroups
•Config
• Process (Entrypoint + Args)
• LinuxContainer.Conifg
initProcess (父进程)
•Pipes : childPipe, parentPipe
•Cmd
• dockerinit
• childPipe
• Cloneflags
•Cgroups
•Config
• Process (Entrypoint + Args)
• LinuxContainer.Conifg
LinuxContainer.start(Process)
linuxContainer
•dockerinit
•Config
linuxContainer
•dockerinit
•Config
Process
•Entrypoint
•Args
Process
•Entrypoint
•Args
initProcessinitProcess
容器
dockerinitdockerinit
Cmd.start
1
2
将 dockerinit
的 PID 加入
Cgroups
创建容器内网
络设备:
lo , veth
发送 Config
给容器
准备 pipe
按照容器 config 初
始化内容和 rootfs
Pipes
EntrypointEntrypointInit()Init()
执行用户指令
Pipes
close pipe
execv
所以,容器的动态表现是
• 一个自带“世界观”的进程
– namespaces :视图
– pivot_root 和 cgroups :边界
– 三层文件系统: RW layer , init-layer , read-only layers
FROM ubuntu:latestFROM ubuntu:latest
VOLUME /dataVOLUME /data
Copy-On-Write & /dataCopy-On-Write & /data
“echo hello”
namespace cgroups
或者 hyper , novm
read-only layer
/bin /dev /etc /home /lib /lib64
/media /mnt /opt /proc /root /run
/sbin /sys /tmp /usr /var /data
/etc/hosts /etc/hostname /etc/resolv.confinit-layer
read-write layer
/var/lib/docker/
volumes/<volume_id>/_data
container/<container_id>/hosts
container/<container_id>/resolv.conf
container/<container_id>/hostname
aufs/mnt
从 BORG 谈容器集群编排
第二部分
Borg : http://research.google.com/pubs/pub43438.html
从单机到集群
• 多任务单机操作系统
• 进程隔离
– 每个进程有自己的虚拟地址
空间
– 进程间使用 IPC 通信
• 单机资源共享
– 资源对象
• CPU
• 物理内存
• 文件
• 外部设备
– 并发:进程上下文切换
• 兼顾公平与高效的调度
• 多容器集群数据中心
• 进程 + 环境隔离
– 环境隔离与资源边界: namespaces
和 cgroups
– 容器间通信:网络方案
• 集群资源共享
– 资源对象:机器(或资源包)
– 在机器内部才考虑单机资源共享
• CPU ,物理内存,文件,外部设备,并发,公平
调度
• 兼顾公平、高效、利用率、能耗
、访问延时的调度
• 机器规模是关键
容器集群管理中的问题
1. 任务分类与优先级?
2. 提升利用率?
3. 允许抢占的调度?
4. 如何评估调度算法?
5. 调度策略优化?
6. 是否混部的权衡?
问题一:容器的分类
• LRS ( Long Running Service )
– “ 死循环”,比如一个 Web 服务
– 需要立刻响应用户的请求,时延敏感
– 高优先级或生产环境级( prod )
• batch jobs
– Map-Reduce ,或者其它类似的计算任务
• 它们的执行往往需要持续一段时间,但是最终都会
停止
– 对服务器瞬时的性能波动不敏感
– 低优先级( non-prod )
容器分类举例
• 监控级、生产级、批任务级、尽力级(也
叫测试级)
– 监控级和生产级: prod 任务
• prod 任务可以抢占非 prod 任务的资源
• prod 任务不能互相抢占
– 避免触发连锁反应( A 抢占 B , B 抢占 C , C
再抢占 D )
问题二:提升利用率
by LeanCloud 陈伟, Docker Meetup
资源边界
• cgroups 只是资源边界
– 只有在资源申请试图超出限额时才发挥作用
– 所以一台机器理应运行更多的容器
• 但是,我们必须有合理的判断依据来决定“
这台机器尚能运行多少个新容器”
– 硬指标: 4G 机器, 1G 的任务,还剩 3G
– 超卖: 4G 的机器, 1G 的任务,还剩 4G*2-
1G=7G
– 有没有更好的做法?
宿主机: 10G
可用: 6G
宿主机: 10G
可用: 6G
动态资源边界
4G
容器 A
4G
容器 A
资源回收事件
宿主机: 10G
可用: 9G
宿主机: 10G
可用: 9G
回收资源: 3G回收资源: 3G
1G
容器 A
1G
容器 A
• 宿主机默认按照动态边界计算自己的可用资源
• 如果容器资源使用超出 1G :迅速恢复资源边界到初始值(比如 4G )
• prod 级别的容器永远只使用现有容器的原始边界计算可用资源,而非
动态边界
• 效果:将近一半的集群减少了 30% 的机器
资源回收事件
• 容器启动成功并运行 300s 后
– 减少该容器资源边界
• 机器某种资源的可用值不足(比如流量激
增)
– 可压缩资源,比如 CPU 周期和磁盘 I/O 带宽
• 热回收,调节 LRS 容器的容器边界
– 如若达不到目的,触发重调度事件,移除部分容器
– 不可压缩资源,比如内存和磁盘空间
• 只能按优先级从低到高杀死容器,直到恢复合理的
可用值
安全余量
• 安全边界 = 实际资源使用量 + 可配置的安全余量
• 方法:以集群为单位,通过实验获得该集群的合理余量
– 给定不同的安全余量值
– 观察不同余量下资源 margin 和 OOM 次数在一段时间内的的变化
– 选取平衡点的余量值
资源 margin
问题三:允许抢占的调度
• 第一,可行性检查
– Node 是否满足容器资源需求
• 可用资源 = 机器容量 – 所有容器的边界 + 可以抢占的容器的资源
– 是否满足自定义约束(比如指定的磁盘类型)
– 得到候选机器列表
• 第二,打分
– 尽量避免发生资源抢占;如果避免不了,则让被抢占的容器数量
最少、优先级最低
– 挑选容器依赖更完备的机器(比如 package 完备,已经 pull 过所
需的镜像)
– 使容器尽量分布在不同的高可用域当中
– 尽量混合部署不同优先级的容器
• 流量峰值突然出现后便于回收资源
问题四:如何评估调度算法
• 压缩实验
– 不断减少集群中机器的数量(“压缩”),然后
重调度某个指定的容器到该集群,直到它再也
不能正常调度运行在这个集群上
• 结果: 最小工作集群
• 调度算法越优秀,对于同一个容器来说它
最后得到的最小集群单元中的机器数就越
少
问题五:调度策略优化
• 缓存机器的打分结果
– 只有当机器本身信息或者容器发生了变化(比如容器数目或者容
器边界)时,才更新缓存的机器分数
– 忽略那些不太明显的变化,减少缓存的更新次数
• 划分容器组(等价类)
– 为一组需求和约束都一样的、亲密关系的容器执行调度过程,而不是单
个容器
• 随机选择一组机器来做可行性检查,而不是整个集群
– 随机挑选一个机器来检查可行性,判断是否通过,再挑选下一个
,直到通过筛选的机器达到预设的数目,返回之作为候选机器列
表
– 参见 Sparrow调度器
• 效果:极端情况可能耗时几天的任务 -> 几百秒
问题六:是否混部的权衡
• LRS 和 batch job 分开部署:
– 需要额外增加 20%-30% 的机器
• 不同用户的容器分开部署:
– 需要额外增加 20%-150% 的机器
• 共享带来的 CPU 性能损失: 3%
– CPI ( cycles per instruction )
– 每增加一个容器,其他任务的 CPI 增加 0.3%
• 权衡:减少的机器数量 VS CPU 性能损失
KUBERNETES 原理与实现
第三部分
Kubernetes
1. k8s 是 Borg 的开源实现吗?他俩什么关系
?
2. K8s 的架构?
3. 怎么部署 Kubernetes ?
4. Pod 的作用?
5. Pod 的调度策略?
6. 如何创建一个 Pod ?
7. Pod 如何被访问到?
8. k8s 提供跨主机网络不?
Kubernetes 核心结构
部署 1 : k8s in docker
MasterMaster WorkerWorker
docker daemondocker daemon docker daemondocker daemon
docker-bootstrap daemon
--iptables=false
docker-bootstrap daemon
--iptables=false
docker-bootstrap daemon
--iptables=false
docker-bootstrap daemon
--iptables=false
flanneldflanneld etcdetcd flanneldflanneld
kubeletkubelet
kube-
proxy
kube-
proxy
kubeletkubelet
kube-
proxy
kube-
proxy
mastermaster
2
1
• 优点:快速,无依赖, self-deploy ,操作系统无关,适合开发环境或小型集群
• 缺点:不方便与现有系统集成,需要登录到每台机器上执行脚本
• 见: <k8s>/getting-started-guides/docker-multinode.md
mastermaster
mastermaster
部署 2 : ubuntu cluster
1. 编译出 kubernetes , etcd, flanneld 二进制文件
2. 规划集群:
3. 部署:
• 优点:一键部署,适合一定规模的集群,符合 k8s e2e test 规范,便于同现有
运维系统集成
• 缺点:只支持 Ubuntu ,暂不支持 systemd
• 见: <k8s>/docs/getting-started-guides/ubuntu.md
IP Address Role
10.10.103.223 node
10.10.103.162 node
10.10.103.250 both master and node
export nodes=vcap@10.10.103.250 vcap@10.10.103.162 vcap@10.10.103.223
export role="ai i i“
export NUM_MINIONS=${NUM_MINIONS:-3}
export SERVICE_CLUSTER_IP_RANGE=192.168.3.0/24
export FLANNEL_NET=172.16.0.0/16
KUBERNETES_PROVIDER=ubuntu ./kube-up.sh
Why Pod
• Pod
– IP 、 port 等网络资源的分配的基本单位
– 共享存储卷 volume
– 共享 namespace
• pid, network, ipc, uts
• 两个典型场景:
– Kubernetes 的 Master 组件
• ./apiserver --address=0.0.0.0
• ./scheduler --master=127.0.0.1:8080
• ./controller-manager --master=127.0.0.1:8080
– 一个应用容器和它的日志转发器
• Web app
• log aggregator
apiserverapiserver
schedulerscheduler
controller-
manager
controller-
manager
But wait …
• Pod 并不是一组容器的简单集合或者集群
• Pod 是 Kubernetes 世界观里的“容器”
– Lessons learned from Borg
– 成规模场景下的任务组织形式
• Pod :进程组
• 容器 :进程
– 超亲密关系
– 地位对等
– 共同决定 Pod 状态
containers:
- name: container A
- name: container B
restartPolicy:
- string: {}
volumes:
- name: string
source: emptyDir | HostDir
emptyDir: {}
hostDir:
path: string
如何创建 Pod ?
V0.16.2
V0.16.2
Scheduler 默认策略
• 完全插件化
• Predicates :筛选出合格的 Node
– 容器申请的主机端口是否可用
– 可用 CPU 和内存是否满足 Pod 里的需求
• 不支持抢占机制,不关注利用率
– host volume 目录是否冲突
– 是否匹配用户指定的 Label
– 是不是指定的 hostname
• Priorities :对通过上述筛选的 Node 打分
– 选择资源空闲更多的机器
– 选择调度完成后 CPU 和内存利用率更平衡的机器
– 属于同一个任务的副本 Pod 尽量分布在不同机器上
V0.16.2
V0.16.2
Scheduler 如何采集信息?
• 向 API Server 请求信息( 10s ),有 client 缓存机制
• 两种数据更新方法
– Reflector :监测( watch )对象变化
– Poller :抓取不支持 etcd watch 操作的 api 对象
数据描述 采集方法 数据对象 client 缓存类型
所有未调度的 pod Reflector podQueue queue
所 有 已 调 度 运 行 的
pod
Reflector podLister cache
所有可用的 minion Poller MinionLister cache
所有 service 对象 Reflector ServiceLister cache
V0.16.2
V0.16.2
SyncPods
pods
pod nodeName
pod nodeName
新版 kubelet
schedulerscheduler APIServerAPIServer
POST /binding
pod node list
RunKubelet
Pods with pod.host == nodeName
watch (三种源)
startKubeletstartKubelet
Pods
statusManagerstatusManager
Pod.status
Pod
SyncPods
Container
Manager,
Cadvisor
…
Container
Manager,
Cadvisor
…
managePod
Loop
managePod
Loop
managePod
Loop
managePod
Loop
managePod
Loop
managePod
LoopWorker
update
Pod
Pods 合法
性检查
Pod
Pod
V1.0V1.0
SyncPod : Pod vs 现有 Pod
1.创建 Pod 数据目录
2.创建 API 实体
3.mount Volume
4.更新 status
DockerManager
1.遍历 Pod 中的
Containers
2.pull 镜像
3.生成 Docker 参数
4.启动容器
期望状态
RC:
replica: 2
selector:
‘label’ : ‘test’
// pod definition …
如何控制 Pod ?
• Controller Manager
– Replication Controller (RC)
– 检测循环( 10s ):
期望状态
RC:
replica: 2
selector:
‘label’ : ‘test’
// pod definition …
Diff
•期望的 replica 值
•查询到的 Pod 数量
APIserver
etcdetcd
1. label 匹配
2. 选择状态不为
podFailed 的 Pods
create/delete Pod
fetch with Reflector cache
如何访问 Pod ?
• Service :
– Portal ,提供访问 Pod 的固定入口( portal_ip :
port )
– 多个副本 Pod 的动态 Load Balancer
– 适合强依赖于 IP 的业务
NAME SELECTOR IP PORT
…
service-nginx name=nginx 11.1.1.88 800111.1.1.88:800111.1.1.88:8001
Label:
name=nginx
Pod A-1
Label:
name=nginx
Pod A-1
Label:
name=nginx
Pod A-2
Label:
name=nginx
Pod A-2
Label:
name=nginx
Pod A-3
Label:
name=nginx
Pod A-3
Endpoint
NodeNode
Service
NodeNode
// 请求发起自容器: PREROUTING
target prot opt source destination
…
REDIRECT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 redir ports 43318
// 请求发起在 HOST : OUTPUT
target prot opt source destination
…
DNAT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 to:10.10.103.58:43318
// 请求发起自容器: PREROUTING
target prot opt source destination
…
REDIRECT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 redir ports 43318
// 请求发起在 HOST : OUTPUT
target prot opt source destination
…
DNAT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 to:10.10.103.58:43318
11.1.1.88:800111.1.1.88:8001
kube-proxy
ProxierProxier
4331843318
LoadBalancerLoadBalancer
Pod 地址 : 端口
根据 etcd 中 Service 的增删创建并维护规则
Request
etcdetcd
1. Service 变化
2. Endpoint 变化
Pod 地址 : 端
口
bi-directionally io.Copy
Round-Robin
Session Affinity
Service
• portalIP 仅在集群范围内的机器上有效
– publicIP (使用机器的 public IP 做 portalIP )
– 外部 LoadBalancer
• 大规模 & 高并发场景下的担忧
– 可能的瓶颈:
• userspace 的 Proxier ( 已经 Fixed ,需要 iptables 1.4.0)
• iptables 更新耗时
– 可选替换: cloudfoundry/gorouter ,
flynn/flynn/router , HAproxy
• 监视: <master:port>/api/v1beta3/watch/pods ,更新 Server Pool
• 缺点:
– 不能有效提供 portal_ip
– 需要域名依赖或者端口管理
Host A
pod_1pod_1
Host B
pod_1pod_1pod_2pod_2
pod_1.mydomain.com
LBLB
如何创建 Service ?
V0.16.2
V0.16.2
如何控制 Service ?
• Controller Manager
– Service Controller :使用真实状态更新 Service
– 检测循环:
• 遍历所有 Service
– 根据 label ,查询出 Pod 列表(真实状态)
– 该 Service 持有的 Endpoint 列表(期望状态)
– Diff
– 有差异:
删除多余的 Endpoint
或者检查实际状态列表的资源版本号
等于 0 ,真实 Pod 并没有出现在 Endpoint 列表中,
创建该 Endpoint
不等于 0 ,更新该 Endpoint
Pod 网络:单 Pod 单 IP 模型
pausepause
Container AContainer A Container BContainer B
--net=container:pause
/proc/{pid}/ns/net -> net:[4026532483]
• 网络容器( infra 容器)
– 使用 docker0 网桥作为默认网关,并且被分配该网桥上的一个 IP
地址作为所有容器共享的 IP 地址
Kubernetes 的网络假设
1. 容器之间可以跨主机通信,无需经过 NAT
2. 所有主机与容器之间可以直接通信,无需
经过 NAT
3. 容器本身看到的自己的 IP 地址与其他容器
看它的 IP 地址是一样的
但是, Kubernetes 本身对上述假设不做任何
实现
e.g. Flannel SocketPlane Calico OVS macvlan ipvlan ...
典型的网络实现
• 两条基本原则
– 绝大部分 Docker 跨主网络方案均可以满足上述“网络假设”
– 可以随意更改 Daemon 的配置、启动参数,但是 Kubernetes 目前必须使
用标准 Docker API
• docker run … √
• my_tool run … ×
• API 不一致,使用 Powerstrip 进行转义 :
https://github.com/ClusterHQ/powerstrip
kubeletkubelet
PowerstripPowerstrip
docker run
my_tool run
抛砖引玉
• Flannel
– overlay 网络, UDP 封装或者 VxLAN 封装
– 用 Docker 启动 flanneld 后配置 DOCKER_OPTS 的 --bip 即可
– 简单,稳定,但没有划分多个隔离域的能力
• Weave
– 通过 ambassador 容器抓取链路层流量,使用 UDP 转发该报文到目的端
• SocketPlane
– OVS 的功能性封装,使用 GRE/VxLAN 隧道
– 使用 Powerstrip
– Hack :修改 kubelet ,在启动 infra 容器时添加” SP_NETWORK=xxx” 环境变量
Qperf test Flannel
UDP
Flannel
VxLAN
Weave Socketplane Native
TCP
bandwidth
28.7 MB/s 47.8 MB/s 3.75 MB/s 42.8 MB/s 62.5 MB/s
TCP latency 200 µs 127 µs 384.4 µs 110.9 µs 96.1µs
Kubernetes VS 小伙伴们
• 祖师: Borg
– 专注于支撑成规模的企业服务并且最大程度地提高资
源利用率
• Kubernetes
– 典型的容器集群管理工具(类似 Swarm ),但基本单
位是 Pod
– 暂时不关注资源抢占和任务混部,以及资源利用率提
升
– K8S 大量借鉴了 Borg 的优秀思想、架构、甚至代码实
现,但并不能说就是 Borg 的开源实现
– Goal :” run your container workload at scale”
Kubernetes VS 小伙伴们
• Mesos
– 专注于 Scheduling 和资源抽象,需要同上层框架协作
– 良好的 framework 支持,适合作为基础依赖
– 适合大数据场景,非原生针对容器集群管理设计
– Goal: “I already have a Layer 1 (business or platform layer), but I need
Layer 0 (infrastructure layer) to run it on cluster“
• Flynn Deis Marathon + Mesos Cloud Foundry OpenShift
– 更类似 PaaS
– “ 从代码,到可运行制品,再到运行实体”
– 低用户自由度,高自动化程度
• Compose + Swarm
– 最 Docker 友好的容器集群管理工具
– 最原生的 Docker 支持 = vendor lock in
– 缺乏成规模集群管理的 vision
Further Contact
• www.sel.zju.edu.cn
• harryzhang AT zju.edu.cn
• @ 柳烟堆雪
Large-Scale Cluster Mangement & Kubernetes Under The Hood

More Related Content

What's hot

廣宣學堂: 企業導入微服務實戰
廣宣學堂: 企業導入微服務實戰廣宣學堂: 企業導入微服務實戰
廣宣學堂: 企業導入微服務實戰Paul Chao
 
Golang advance
Golang advanceGolang advance
Golang advancerfyiamcool
 
Software Engineer Talk
Software Engineer TalkSoftware Engineer Talk
Software Engineer TalkLarry Cai
 
CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)
CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)
CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)Jian-Kai Wang
 
Docker tutorial
Docker tutorialDocker tutorial
Docker tutorialazole Lai
 
20150604 docker 新手入門
20150604 docker 新手入門20150604 docker 新手入門
20150604 docker 新手入門azole Lai
 
DAE 新变化介绍
DAE 新变化介绍DAE 新变化介绍
DAE 新变化介绍Tianwei Liu
 
開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018
開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018
開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018Will Huang
 
AWS EC2 for beginner
AWS EC2 for beginnerAWS EC2 for beginner
AWS EC2 for beginnerazole Lai
 
Introduction to Docker
Introduction to DockerIntroduction to Docker
Introduction to DockerChris Chen
 
Docker Compose
Docker ComposeDocker Compose
Docker ComposeMiles Chou
 
深入Docker的资源管理
深入Docker的资源管理深入Docker的资源管理
深入Docker的资源管理SpeedyCloud
 
基于Fuel的超融合一体机
基于Fuel的超融合一体机基于Fuel的超融合一体机
基于Fuel的超融合一体机EdwardBadBoy
 
Design realization and application of RBD NBD - Wang Li
Design realization and application of RBD NBD - Wang LiDesign realization and application of RBD NBD - Wang Li
Design realization and application of RBD NBD - Wang LiCeph Community
 
RxJS 6 新手入門
RxJS 6 新手入門RxJS 6 新手入門
RxJS 6 新手入門Will Huang
 
Ceph in UnitedStack
Ceph in UnitedStackCeph in UnitedStack
Ceph in UnitedStackRongze Zhu
 
Golang 高性能实战
Golang 高性能实战Golang 高性能实战
Golang 高性能实战rfyiamcool
 
Deployment with Capistrano
Deployment with CapistranoDeployment with Capistrano
Deployment with Capistrano旭 張
 
Serverless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolongServerless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolongStreamNative
 

What's hot (20)

廣宣學堂: 企業導入微服務實戰
廣宣學堂: 企業導入微服務實戰廣宣學堂: 企業導入微服務實戰
廣宣學堂: 企業導入微服務實戰
 
Golang advance
Golang advanceGolang advance
Golang advance
 
Software Engineer Talk
Software Engineer TalkSoftware Engineer Talk
Software Engineer Talk
 
Docker應用
Docker應用Docker應用
Docker應用
 
CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)
CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)
CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)
 
Docker tutorial
Docker tutorialDocker tutorial
Docker tutorial
 
20150604 docker 新手入門
20150604 docker 新手入門20150604 docker 新手入門
20150604 docker 新手入門
 
DAE 新变化介绍
DAE 新变化介绍DAE 新变化介绍
DAE 新变化介绍
 
開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018
開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018
開發人員必須知道的 Kubernetes 核心技術 - Kubernetes Summit 2018
 
AWS EC2 for beginner
AWS EC2 for beginnerAWS EC2 for beginner
AWS EC2 for beginner
 
Introduction to Docker
Introduction to DockerIntroduction to Docker
Introduction to Docker
 
Docker Compose
Docker ComposeDocker Compose
Docker Compose
 
深入Docker的资源管理
深入Docker的资源管理深入Docker的资源管理
深入Docker的资源管理
 
基于Fuel的超融合一体机
基于Fuel的超融合一体机基于Fuel的超融合一体机
基于Fuel的超融合一体机
 
Design realization and application of RBD NBD - Wang Li
Design realization and application of RBD NBD - Wang LiDesign realization and application of RBD NBD - Wang Li
Design realization and application of RBD NBD - Wang Li
 
RxJS 6 新手入門
RxJS 6 新手入門RxJS 6 新手入門
RxJS 6 新手入門
 
Ceph in UnitedStack
Ceph in UnitedStackCeph in UnitedStack
Ceph in UnitedStack
 
Golang 高性能实战
Golang 高性能实战Golang 高性能实战
Golang 高性能实战
 
Deployment with Capistrano
Deployment with CapistranoDeployment with Capistrano
Deployment with Capistrano
 
Serverless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolongServerless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolong
 

Similar to Large-Scale Cluster Mangement & Kubernetes Under The Hood

Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)ykdsg
 
从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰
从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰
从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰Scourgen Hong
 
Web请求异步处理和海量数据即时分析在淘宝开放平台的实践
Web请求异步处理和海量数据即时分析在淘宝开放平台的实践Web请求异步处理和海量数据即时分析在淘宝开放平台的实践
Web请求异步处理和海量数据即时分析在淘宝开放平台的实践mysqlops
 
My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎frogd
 
海量日志分析系统实践,Dba
海量日志分析系统实践,Dba海量日志分析系统实践,Dba
海量日志分析系统实践,DbaCevin Cheung
 
ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1medcl
 
Docker一期培训
Docker一期培训Docker一期培训
Docker一期培训青帅 常
 
Nosql三步曲
Nosql三步曲Nosql三步曲
Nosql三步曲84zhu
 
百度系统部分布式系统介绍 马如悦 Sacc2010
百度系统部分布式系统介绍 马如悦 Sacc2010百度系统部分布式系统介绍 马如悦 Sacc2010
百度系统部分布式系统介绍 马如悦 Sacc2010Chuanying Du
 
Track2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewaveTrack2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewaveOpenCity Community
 
阿里云技术实践
阿里云技术实践阿里云技术实践
阿里云技术实践drewz lin
 
服务器基准测试-叶金荣@CYOU-20121130
服务器基准测试-叶金荣@CYOU-20121130服务器基准测试-叶金荣@CYOU-20121130
服务器基准测试-叶金荣@CYOU-20121130Jinrong Ye
 
Altibase管理培训 安装篇
Altibase管理培训 安装篇Altibase管理培训 安装篇
Altibase管理培训 安装篇小新 制造
 
Docker初识
Docker初识Docker初识
Docker初识hubugui
 
淘宝主备数据库自动切换
淘宝主备数据库自动切换淘宝主备数据库自动切换
淘宝主备数据库自动切换mysqlops
 
Install Oracle11g For Aix 5 L
Install Oracle11g For Aix 5 LInstall Oracle11g For Aix 5 L
Install Oracle11g For Aix 5 Lheima911
 
OpenStack and Docke Integration V6
OpenStack and Docke Integration V6OpenStack and Docke Integration V6
OpenStack and Docke Integration V6Guangya Liu
 

Similar to Large-Scale Cluster Mangement & Kubernetes Under The Hood (20)

Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)
 
从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰
从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰
从林书豪到全明星 - 虎扑网技术架构如何化解流量高峰
 
Web请求异步处理和海量数据即时分析在淘宝开放平台的实践
Web请求异步处理和海量数据即时分析在淘宝开放平台的实践Web请求异步处理和海量数据即时分析在淘宝开放平台的实践
Web请求异步处理和海量数据即时分析在淘宝开放平台的实践
 
My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎My sql 5.6新特性深入剖析——innodb引擎
My sql 5.6新特性深入剖析——innodb引擎
 
海量日志分析系统实践,Dba
海量日志分析系统实践,Dba海量日志分析系统实践,Dba
海量日志分析系统实践,Dba
 
ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1ElasticSearch Training#2 (advanced concepts)-ESCC#1
ElasticSearch Training#2 (advanced concepts)-ESCC#1
 
Docker一期培训
Docker一期培训Docker一期培训
Docker一期培训
 
Nosql三步曲
Nosql三步曲Nosql三步曲
Nosql三步曲
 
百度系统部分布式系统介绍 马如悦 Sacc2010
百度系统部分布式系统介绍 马如悦 Sacc2010百度系统部分布式系统介绍 马如悦 Sacc2010
百度系统部分布式系统介绍 马如悦 Sacc2010
 
Track2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewaveTrack2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewave
 
阿里云技术实践
阿里云技术实践阿里云技术实践
阿里云技术实践
 
服务器基准测试-叶金荣@CYOU-20121130
服务器基准测试-叶金荣@CYOU-20121130服务器基准测试-叶金荣@CYOU-20121130
服务器基准测试-叶金荣@CYOU-20121130
 
Altibase管理培训 安装篇
Altibase管理培训 安装篇Altibase管理培训 安装篇
Altibase管理培训 安装篇
 
Aswan&hump
Aswan&humpAswan&hump
Aswan&hump
 
Win dbg入门
Win dbg入门Win dbg入门
Win dbg入门
 
Windbg入门
Windbg入门Windbg入门
Windbg入门
 
Docker初识
Docker初识Docker初识
Docker初识
 
淘宝主备数据库自动切换
淘宝主备数据库自动切换淘宝主备数据库自动切换
淘宝主备数据库自动切换
 
Install Oracle11g For Aix 5 L
Install Oracle11g For Aix 5 LInstall Oracle11g For Aix 5 L
Install Oracle11g For Aix 5 L
 
OpenStack and Docke Integration V6
OpenStack and Docke Integration V6OpenStack and Docke Integration V6
OpenStack and Docke Integration V6
 

Large-Scale Cluster Mangement & Kubernetes Under The Hood

  • 1.
  • 2. 容器集群编排与 Kubernetes 原理剖析 LARGE-SCALE CONTAINER CLUSTER MANAGEMENT & DEEP DIVE INTO KUBERNETES
  • 3. About Me • @resouer • Lei (Harry) Zhang • Phd & Researcher @ZJU • Contributor • Former: Baidu, VMware • Publish: – Docker & Kubernetes Under The Hood
  • 4. Contents • 深入理解容器(以 runc 实现为 例) • Borg 的大规模集群管理经验 • Kubernetes 的原理与实现
  • 6. 进程 101 • 静态视角 – 程序:代码和数据的集合 • 表现为:磁盘上的可执行镜像( Executable Image ) • 动态视角 – 进程:程序运行起来的执行环境的总和 • 表现为:指令与数据、寄存器值、堆栈、被打开文 件数、 I/O 设备状态等信息的动态变化
  • 7. 容器 101 • 静态视角 – 镜像:程序、数据以及它们所依赖的所有文件、目录和配置的集合 – 表现为: rootfs • 文件系统结构和 library • 目录: /dev /proc /bin /etc /lib /usr /tmp • 指令: sh ls cp mv etc... • 配置: rc inittab fstab etc... • 设备: /dev/hd* /dev/tty* /dev/fd0 etc... – 为了避免每个进程都需要 build 一个 rootfs :“层”和 unionfs • 动态视角 – 容器:程序运行起来的执行环境的视图和边界 – 表现为:?
  • 8. 容器 201 : docker run Docker DaemonDocker Daemon Container •镜像 ID •网络配置 •Volumes •其他 docker run 参数 Container •镜像 ID •网络配置 •Volumes •其他 docker run 参数 Command •Resources : cgroup 配置 •InitPath : dockerinit 的位置 •Process : • Entrypoint + Args • e.g. /bin/sh –c echo hello •Rootfs •其他容器参数,比如网络, Mounts 等 Command •Resources : cgroup 配置 •InitPath : dockerinit 的位置 •Process : • Entrypoint + Args • e.g. /bin/sh –c echo hello •Rootfs •其他容器参数,比如网络, Mounts 等 生 成 生 成 Libcontainer(runc)Libcontainer(runc) linuxContainer •dockerinit •Config • Cgroups • Namespaces • 默认 NS • 用户指定的 NS • Mounts • 其他 Command 中的容 器相关参数 linuxContainer •dockerinit •Config • Cgroups • Namespaces • 默认 NS • 用户指定的 NS • Mounts • 其他 Command 中的容 器相关参数 Process •Entrypoint + Args •Env •User •Work dir Process •Entrypoint + Args •Env •User •Work dir $ docker run ubuntu “echo hello”
  • 9. Docker DaemonDocker Daemon 容器 201 : docker run libcontainerlibcontainer initProcess (父进程) •Pipes : childPipe, parentPipe •Cmd • dockerinit • childPipe • Cloneflags •Cgroups •Config • Process (Entrypoint + Args) • LinuxContainer.Conifg initProcess (父进程) •Pipes : childPipe, parentPipe •Cmd • dockerinit • childPipe • Cloneflags •Cgroups •Config • Process (Entrypoint + Args) • LinuxContainer.Conifg LinuxContainer.start(Process) linuxContainer •dockerinit •Config linuxContainer •dockerinit •Config Process •Entrypoint •Args Process •Entrypoint •Args initProcessinitProcess 容器 dockerinitdockerinit Cmd.start 1 2 将 dockerinit 的 PID 加入 Cgroups 创建容器内网 络设备: lo , veth 发送 Config 给容器 准备 pipe 按照容器 config 初 始化内容和 rootfs Pipes EntrypointEntrypointInit()Init() 执行用户指令 Pipes close pipe execv
  • 10. 所以,容器的动态表现是 • 一个自带“世界观”的进程 – namespaces :视图 – pivot_root 和 cgroups :边界 – 三层文件系统: RW layer , init-layer , read-only layers FROM ubuntu:latestFROM ubuntu:latest VOLUME /dataVOLUME /data Copy-On-Write & /dataCopy-On-Write & /data “echo hello” namespace cgroups 或者 hyper , novm read-only layer /bin /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /sys /tmp /usr /var /data /etc/hosts /etc/hostname /etc/resolv.confinit-layer read-write layer /var/lib/docker/ volumes/<volume_id>/_data container/<container_id>/hosts container/<container_id>/resolv.conf container/<container_id>/hostname aufs/mnt
  • 11. 从 BORG 谈容器集群编排 第二部分 Borg : http://research.google.com/pubs/pub43438.html
  • 12. 从单机到集群 • 多任务单机操作系统 • 进程隔离 – 每个进程有自己的虚拟地址 空间 – 进程间使用 IPC 通信 • 单机资源共享 – 资源对象 • CPU • 物理内存 • 文件 • 外部设备 – 并发:进程上下文切换 • 兼顾公平与高效的调度 • 多容器集群数据中心 • 进程 + 环境隔离 – 环境隔离与资源边界: namespaces 和 cgroups – 容器间通信:网络方案 • 集群资源共享 – 资源对象:机器(或资源包) – 在机器内部才考虑单机资源共享 • CPU ,物理内存,文件,外部设备,并发,公平 调度 • 兼顾公平、高效、利用率、能耗 、访问延时的调度 • 机器规模是关键
  • 13. 容器集群管理中的问题 1. 任务分类与优先级? 2. 提升利用率? 3. 允许抢占的调度? 4. 如何评估调度算法? 5. 调度策略优化? 6. 是否混部的权衡?
  • 14. 问题一:容器的分类 • LRS ( Long Running Service ) – “ 死循环”,比如一个 Web 服务 – 需要立刻响应用户的请求,时延敏感 – 高优先级或生产环境级( prod ) • batch jobs – Map-Reduce ,或者其它类似的计算任务 • 它们的执行往往需要持续一段时间,但是最终都会 停止 – 对服务器瞬时的性能波动不敏感 – 低优先级( non-prod )
  • 15. 容器分类举例 • 监控级、生产级、批任务级、尽力级(也 叫测试级) – 监控级和生产级: prod 任务 • prod 任务可以抢占非 prod 任务的资源 • prod 任务不能互相抢占 – 避免触发连锁反应( A 抢占 B , B 抢占 C , C 再抢占 D )
  • 17. 资源边界 • cgroups 只是资源边界 – 只有在资源申请试图超出限额时才发挥作用 – 所以一台机器理应运行更多的容器 • 但是,我们必须有合理的判断依据来决定“ 这台机器尚能运行多少个新容器” – 硬指标: 4G 机器, 1G 的任务,还剩 3G – 超卖: 4G 的机器, 1G 的任务,还剩 4G*2- 1G=7G – 有没有更好的做法?
  • 18. 宿主机: 10G 可用: 6G 宿主机: 10G 可用: 6G 动态资源边界 4G 容器 A 4G 容器 A 资源回收事件 宿主机: 10G 可用: 9G 宿主机: 10G 可用: 9G 回收资源: 3G回收资源: 3G 1G 容器 A 1G 容器 A • 宿主机默认按照动态边界计算自己的可用资源 • 如果容器资源使用超出 1G :迅速恢复资源边界到初始值(比如 4G ) • prod 级别的容器永远只使用现有容器的原始边界计算可用资源,而非 动态边界 • 效果:将近一半的集群减少了 30% 的机器
  • 19. 资源回收事件 • 容器启动成功并运行 300s 后 – 减少该容器资源边界 • 机器某种资源的可用值不足(比如流量激 增) – 可压缩资源,比如 CPU 周期和磁盘 I/O 带宽 • 热回收,调节 LRS 容器的容器边界 – 如若达不到目的,触发重调度事件,移除部分容器 – 不可压缩资源,比如内存和磁盘空间 • 只能按优先级从低到高杀死容器,直到恢复合理的 可用值
  • 20. 安全余量 • 安全边界 = 实际资源使用量 + 可配置的安全余量 • 方法:以集群为单位,通过实验获得该集群的合理余量 – 给定不同的安全余量值 – 观察不同余量下资源 margin 和 OOM 次数在一段时间内的的变化 – 选取平衡点的余量值 资源 margin
  • 21. 问题三:允许抢占的调度 • 第一,可行性检查 – Node 是否满足容器资源需求 • 可用资源 = 机器容量 – 所有容器的边界 + 可以抢占的容器的资源 – 是否满足自定义约束(比如指定的磁盘类型) – 得到候选机器列表 • 第二,打分 – 尽量避免发生资源抢占;如果避免不了,则让被抢占的容器数量 最少、优先级最低 – 挑选容器依赖更完备的机器(比如 package 完备,已经 pull 过所 需的镜像) – 使容器尽量分布在不同的高可用域当中 – 尽量混合部署不同优先级的容器 • 流量峰值突然出现后便于回收资源
  • 23. 问题五:调度策略优化 • 缓存机器的打分结果 – 只有当机器本身信息或者容器发生了变化(比如容器数目或者容 器边界)时,才更新缓存的机器分数 – 忽略那些不太明显的变化,减少缓存的更新次数 • 划分容器组(等价类) – 为一组需求和约束都一样的、亲密关系的容器执行调度过程,而不是单 个容器 • 随机选择一组机器来做可行性检查,而不是整个集群 – 随机挑选一个机器来检查可行性,判断是否通过,再挑选下一个 ,直到通过筛选的机器达到预设的数目,返回之作为候选机器列 表 – 参见 Sparrow调度器 • 效果:极端情况可能耗时几天的任务 -> 几百秒
  • 24. 问题六:是否混部的权衡 • LRS 和 batch job 分开部署: – 需要额外增加 20%-30% 的机器 • 不同用户的容器分开部署: – 需要额外增加 20%-150% 的机器 • 共享带来的 CPU 性能损失: 3% – CPI ( cycles per instruction ) – 每增加一个容器,其他任务的 CPI 增加 0.3% • 权衡:减少的机器数量 VS CPU 性能损失
  • 26. Kubernetes 1. k8s 是 Borg 的开源实现吗?他俩什么关系 ? 2. K8s 的架构? 3. 怎么部署 Kubernetes ? 4. Pod 的作用? 5. Pod 的调度策略? 6. 如何创建一个 Pod ? 7. Pod 如何被访问到? 8. k8s 提供跨主机网络不?
  • 28. 部署 1 : k8s in docker MasterMaster WorkerWorker docker daemondocker daemon docker daemondocker daemon docker-bootstrap daemon --iptables=false docker-bootstrap daemon --iptables=false docker-bootstrap daemon --iptables=false docker-bootstrap daemon --iptables=false flanneldflanneld etcdetcd flanneldflanneld kubeletkubelet kube- proxy kube- proxy kubeletkubelet kube- proxy kube- proxy mastermaster 2 1 • 优点:快速,无依赖, self-deploy ,操作系统无关,适合开发环境或小型集群 • 缺点:不方便与现有系统集成,需要登录到每台机器上执行脚本 • 见: <k8s>/getting-started-guides/docker-multinode.md mastermaster mastermaster
  • 29. 部署 2 : ubuntu cluster 1. 编译出 kubernetes , etcd, flanneld 二进制文件 2. 规划集群: 3. 部署: • 优点:一键部署,适合一定规模的集群,符合 k8s e2e test 规范,便于同现有 运维系统集成 • 缺点:只支持 Ubuntu ,暂不支持 systemd • 见: <k8s>/docs/getting-started-guides/ubuntu.md IP Address Role 10.10.103.223 node 10.10.103.162 node 10.10.103.250 both master and node export nodes=vcap@10.10.103.250 vcap@10.10.103.162 vcap@10.10.103.223 export role="ai i i“ export NUM_MINIONS=${NUM_MINIONS:-3} export SERVICE_CLUSTER_IP_RANGE=192.168.3.0/24 export FLANNEL_NET=172.16.0.0/16 KUBERNETES_PROVIDER=ubuntu ./kube-up.sh
  • 30. Why Pod • Pod – IP 、 port 等网络资源的分配的基本单位 – 共享存储卷 volume – 共享 namespace • pid, network, ipc, uts • 两个典型场景: – Kubernetes 的 Master 组件 • ./apiserver --address=0.0.0.0 • ./scheduler --master=127.0.0.1:8080 • ./controller-manager --master=127.0.0.1:8080 – 一个应用容器和它的日志转发器 • Web app • log aggregator apiserverapiserver schedulerscheduler controller- manager controller- manager
  • 31. But wait … • Pod 并不是一组容器的简单集合或者集群 • Pod 是 Kubernetes 世界观里的“容器” – Lessons learned from Borg – 成规模场景下的任务组织形式 • Pod :进程组 • 容器 :进程 – 超亲密关系 – 地位对等 – 共同决定 Pod 状态 containers: - name: container A - name: container B restartPolicy: - string: {} volumes: - name: string source: emptyDir | HostDir emptyDir: {} hostDir: path: string
  • 33. Scheduler 默认策略 • 完全插件化 • Predicates :筛选出合格的 Node – 容器申请的主机端口是否可用 – 可用 CPU 和内存是否满足 Pod 里的需求 • 不支持抢占机制,不关注利用率 – host volume 目录是否冲突 – 是否匹配用户指定的 Label – 是不是指定的 hostname • Priorities :对通过上述筛选的 Node 打分 – 选择资源空闲更多的机器 – 选择调度完成后 CPU 和内存利用率更平衡的机器 – 属于同一个任务的副本 Pod 尽量分布在不同机器上 V0.16.2 V0.16.2
  • 34. Scheduler 如何采集信息? • 向 API Server 请求信息( 10s ),有 client 缓存机制 • 两种数据更新方法 – Reflector :监测( watch )对象变化 – Poller :抓取不支持 etcd watch 操作的 api 对象 数据描述 采集方法 数据对象 client 缓存类型 所有未调度的 pod Reflector podQueue queue 所 有 已 调 度 运 行 的 pod Reflector podLister cache 所有可用的 minion Poller MinionLister cache 所有 service 对象 Reflector ServiceLister cache V0.16.2 V0.16.2
  • 35. SyncPods pods pod nodeName pod nodeName 新版 kubelet schedulerscheduler APIServerAPIServer POST /binding pod node list RunKubelet Pods with pod.host == nodeName watch (三种源) startKubeletstartKubelet Pods statusManagerstatusManager Pod.status Pod SyncPods Container Manager, Cadvisor … Container Manager, Cadvisor … managePod Loop managePod Loop managePod Loop managePod Loop managePod Loop managePod LoopWorker update Pod Pods 合法 性检查 Pod Pod V1.0V1.0 SyncPod : Pod vs 现有 Pod 1.创建 Pod 数据目录 2.创建 API 实体 3.mount Volume 4.更新 status DockerManager 1.遍历 Pod 中的 Containers 2.pull 镜像 3.生成 Docker 参数 4.启动容器
  • 36. 期望状态 RC: replica: 2 selector: ‘label’ : ‘test’ // pod definition … 如何控制 Pod ? • Controller Manager – Replication Controller (RC) – 检测循环( 10s ): 期望状态 RC: replica: 2 selector: ‘label’ : ‘test’ // pod definition … Diff •期望的 replica 值 •查询到的 Pod 数量 APIserver etcdetcd 1. label 匹配 2. 选择状态不为 podFailed 的 Pods create/delete Pod fetch with Reflector cache
  • 37. 如何访问 Pod ? • Service : – Portal ,提供访问 Pod 的固定入口( portal_ip : port ) – 多个副本 Pod 的动态 Load Balancer – 适合强依赖于 IP 的业务 NAME SELECTOR IP PORT … service-nginx name=nginx 11.1.1.88 800111.1.1.88:800111.1.1.88:8001 Label: name=nginx Pod A-1 Label: name=nginx Pod A-1 Label: name=nginx Pod A-2 Label: name=nginx Pod A-2 Label: name=nginx Pod A-3 Label: name=nginx Pod A-3 Endpoint
  • 38. NodeNode Service NodeNode // 请求发起自容器: PREROUTING target prot opt source destination … REDIRECT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 redir ports 43318 // 请求发起在 HOST : OUTPUT target prot opt source destination … DNAT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 to:10.10.103.58:43318 // 请求发起自容器: PREROUTING target prot opt source destination … REDIRECT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 redir ports 43318 // 请求发起在 HOST : OUTPUT target prot opt source destination … DNAT tcp -- 0.0.0.0/0 11.1.1.88 tcp dpt:8001 to:10.10.103.58:43318 11.1.1.88:800111.1.1.88:8001 kube-proxy ProxierProxier 4331843318 LoadBalancerLoadBalancer Pod 地址 : 端口 根据 etcd 中 Service 的增删创建并维护规则 Request etcdetcd 1. Service 变化 2. Endpoint 变化 Pod 地址 : 端 口 bi-directionally io.Copy Round-Robin Session Affinity
  • 39. Service • portalIP 仅在集群范围内的机器上有效 – publicIP (使用机器的 public IP 做 portalIP ) – 外部 LoadBalancer • 大规模 & 高并发场景下的担忧 – 可能的瓶颈: • userspace 的 Proxier ( 已经 Fixed ,需要 iptables 1.4.0) • iptables 更新耗时 – 可选替换: cloudfoundry/gorouter , flynn/flynn/router , HAproxy • 监视: <master:port>/api/v1beta3/watch/pods ,更新 Server Pool • 缺点: – 不能有效提供 portal_ip – 需要域名依赖或者端口管理 Host A pod_1pod_1 Host B pod_1pod_1pod_2pod_2 pod_1.mydomain.com LBLB
  • 41. 如何控制 Service ? • Controller Manager – Service Controller :使用真实状态更新 Service – 检测循环: • 遍历所有 Service – 根据 label ,查询出 Pod 列表(真实状态) – 该 Service 持有的 Endpoint 列表(期望状态) – Diff – 有差异: 删除多余的 Endpoint 或者检查实际状态列表的资源版本号 等于 0 ,真实 Pod 并没有出现在 Endpoint 列表中, 创建该 Endpoint 不等于 0 ,更新该 Endpoint
  • 42. Pod 网络:单 Pod 单 IP 模型 pausepause Container AContainer A Container BContainer B --net=container:pause /proc/{pid}/ns/net -> net:[4026532483] • 网络容器( infra 容器) – 使用 docker0 网桥作为默认网关,并且被分配该网桥上的一个 IP 地址作为所有容器共享的 IP 地址
  • 43. Kubernetes 的网络假设 1. 容器之间可以跨主机通信,无需经过 NAT 2. 所有主机与容器之间可以直接通信,无需 经过 NAT 3. 容器本身看到的自己的 IP 地址与其他容器 看它的 IP 地址是一样的 但是, Kubernetes 本身对上述假设不做任何 实现 e.g. Flannel SocketPlane Calico OVS macvlan ipvlan ...
  • 44. 典型的网络实现 • 两条基本原则 – 绝大部分 Docker 跨主网络方案均可以满足上述“网络假设” – 可以随意更改 Daemon 的配置、启动参数,但是 Kubernetes 目前必须使 用标准 Docker API • docker run … √ • my_tool run … × • API 不一致,使用 Powerstrip 进行转义 : https://github.com/ClusterHQ/powerstrip kubeletkubelet PowerstripPowerstrip docker run my_tool run
  • 45. 抛砖引玉 • Flannel – overlay 网络, UDP 封装或者 VxLAN 封装 – 用 Docker 启动 flanneld 后配置 DOCKER_OPTS 的 --bip 即可 – 简单,稳定,但没有划分多个隔离域的能力 • Weave – 通过 ambassador 容器抓取链路层流量,使用 UDP 转发该报文到目的端 • SocketPlane – OVS 的功能性封装,使用 GRE/VxLAN 隧道 – 使用 Powerstrip – Hack :修改 kubelet ,在启动 infra 容器时添加” SP_NETWORK=xxx” 环境变量 Qperf test Flannel UDP Flannel VxLAN Weave Socketplane Native TCP bandwidth 28.7 MB/s 47.8 MB/s 3.75 MB/s 42.8 MB/s 62.5 MB/s TCP latency 200 µs 127 µs 384.4 µs 110.9 µs 96.1µs
  • 46. Kubernetes VS 小伙伴们 • 祖师: Borg – 专注于支撑成规模的企业服务并且最大程度地提高资 源利用率 • Kubernetes – 典型的容器集群管理工具(类似 Swarm ),但基本单 位是 Pod – 暂时不关注资源抢占和任务混部,以及资源利用率提 升 – K8S 大量借鉴了 Borg 的优秀思想、架构、甚至代码实 现,但并不能说就是 Borg 的开源实现 – Goal :” run your container workload at scale”
  • 47. Kubernetes VS 小伙伴们 • Mesos – 专注于 Scheduling 和资源抽象,需要同上层框架协作 – 良好的 framework 支持,适合作为基础依赖 – 适合大数据场景,非原生针对容器集群管理设计 – Goal: “I already have a Layer 1 (business or platform layer), but I need Layer 0 (infrastructure layer) to run it on cluster“ • Flynn Deis Marathon + Mesos Cloud Foundry OpenShift – 更类似 PaaS – “ 从代码,到可运行制品,再到运行实体” – 低用户自由度,高自动化程度 • Compose + Swarm – 最 Docker 友好的容器集群管理工具 – 最原生的 Docker 支持 = vendor lock in – 缺乏成规模集群管理的 vision
  • 48. Further Contact • www.sel.zju.edu.cn • harryzhang AT zju.edu.cn • @ 柳烟堆雪

Editor's Notes

  1. 基本的文件系统结构和library 必须的目录集合:/dev /proc /bin /etc /lib /usr /tmp 基本指令:sh ls cp mv etc... 必要的配置文件:rc inittab fstab etc... 设备:/dev/hd* /dev/tty* /dev/fd0 etc...
  2. rootfs用的是mount+pivot_root,也可以指定用chroot 区别:pivot_root是把整个系统切换到一个新的root目录,而移除对之前root文件系统的依赖,这样你就能够umount原先的root文件系统。而chroot是针对某个进程,而系统的其它部分依旧运行于老的root目录。
  3. rootfs:将aufs/diff挂载到aufs/mnt下 pivot_root VS chroot 前者更加彻底,整个context的根都被切换,后者只是一个进程
  4. cgroups提供了统一的接口对资源进行控制和统计,当进程需要申请更多内存时,就会触发cgroup用量检测。导致进程结束或者被挂起。 超卖指数,总的来说就是偏,让调度器以为这台机器有“很多”资源
  5. cgroups提供了统一的接口对资源进行控制和统计,当进程需要申请更多内存时,就会触发cgroup用量检测。导致进程结束或者被挂起。
  6. kernel不释放这部分page的话,减少limit可能会失败或者造成OOM
  7. 8080是非安全端口,只允许本地访问
  8. Pod状态变化: pod处于running状态,总共包含2个容器,其中1个容器异常退出,这时发生的操作如下。 向系统输出信息为failure(错误)的事件对象(event); 若RestartPolicy是Always,重启异常退出的容器,pod仍处于running状态; 若RestartPolicy是OnFailure,重启异常退出的容器,pod仍处于running状态; 若RestartPolicy是Never, pod仍处于running状态。如果另一个也退出,那么变成failed状态
  9. 耦合度非常低 会出现延时
  10. 第一阶段 类似Borg的“可行性检查
  11. 第一阶段 类似Borg的“可行性检查
  12. 三种源充分体现了:kubelet的自治 现在很多组件比如kubelet都会运行在resource container里,其实就是设置了个cgroup TODO 只是创建没有更新Pod的过程
  13. CM持有的对象是通过Reflector模式进行更新的,第一次加载RC和Pods之后不需要一直poll,而是等变化 learned from Borg
  14. DNAT性能稍差 REDIRECT只管本地
  15. 存在更新已有对象的情况:通过资源版本号来判断
  16. udp封装的是IP包,vxlan封装的是L3帧 数据面:vxlan,管理面:flanneld(可随意重启),vxlan全是kernel态,没有用户态的封装过程(udp方式)