https://edu.aliyun.com/course/1651
第一章 云原生课
1.1 云原生技术发展历程
04-07 google cgroups
08 cgroups合并进入linxu内核主干
13 docker项目发布
14 kubernetes项目发布
15 CNCF(云原生基金会)成立
云原生基金会,包含很多项目,包括kubernetes
云原生技术社区
云原生全景图:
1.2 课程简介与预备知识
基础课:linux容器基础
kubernetes基础
上层:应用编排与管理,应用配置管理,应用存储与持久化数据卷,应用监控与可观测性, 应用服务与网络
进阶课:linux容器进阶
kubernetes进阶
上层:深入理解,调度与资源管理,GPU与硬件加速器,API编程范式,K8s网络模型剖析,CNI与CNI网络插件,集群安装配置与验证,容器与集群安全,CRI与安全容器,多容器运行时
课程预备知识:linux操作系统,计算机与程序设计基础,容器的使用基础(https://docs.docker.com/get-started/part2)
1.3 云原生定义与技术要点
元原生:最佳路径
1.低心智负担的
2.敏捷的
3.以可扩展、可复制的方式,最大化利用云的能力,发挥云的价值的最佳路径
1.3.1 技术范畴:
优点:自包含,可定制的应用镜像,应用快速部署与隔离能力,应用基础设施创建和销毁的自动化管理,可复制的管控系统与支撑组件
云应用定义与开发流程:1.应用定义与镜像制作
2.CI/CD
3.消息和streaming
4.数据库
云应用编排与管理:1.应用编排与调度
2.服务发现与治理
3.远程调用
4.API网关
5.Service Mesh
监控与可观测性:1.监控
2.日志
3.Tracing
4.混沌工程
云原生底层技术:1.容器运行时
2.云原生存储技术
3.云原生网络技术
云原生工具集:1.流程自动化与配置管理
2.容器镜像仓库
3.云原生安全技术
4.云端密码管理
Serverless:1.FaaS
2.BaaS
3.Serverless计费
1.3.2 理论基础:不可变基础设施 目标实现:容器镜像
传统的应用基础设施:ssh链接到服务器上,手动升级或降级软件包,逐个服务器调整配置文件,以及将新代码直接部署到现有服务器上
对云友好的应用基础设施:不可变,部署完成之后基础设施不会被修改。如需更新,则先更改公共镜像构建新服务以替换旧服务。经过验证后,新服务投入使用,旧服务则退役
优点:基础设施一致性和可靠性:容器镜像,自包含,可漂移
简单可预测的部署与运维:自描述,自运维,流程自动化,容易水平扩展,可快速复制的管控系统与支撑组件
云应用编排理论 目标实现:容器设计模式
第二章 容器基本概念
2.1 容器与镜像
namespace:CLONE_NEWUSER(一个进程的UserID和GrooupID在UserNamespace内外可以是不同的。比较常用的在宿主机以一个非root用户运行,创建一个User Namespace,然后在User Namespace里面却映射成root用户。这意味着这个进程在User Namespace里有root权限,在User Namespace外没有root权限。)
cgroup:资源限制,对这个namespace增加资源限制
容器是一个视图隔离,资源可限制,独立文件系统的进程集合
镜像:运行容器所需要的所有文件集合,dockerfile:描述镜像构建步骤
构建步骤所产生文件系统的变化—changeset(镜像分层和复用)
2.1.1 如何构造镜像:Dockerfile - app:v1
$ docker build . -t app:v1
Docker registry - 镜像数据的存储和分发
$ docker push app:v1
2.1.2 如何运行一个容器:
- 从docker registry下载镜像 docker pull busybox:1.25
2.查看本地镜像列表 docker images - 选择相应的镜像并运行 docker run [-d] —name demo busybox:1.25 top
top含义:(容器所对应的这个进程是top命令)
2.2 容器生命周期
2.2.1 单进程模型
init进程生命周期 = 容器生命周期
运行期间可运行docker exec执行运维操作
当init退出后,所有的子进程也退出
如果容器退出,需要把容器产生的数据给持久化下来
2.2.2 数据持久化
独立于容器的生命周期
数据卷 docker volume vs bind
第一种:将宿主机的某个目录和容器中的目录,映射起来,这样可以将容器内的东西保存到宿主机上
docker run -v /tmp:/tmp busybox:1.25 sh -c "date > /tmp/demo.log"
/tmp:/tmp 左边是宿主机的/tmp目录,右边是容器中的目录
检查结果:cat /tmp/demo.log
第二种:通过docker container engine来创建数据卷
docker create volume demo
docker run -v demo:/tmp busybox:1.25 sh -c "date > /tmp/demo.log"
检查结果:docker run -v demo:/tmp busybox:1.25 sh -c "cat /tmp/demo.log"
2.3 容器项目的架构
moby 容器引擎结构,最流行的容器管理引擎
containerd:容器运行时管理引擎,独立于moby daemon
containerd-shim 管理容器生命周期,可被containrd动态接管:dshim可以原地升级
容器运行时:容器虚拟化技术方案
runC kata gVisor
2.4 容器vsVM
进程之间的隔离效果比VM会差很多,但是启动时间更快
所以容器也在向着强隔离的方向发展
2.5 容器镜像的本质
深入了解容器隔离(namespace)和资源控制(cgroup)
容器数据卷的实现方式
containerd架构的分析和工作原理解析
第三章 kubernetes核心概念
3.1 什么是kubernetes
工业级容器编排平台
- 部署
- 弹性
- 管理
核心功能 - 服务发现与负载均衡
- 容器自动装箱
- 存储编排
- 自动容器恢复
- 自动发布与回滚
- 配置与密文管理
- 批量执行
- 水平伸缩
调度
自动恢复
水平伸缩
3.2 kubernetes架构
master
etcd是个存储,把元信息存入,
Node
例子
用户通过UI或者CLI提交一个pod给kubernetes进行部署,apiserver会把这个存储写到etcd中,scheduler会通过api server的watch或者notification机制得到这个信息,又一个pod被调度,会根据调度状态进行决策。向apiserver说这个pod需要调度到某个节点上,再写到etcd上,apiserver再通知相应的节点启动,这个节点里的kubelet通知container runtime启动
3.3 kubernetes的核心概念
3.3.1 Pod
用户可以提交最小的调度以及资源单元
由一个或者多个容器组成
定义容器运行的方式(command,环境变量等)
提供给容器共享的运行环境(网络,进程空间)
Pod和Pod之间有隔离
3.3.2 Volume
声明在Pod中的容器可访问的文件目录
可以给挂载在Pod中一个或者多个容器的指定路径下
支持多种后端存储的抽象:本地存储,分布式存储,云存储
Pod-->Volume-->Remote Block Device
3.3.3 deployment
定义一组Pod的副本数据,版本等
通过控制器(Controller)维持Pod的数目
自动恢复失败的Pod
通过控制器以指定的策略控制版本
滚动升级,重新生成,回滚等
3.3.4 service
提供访问一个多个Pod实例的稳定访问地址
支持多种访问方式实现 ClusterIP,NodePort,LoadBalancer
3.3.5 namespaces
一个集群内部的逻辑隔离机制(鉴权,资源额度)
每个资源都属于一个Namespace
统一个Namespace中的资源命名唯一
不同Namespace中的资源可重名
每个bussiness unit 都视图隔离
3.4 API
3.4.1 HTTP + JSON/YAML
- kubectl
- UI
-
curl
pod的状态,running,terminate,schedule
3.4.2 Label
3.5 安装Minikube
1.安装VirtualBox
https://www.virtualbox.org/wiki/Downloads
2.安装MiniKube(中国版)
https://yq.aliyun.com/articles/221687
3.启动MiniKube
minikube start --vm-dirver virtualbox
3.6 样例
1.提交一个 nginx deployment
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
2.升级 nginx deployment
kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml
3.扩容 nginx deployment
kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml
操作:
minikube status
host: Running
kubelet: Running
apiserver: Running
kubectl get nodes
kubectl get deployments: 没有任何资源
在另一个窗口里,可以watch查看deployments变化情况:kubectl get --watch deployments
kubectl apply -f deployment.yaml发布了一个pod
kubectl describe deployment nginx-deployment
升级nginx:kubectl apply -f deployment-update.yaml
kubectl describe deployment nginx-deployment,发现已经都更新
水平扩张:kubectl apply -f deployment-scale.yaml
kubectl describe deployment nginx-deployment,发现已经都更新
kubectl delete deployment nginx-deployment
第四章 理解Pod和容器设计模式
4.1 为什么需要Pod
容器的本质:一个视图被隔离,资源受限的进程
容器PID=1的进程就是应用本身
管理虚拟机=管理基础设施 管理容器=直接管理应用本身
Kubernetes:云时代的操作系统
容器镜像其实就是:这个操作系统的软件安装包
helloworld程序实际上是由一组进程(linux的线程)组成
4个进程共享helloworld程序的资源,相互协作,完成helloworld
kubernetes = 操作系统(linux)
容器=进程{linux线程}
Pod=进程组{linux 线程组}
进程组:当helloworld是由4个进程组成,在一个docker容器中,启动4个进程,容器PID=1的进程就是应用本身main进程,容器是单进程模型,那么其他3个进程就会丢失。如果应用进程本身具备进程管理能力,意味这helloworld需要由systemd能力,容器PID=1改成systemd,这会导致管理容器=管理systemd != 直接管理应用本身,这样如果helloworld启动,失败等就无法传给外面
容器是比较简单的模型,做不到这种
这时候Pod=进程组,四个独立的进程用四个容器启动,定义在一个Pod里,他们共享某些资源,Pod只是逻辑单位,四个容器组合成Pod,Pod是kubernets分享资源的单位,因为容器之间要共享资源。
一个Pod作为最小资源单位,可以做到如果某个node的分配空间不够这么多的每个进程的容器启动,所以Pod的意义就在这里,从逻辑单元上做到了统一。两个应用一定会运行在同一台宿主机上。
4.2 Pod的实现机制
Pod的多个容器之间可以高效的共享某些资源和数据,容器之间本来是被linux namespace和cgroups隔离开的。
4.2.1 共享网络
容器A和容器B
-
通过Infra Container的方式共享同一个Network Namespace
首先启动infra,所以你升级服务时,不会关掉Pod
- 直接使用localhost通信
- 看到的网络设备跟infra容器看到的一样
- 一个Pod只有一个IP地址,也就是这个Pod
4.2.2 共享存储
shared-data对应在宿主机上的目录会被同时绑定挂载进了上述两个容器当中
4.3 详解容器设计模式
例子
4.3.1 InitContainer
InitContainer会比spec.containers定义的用户容器先启动,并且严格按照定义顺序依次执行
/app是一个volume
Tomat容器,同样声明了挂载该Volume到自己的webapps目录下,volume到自己的webapps目录下
当Tomcat容器启动时,它的webapps目录下就一定存在sample.war文件
容器设计模式:Sidecar 通过在Pod里定义专门容器,来执行主业务容器需要的辅助工作
日志收集:将产出日志的进程不放到容器里,将容器的volumn和这个映射起来
代理容器:
第五章 应用编排与管理 核心原理
5.1 资源元信息
Kubernetes资源对象:
Spec:期望的状态
Status:观测到的状态
- Metadata:
-
Labels:
标识型的Key:Value元数据
作用:用于筛选资源,唯一的组合资源方法
可以使用selector来查询
样例:
Annotations:Key:Value
OwnerReference:
所有者集合类资源
-
5.2 操作演示
kubectl get pods
kubectl apply -f pod1.yaml
kubectl apply -f pod2.yaml
kubectl get pods --show-labels
kubectl get pods nginx1 -o yaml | less
kubectl label pods nginx1 env=test --overwrite
kubectl get pods --show-labels
kubectl get pods --show-labels -l env=test
kubectl get pods --show-labels -l env=test,env=dev
kubectl get pods --show-labels -l 'env in (test, dev)'
kubelctl annotate pods nginx1 my-annotate='my comment, ok'
5.3 控制器模式
两种API设计方法:命令式,声明式
声明式API 控制器
Deployment DP controller
ReplicaSet RS controller
Service Svc controller
自定义资源1 自定义控制器1
自定义资源2 自定义控制器2
由声明式的API驱动--K8S资源对象
由控制器异步的控制系统向终态驱近
系统的自动化和无人值守化成为可能
便于扩展--自定义资源和控制器
第六章 应用编排和管理 Deployment
如果保证集群内可用Pod的数量
如何为所有Pod更新镜像版本
更新过程中,如何保证服务可用性
更新过程中,发现问题如何回滚
6.1 Deployment:管理部署发布的控制器
1.定义一组Pod的期望数量,controller会维持Pod数量与期望数量一致
2.配置Pod发布方式,controller会按照给定策略更新Pod,保证更新过程中不可用的Pod数量在限定范围内
3.如果发布有问题,支持“一键”回滚
创建了deployment.yaml之后,kubectl get deployment查看状态
kubectl get pod/name -o yaml
更新镜像:
快速回滚
kubectl rollout undo deployment/nginx-deployment
回滚到上一个版本
kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
回滚到Deployment到某一个版本,需要先查询版本列表
kubectl rollout history deployment.v1.apps/nginx-deployement
6.2 deployment管理模式
Deployment只负责管理不同版本的ReplicaSet,由ReplicaSet管理Pod副本数
每个ReplicaSet对应了Deployment template的一个版本
一个ReplicaSet下的Pod都是相同的版本
Deployment控制器,更复杂的,包含版本管理
ReplicaSet控制器
扩容模拟:deployment的副本数由ReplicaSet管理,修改Deployement replicas之后,controller会把replicas同步到当前版本的ReplicaSet中,由ReplicaSet执行扩容/缩容
发布模拟,回滚模拟
第七章 应用编排和管理:Job和Daemon
7.1 背景
直接通过Pod来直接运行任务进程吗?
1.如何保证Pod内进程结束
2.如果进程运行失败,如何重试
3.如何管理多个任务且任务之间的互相依赖关系
4.如何并行运行任务并管理他们的队列大小
7.2 Job:管理任务的控制器
1.创建一个或多个Pod确保指定数量的Pod可以成功的运行终止
2.跟踪Pod状态,根据配置及时重试失败的Pod
3.确定依赖关系,保证上一个任务运行完毕后再运行下一个任务
4.控制任务并行度,并根据配置确保Pod队列大小
Job的yaml格式
查看Job状态
kubectl create -f job.yaml
kubectl get jobs
completions: 完成pod数量
duration:job实际业务运行时长
age:job创建的时长
并行运行Job
completions:代表本Pod队列一共执行的次数
parallelism:并行执行的个数
CronJob:schedule:crontab时间格式相同
startingDeadlineSeconds:job最长启动时间
concurrencyPolicy:是否允许并行运行
successfulJobsHistoryLimit:允许留存历史的Job个数
7.3 job的架构模式
1.job controller负责根据配置创建Pod
2.job controller跟踪job状态,根据配置及时重试Pod或者继续创建
3.Job controller会自动添加label来跟踪对应的pod,并根据配置并行或者串行创建Pod
Job<=======>Pod
create/OwnerRef
7.4 DaemonSet 背景
让每个集群内的节点都运行一个相同的Pod吗
1.如何保证每个节点都运行一个pod
2.如果新节点加入集群,如何感知并部署对应的Pod
3.如果有节点退出,如何删除对应的Pod
4.如果Pod状态异常,如何监控并恢复Pod的状态
7.5 DeamonSet 守护进程控制器
它能做什么
1.保证集群内每一个(或者一些)节点都运行一组相同的Pod
2.跟踪集群节点状态,保证新加入的节点自动创建对应的Pod
3.跟踪集群节点状态,保证移除的节点删除对应的Pod
4.跟踪Pod状态,保证每个节点Pod处于运行状态
适用场景:
1.集群存储过程:glusterd,ceph。比如hdfs需要每台机器运行一个agent
2.日志收集进程:
3.需要在每个节点运行的监控收集器
更新策略:rollingUpdate 先移除一个,再更新
OnDelete:模版更新后,只有手动删除某一个对应的Pod,节点的Pod才会更新
管理模式:
1.DaemonSet Controller负责根据配置创建Pod
2.DaemonSet Controller跟踪Job状态,根据配置及时重试Pod或者继续创建
3.DaemonSet Controller会自动添加affinity&label来跟踪对应的pod,并根据配置在每个节点或者适合的部分节点创建Pod
DaemonSet控制器
第八章 应用配置管理
8.1 需求来源
容器镜像来定义运行的Container,Pod还需要解决如下问题:
1.不可变基础设施(容器)的可变配置
2.敏感信息的存储和使用 (如:密码,token等)
3.集群中Pod自我身份认证
4.容器运行资源的配置管理
5.容器运行安全管控
6.容器启动前置条件校验等
8.2 ConfigMap
管理容器运行所需的配置文件,环境变量,命令行参数等可变配置。由于解耦容器镜像和可变配置,从而保障工作负载Pod的可移植性
kubectl create configmap [NAME] [DATA]
其中DATA:指定文件或者目录,指定键值对
kubectl create configmap kube-flannel-cfg --from-file=configure-pod-container/configmap/cni-conf.json -n kube-system
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
ConfigMap 使用:
被Pod使用,一般用于挂载Pod用的配置文件,环境变量,命令行参数等
注意点:
ConfigMap文件大小限制:1MB(etcd要求)
Pod只能引用相同Namespace中的ConfigMap
Pod创建前需要先创建好ConfigMap
使用envFrom从ConfigMap来配置环境变量时,如果ConfigMap中的某些key被认为无效
只有通过k8s api创建的pod才能使用ConfigMap
8.3 Secret
Secret是在集群中用于存储密码,token等敏感信息用的资源对象,其中的敏感数据采用base-64编码
Secret可以用户自己创建,或者系统自动创建
比如:K8S为每个namespace的默认用户(default service account)创建的secret
kubectl create secret generic [NAME] [DATA] [TYPE]
DATA:指定文件/键值对
8.4 ServiceAccount
8.5 Resource
支持资源类型:
CPU:单位:millicore
memory
ephemeral storage
自定义资源
8.6 SecurityContext
限制容器的行为,从而保障系统和其他容器的安全
1.容器级别
2.Pod级别
3.Pod security policies:对集群内的所有pod生效
8.7 InitContainer
优先于普通container启动执行,直到所有initcontainer执行成功后,普通才会启动
Pod中多个Initcontainer之间是按次序依次启动执行,而Pod中多个普通Container是并行启动
InitContainer执行成功后就结束退出了,而普通容器可能会一直执行或者重启(restartPolicy!=Never)
作用:配置文件准备,前置条件校验(网络连通检验)
第九章 应用存储和持久化数据卷
9.1 Pod Volumes
1.如果一个Pod中某一个容器异常退出,被kubelet拉起如何保证之前产生的重要数据不丢失
2.同一个Pod的多个容器如何共享数据?
kubernetes Volume类型:
1.本地存储:emptydir/hostpath
2.网络存储:in-tree: awsElasticBlockStore/gcePersistentDisk/nfs...
out-of-tree:flexvolume/csi等网络存储volume plugins
3.Projected Volume: secret/configmap/downwardAPI/serviceAccountToken
4.PVC与PV体系
9.2 Persistent volumes
Pod中声明的volume的生命周期与Pod相同,以下常见场景
1.Pod销毁重建(如deployment管理的Pod镜像升级)
2.宿主机故障迁移(如statefulSet管理的Pod带远程volume迁移)
3.多Pod共享同一数据volume
4.数据volume snapshot,resize等功能的扩展实现
不足之处:
使用Pod volumes无法准确表达数据volume复用/共享语义,新功能扩展很难实现
优化:
如果能将存储与计算分离,使用不同的组件(controllers)管理存储与计算资源,解耦Pod与Volume的生命周期关联,可以很好的解决这些场景下的问题
9.3 persistent volume claim PVC 设计意图
1.职责分离,PVC中只用声明自己需要的存储size, access mode(单node独占还是多node共享,只读还是读写访问)等业务真正关心的存储需求(不用关心存储实现细节),PV和其对应的后端存储信息则由交给cluster admin统一运维和管控,安全访问策略更容易控制
2.PVC简化了User对存储的需求,PV才是存储的实际信息的承载体,通过kube-controller-manager中的PersistentVolumeController将PVC与合适PV bound到一起,从而满足User对存储的实际需求
3.PVC像是面向对象编程中抽象出来的接口,PV是接口对应的实现
static volume provisioning
dynamic volume provisioning
storageClass前文说的创建PV的模版,它包含了创建某种具体类型PV所需的参数信息,User无需关心这些PV的细节
而K8s则会结合PVC和SC两者的信息动态创建PV对象
第十章 应用存储和持久化数据卷:存储快照与拓扑调度 待学习
Volume snapshot/restore
csi-snapshotter:snapshot/restore 处理流程
volume scheduling 存储调度
volume scheduling 处理流程
第十一章 可观测性:你的应用健康吗
11.1 需求来源
提高应用的可观测性,提高应用的可恢复能力
应用的状态可以实时观测:应用健康状态,应用资源使用,应用实时日志
应用出现问题需要降低影响范围,进行问题调试,诊断
应用出现问题可以通过自愈机制恢复
11.2 liveness与readiness
应用健康的使用方式
应用健康状态--liveness与readness总结
11.3 问题诊断
远程调试
开源的调试工具
kubectl debug
第十二章 可观测性:监控与日志
12.1 背景
监控和日志大型分布式系统的重要基础设施
kubernetes中,监控和日志属于生态的一部分,并不是核心组件,因此大部分的能力依赖上层的云厂商的适配。kubernetes定义了接入的接口标准和规范,任何符合接口标准的组件都可以快速集成
12.2 监控
资源监控:CPU,内存,网络等资源类的指标,常以数值,百分比为单位进行统计,是最常见的资源监控
性能监控:应用的内部监控,通常通过hook的机制在虚拟机层,字节码执行层隐式回调,或者在应用层显示注入,获取更深层次的监控指标,常用来应用诊断与调优
安全监控:针对安全进行的一系列监控策略,例如越权管理,安全漏洞扫描等
事件监控:kubernetes中的另类监控方式,紧密贴合kubernetes的设计理念,补充常规监控方案的欠缺与弊端
kubernetes的监控演进
heapster采集和消费链路
kubernetes的监控接口标准
通过APIServer Aggregated API注册了三种不同的metrics接口
Prometheus--开源社区的监控“标准”
简洁强大的接入标准
多种数据采集,离线方式
kubernetes的兼容
丰富的插件机制与生态
prometheus operator的助力
kube-eventer
AliyunContainerService/kube-eventer
12.3 日志
主机内核的日志
网络栈异常,驱动异常,文件系统异常,影响节点(内核)稳定的异常
runtime的日志
Docker,通过docker的日志排查例如删除Pod Hang等问题
核心组件的日志
APIServer日志可以用来审计,scheduler日志可以诊断调度,etcd日志可以查看存储状态,ingress日志可以分析接入层流量
部署应用的日志:
通过应用日志分析查看业务层的状态,诊断异常
日志采集
宿主机文件:从volume
容器内文件:fluentd日志采集方案
容器标准/错误输出:
第十三章 kubernetes网络概念及策略控制
13.1 基本法:约法三章 + 四大目标
kubernetes对于Pod间的网络没有任何限制,只需满足如下【三个基本条件】:
所有Pod可以与其他Pod直接通信,无需显式使用NAT
所有Node可以与所有Pod直接通信,无需显式使用NAT
Pod可见的IP地址确为其他Pod与其通信时使用,无需显式转换
基于以上准入条件,审视一个网络方案时候,需要考虑如下
容器和容器间通信
Pod与Pod间通信
Pod与Service间通信
外部世界与Service间通信
Network namespace实现网络虚拟化的内核基础,创建了隔离的网络空间
拥有独立的附属网络设备(lo, veth等虚设备/物理网卡)
独立的协议栈,IP地址和路由表
iptables规则
ipvs等
Pod与netns关系
每个Pod拥有独立Netns空间,Pod内的Container共享该空间,可通过Loopback接口实现通信,或通过共享的Pod-IP对外提供服务。别忘记,宿主上还有个Root Netns,可以看作一个特殊的容器空间。
13.2 典型的容器网络实现方案
容器网络可能是kubernets领域最为百花齐放的一个领域,依照IaaS层的配置,外部物理网络的设备,性能或者灵活优先,可以有不同的实现
Flannel,最为普通的实现,提供多种网络backend实现,覆盖多种场景
Calico,采用BGP提供网络直连,功能丰富,对底层网络有要求
Canal,(Flannel for network + Calico for firewalling),嫁接型创新项目
Cilium,基于eBPF和XDP的高性能Overlay网络方案
kube-router,同样采用BGP提供网络直连,集成基于LVS的负载均衡能力
Romana,采用BGP or OSPF提供网络直连能力的方案
WeaveNet,采用UDP封装实现L2 Overlay,支持用户态(慢,可加密)/内核态(快,不能加密)两种实现
Flannel方案
最为普遍的方案,通过backend机制独立,目前已经支持多种数据路径,也可以适用于overlay/underlay等多种场景,封装可以选用用户态udp(纯用户态实现),内核Vxlan(性能好),如集群规模不大,处于同一二层域,也可以选择host-gw方式
network policy基本概念
基于策略的网络控制,用于隔离应用并减少攻击面,它适用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量
控制Pod到Pod,node,外界网络的访问控制
在适用network policy之前,需要注意:
小节总结
第十四章 kubernetes service
14.1 需求
为什么需要服务发现
kubernetes应用应如何相互调用?
Pod生命周期短暂,IP地址随时变化
Deployment等Pod组需要统一访问入口和做负载均衡
应用间在不同环境部署时保持同样的部署拓扑和访问方式
应用服务如何暴露到外部访问和负载均衡
Service:kubernetes中的服务发现与负载均衡
14.2 service概念
Service 语法:
访问service port80端口,到Pod中的MyApp中的targetPort是9376
kubectl apply -f service.yaml
kubectl describe service my-service
集群内访问service
直接Service的虚拟IP
kubetctl get svc可以查到
直接访问服务名,依靠DNS解析:同一个Namespace直接通过servicename访问不同Namespace加上namespace名访问:{servicename}.{namespace}
通过环境访问:
Headless service:
Service指定ClusterIP:None
Pod通过service_name方式时直接解析到所有后端Pod IP
客户端应用自主选择需要访问的Pod
14.3 向集群外暴露service
service类型:
ClusterIP
ExternalName
NodePort ----belong to 向外暴露服务
LoadBalancer ----belong to 向外暴露服务
14.4 service样例
内部访问例子
server.yaml
service.yaml
执行命令:
kubectl create -f service.yaml
kubectl get pod
kubectl get pod -o wide -l run=nginx
kubectl create -f server.yaml
kubectl describe svc
kubectl create -f client.yaml
kubectl get pod
kubectl exec -it clientpod sh 进入pod
wget -O clusterIP
wget -O- nginx
wget -O- $NGINX_
外部访问例子
在service.yaml中增加type:LoadBalancer
kubectl get svc -o wide
14.5 架构设计
14.6 特别样例:从0开始创作云原生应用
第十五章 深入剖析Linux容器
15.1 资源隔离和限制
namespace
1.mount
2.uts
3.pid
4.network
5.user
6.ipc
7.cgroup:
systemd cgroup driver
cgroupfs cgroup driver
容器中常用的cgroup:cpu cpuset cpuacct
memory
device
freezer
blkio
pid
15.2 容器镜像
docker images:基于联合文件系统
不同的层可以被其他镜像复用
容器的可写层可以做成镜像新的一层
以overlay为例:
操作步骤:
启动容器
docker run -d busybox top
查看容器rootfs的挂载点
mount -l | grep
查看新文件写入:docer exec 4efceba27298 sh -c 'echo "new_file" > ./new.file'
15.3 容器引擎
containerd 容器架构详解
第十六章 深入理解etcd
16.1 etcd项目发展历程
etcd诞生与coreOS公司,最初用于解决集群管理系统中OS升级时的分布式并发控制,配置文件的存储与分发等问题。基于此,etcd被设计为提供高可用,强一致的小型KeyValue数据存储服务。项目当前隶属于CNCF基金会,被包括AWS,Google,microsoft,alibaba
16.2 架构及内部机制解析
A distributed, reliable key -- value store for the most critical data of a distributed system
16.2.1 整体架构
quorum一定存在交集,quorum=(n+1)/2
16.2.2 使用方式
16.2.3 etcd提供的APIs
Put(key, value) / Delete(key)
Get(key) Get(keyFrom, keyEnd)]
Watch(key/keyPrefix)
Transactions(if/then/else ops).Commit()
Leases:Grant/Revoke/KeepAlive
16.2.4 etcd数据版本号机制
- term: 全局单调递增,64bits
leader的任期 - revision:全局单调递增,64bits,支持mvcc和watch
- KeyValue:create_revision, mod_revision, version
put key1: term=2, rev=6
put key2: term=2, rev=7
delte key1: term=2, rev=8
put key2: term=2, rev=9
restart etcd:
put key3: term=3, rev=10
put key4: term=3, rev=11
delete key2: term=3, rev=12
16.2.5 etcd mvcc & streaming watch
Put(key, value1) rev=5
Put(key, value2) rev=6
Get(key) -> value2
Get(key, rev=5) -> value1
watcher = Watch(key, rev)
for {
event = watcher.Recv()
handle(event)
.....
}
一个数据有多个版本
通过定期的Compaction来清理历史数据
16.3 典型的使用场景介绍
./etcdctl get key -w json | json_pp
json_pp这个工具
echo dmFsdWVY | base64 -d
etcdctl watch key --prefix
etcdctl txn -i
1.元数据存储--kubernetes
2.service discovery(naming service)
资源注册,存活性检测,API gateway无状态,可水平扩展,支持上万个进程的规模
3.分布式系统:leader election
4.分布式并发系统控制
第十七章 深入理解etcd 性能优化实践
理解etcd性能优化
etcd性能优化--server端
硬件部署:升级CPU memory,选取性能优秀的ssd,网络带宽优先级,独占部署,减少其他程序的运行时干扰
软件优化:
内存索引层:提升etcd内存索引性能,优化内部锁的使用减少等待时间
http://github.com/coreos/etcd/pull/9511
lease规模使用:优化lease revoke和过期失效算法,解决了lease规模性问题 http://github.com/etcd-io/etcd/pull/9418
后端boltdb使用优化:后端batch size limit/interval,可根据不同的硬件和工作负载配置
完全并发读优化调用boltdb tx读写锁使用,提升读性能
etcd性能优化--client端
put时避免大value,精简再精简,如k8s下crd使用
避免创建频繁变化的key/value,例如k8s下node数据上传
避免创建大量lease,尽量选择复用,例如k8s下event数据管理