-
Kubernetes将所有工作节点的资源集结在一起形成一台更加强大的“服务器”
-
计算和存储接口通过Master之上的API Server暴露
-
客户端通过API提交应用程序的运行请求,而后由Master通过调度算法将其自动指派至某特定的工作节点以
-
Pod对象的形式运行
-
Master会自动处理因工作节点的添加、故障或移除等变动对Pod的影响

http://www.magedu.com
Kubernetes集群架构
-
Kubernetes属于典型的Server-Client形式的二层架构
-
Master主要由API Server、Controller-Manager和Scheduler三个组件,以及一个用于集群状态存储的Etcd存储服务组成,它们构成整个集群的控制平面
-
而每个Node节点则主要包含Kubelet、Kube Proxy及容器运行时(docker是最为常用的实现)三个组件,它们承载运行各类应用容器
-


http://www.magedu.com
Kubernetes Master Components
API Server
◼ 整个集群的API网关,相关应用程序为kube-apiserver
◼ 基于http/https协议以REST风格提供,几乎所有功能全部抽象为“资源”及相关的“对象”
◼ 声明式API,用于只需要声明对象的“终态”,具体的业务逻辑由各资源相关的Controller负责完成 ◼ 无状态,数据存储于etcd中
-
Cluster Store
-
集群状态数据存储系统,通常指的就是etcd
-
仅会同API Server交互
-
-
Controller Manager
-
负责实现客户端通过API提交的终态声明,相应应用程序为kube-controller-manager
-
由相关代码通过一系列步骤驱动API对象的“实际状态”接近或等同“期望状态”
- 工作于loop模式
-
-
Scheduler
-
调度器,负责为Pod挑选出(评估这一刻)最合适的运行节点
-
相关程序为kube-scheduler
-

http://www.magedu.com
Kubernetes Worker Components
-
Kubelet
-
Kubernetes集群于每个Worker节点上的代理,相应程序为kubelet
-
接收并执行Master发来的指令,管理由Scheduler绑定至当前节点上的Pod对象的容器
-
通过API Server接收Pod资源定义,或从节点本地目录中加载静态Pod配置
-
借助于兼容CRI的容器运行时管理和监控Pod相关的容器
-
-
-
Kube Proxy
-
运行于每个Worker节点上,专用于负责将Service资源的定义转为节点本地的实现 ◆ iptables模式:将Service资源的定义转为适配当前节点视角的iptables规则
- ipvs模式:将Service资源的定义转为适配当前节点视角的ipvs和少量iptables规则
-
是打通Pod网络在Service网络的关键所在
-

http://www.magedu.com
Kubernetes Add-ons
-
负责扩展Kubernetes集群的功能的应用程序,通常以Pod形式托管运行于Kubernetes集群之上
-
必选插件
-
Network Plugin:网络插件,经由CNI接口,负责为Pod提供专用的通信网络,有多种实现
-
Cluster DNS:集群DNS服务器,负责服务注册、发现和名称解析,当下的实现是CoreDNS
-
-
重要插件
-
Ingress Controller:Ingress控制器,负责为Ingress资源提供具体的实现,实现http/https协议的七层路由和流量调度,有多种实现,例如Ingress-Nginx、Contour等
-
Dashboard:基于Web的UI
-
指标监控系统:Prometheus
-
日志系统:ELK、PLG等
-

http://www.magedu.com


2 应用编排的基本工作逻辑
Pod和应用
-
Kubernetes本质上是“以应用为中心”的现代应用基础设施, Pod 是其运行应用及应用调度的最小逻辑单元
-
本质上是共享Network、IPC和UTS名称空间以及存储资源的容器集
-
可将其想象成一台物理机或虚拟机,各容器就是该主机上的进程
-
各容器共享网络协议栈、网络设备、路由、IP地址和端口等,但Mount、PID和USER仍隔离
-
每个Pod上还可附加一个“存储卷(Volume)”作为该“主机”的外部存储,独立于Pod的生命周期,可由Pod内的
-
各容器共享
-
-
模拟“不可变基础设施”,删除后可通过资源清单重建
-
具有动态性,可容忍误删除或主机故障等异常
-
存储卷可以确保数据能超越Pod的生命周期
-
-
-
在设计上,仅应该将具有“超亲密”关系的应用分别以不同容器的形式运行于同一Pod内部


http://www.magedu.com
为什么要设计Service资源?
-
Pod具有动态性,其IP地址也会在基于配置清单重构后重新进行分配,因而需要服务发现机制的支撑
-
Kubernetes使用Service资源和DNS服务(CoreDNS)进行服务发现
-
Service能够为一组提供了相同服务的Pod提供负载均衡机制,其IP地址(Service IP,也称为Cluster IP)即为客户端流量入口
-
一个Service对象存在于集群中的各节点之上,不会因个别节点故障而丢失,可为Pod提供固定的前端入口
-
Service使用标签选择器 (Label Selector)筛选并匹配Pod对象上的标签(Label),从而发现Pod
- 仅具有符合其标签选择器筛选条件的标签的Pod才可
-
由Service对象作为后端端点使用


http://www.magedu.com
Pod 和工作负载型控制器
-
Pod是运行应用的原子单元,其生命周期管理和健康状态监测由kubelet负责完成,而诸如更新、扩缩容和重建等应用编排功能需要由专用的控制器实现,这类控制器即工作负载型控制器
-
ReplicaSet和Deployment
-
DaemonSet
-
StatefulSet
-
Job和CronJob
-
工作负载型控制器也通过标签选择器筛选Pod标签从而完成关联
工作负载型控制器的工作重心
◼ 确保选定的Pod精确符合期望的数量
◆ 数量不足时依据 Pod模板创建,超出时销毁多余的对象
-
按配置定义进行扩容和缩容
-
依照策略和配置进行应用更新


http://www.magedu.com
部署并访问应用
-
部署应用
-
依照编排需求,选定合适类型的工作负载型控制器
-
创建工作负载型控制器对象,由其确保运行合适数量的Pod对象
-
创建Service对象,为该组Pod对象提供固定的访问入口
-


http://www.magedu.com
部署并访问应用(2)
-
请求访问Service对象上的服务
-
集群内部的通信流量也称为东西向流量,客户端也是集群上的Pod对象;
-
Service同集群外部的客户端之间的通信流量称为南北向流量,客户端是集群外部的进程;
- 另外,集群上的Pod也可能会与集群外部的服务进程通信,
-


http://www.magedu.com
.jpg)


3 Kubernetes网络基础
Kubernetes网络模型
-
Kubernetes集群上会存在三个分别用于节点、Pod和Service的网络
-
于worker上完成交汇
-
由节点内核中的路由模块,以及iptables/netfilter和ipvs等完成网络间的流量转发
-
.jpg)

http://www.magedu.com
Kubernetes网络模型(2)
-
节点网络
-
集群节点间的通信网络,并负责打通与集群外部端点间的通信
-
网络及各节点地址需要于Kubernetes部署前完成配置,非由Kubernetes管理,因而,需要由管理员手动进行,
-
或借助于主机虚拟化管理程序进行
-
-
Pod网络
-
为集群上的Pod对象提供的网络
-
虚拟网络, 需要经由CNI网络插件实现 ,例如Flannel、Calico、Cilium等
-
-
Service网络
-
在部署Kubernetes集群时指定,各Service对象使用的地址将从该网络中分配
-
Service对象的IP地址存在于其相关的iptables或ipvs规则中
-
由Kubernetes集群自行管理
-

http://www.magedu.com
Kubernetes集群中的通信流量
-
Kubernetes网络中主要存在4种类型的通信流量
-
同一Pod内的容器间通信
-
Pod间的通信
-
Pod与Service间的通信
-
集群外部流量与Service间的通信
-
-
Pod网络需要借助于第三方兼容CNI规范的网络插件完成,这些插件需要满足以下功能要求 ◼ 所有Pod间均可不经NAT机制而直接通信
-
所有节点均可不经NAT机制直接与所有Pod通信
-
所有Pod对象都位于同一平面网络中
-

http://www.magedu.com

集群部署与应用编排
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
-
部署分布式Kubernetes集群
-
集群组件运行模式
-
可用的集群部署工具
-
使用kubeadm部署高可用的K8S集群
-
-
API资源规范
-
类型元数据
-
对象元数据
-
spec和status
-
-
应用编排快速入门

-
kubectl命令格式
-
应用编排示例

http://www.magedu.com


1 部署Kubernetes集群
Kubernetes集群组件运行模式
-
独立组件模式
-
除Add-ons以外,各关键组件以二进制方式部署于节点上,并运行于守护进程;
-
各Add-ons以Pod形式运行
-
-
静态Pod模式
-
控制平面各组件以静态Pod对象运行于Master主机之上
-
kubelet和docker以二进制部署,运行为守护进程
-
kube-proxy等则以Pod形式运行
-
k8s.gcr.io
-



http://www.magedu.com
安装工具
- 原生安装工具kubeadm
CNCF认证的安装工具


http://www.magedu.com
kubeadm
-
Kubernetes社区提供的集群构建工具
-
负责执行构建一个最小化可用集群并将其启动等必要的基本步骤
-
Kubernetes集群全生命周期管理工具,可用于实现集群的部署、升级/降级及卸载等
-
kubeadm仅关心如何初始化并拉起一个集群,其职责仅限于下图中背景着色的部分
-



http://www.magedu.com
kubeadm支持的控制平面高可用模型
kubeadm HA topology - stacked etcd


http://www.magedu.com
kubeadm支持的控制平面高可用模型
kubeadm HA topology - external etcd


http://www.magedu.com
部署前提
- 使用kubeadm部署Kubernetes集群的前提条件
◼ 支持Kubernetes运行的Linux主机,例如Debian、RedHat及其变体等
-
每主机2GB以上的内存,以及2颗以上的CPU
-
各主机间能够通过网络无障碍通信
-
独占的hostname、MAC地址以及product_uuid,主机名能够正常解析
-
放行由Kubernetes使用到的各端口,或直接禁用iptables
-
禁用各主机的上的Swap设备
-
各主机时间同步
-
准备代理服务,以便接入k8s.gcr.io,或根据部署过程提示的方法获取相应的Image

http://www.magedu.com
需要开放的端口


http://www.magedu.com
Kubernetes集群示例环境
OS: Ubuntu 20.04.2 LTS
-
Docker:20.10.21,CGroup Driver: systemd
-
Kubernetes:v1.25.3, CRI: cri-dockerd, CNI: Flannel
-
网络环境
- 节点网络:172.29.0.0/16
◼ Pod网络:10.244.0.0/16
◼ Service网络:10.96.0.0/12
| IP地址 | 主机名 | 角色 |
|---|---|---|
| 172.29.9.1 | K8s-master01.magedu.com, K8s-master01, kubeapi.magedu.com | Master |
| 172.29.9.2 | K8s-master02.magedu.com, K8s-master02 | Master |
| 172.29.9.3 | K8s-master03.magedu.com, K8s-master03 | Master |
| 172.29.9.11 | K8s-node01.magedu.com, K8s-node01 | Worker |
| 172.29.9.12 | K8s-node02.magedu.com, K8s-node02 | Worker |
| 172.29.9.13 | K8s-node03.magedu.com, K8s-node03 | Worker |

http://www.magedu.com
集群部署步骤
-
验证各前提条件是否已然满足
-
在各节点上安装容器运行时
- 本示例选用Docker 20.10.21,但Kubernetes将直接使用Containerd - 必要时,为Docker设置使用的代理服务 -
在各节点上安装kubeadm、kubelet和kubectl
-
创建集群
-
① 在控制平面的第一个节点上,使用kubeadm init命令拉起控制平面
- 会生成token以认证后续加入的节点 -
② (实验环境可选)将其它几个控制平面节点使用kubeadm join命令加入到控制平面集群中
- 提示:需要先从第一个控制平面节点上拿到CA及API Server等相应的证书 -
③ 将各worker节点使用kubeadm join命令加入到集群中
-
④ 确认各节点状态正常转为“Ready”
-

http://www.magedu.com
Bootstrapping clusters with kubeadm
部署高可用的Kubernetes集群
- 简单的示例发表在公众号iKubernetes 上

-
或者参考Kubernetes网站上的部署文档
- https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

http://www.magedu.com


2 API资源规范
核心资源类型
-
Kubernetes API Primitive
-
用于描述在Kubernetes上运行应用程序的基本组件,即俗称的Kubernetes对象(Object)
-
它们持久存储于API Server上,用于描述集群的状态
-
-
依据资源的主要功能作为分类标准,Kubernetes的API对象大体可分为如下几个类别
-
工作负载(Workload)
-
服务发现和负载均衡(Discovery & LB)
-
配置和存储(Config & Storage)
-
集群(Cluster)
-
元数据(Metadata)
-
-
“以应用为中心”
- Kubernetes API Primitive基本都是围绕一个核心目的而设计:如何更好地运行和丰富Pod资源,从而为容器化应用提供更灵活和更完善的操作与管理组件

http://www.magedu.com
核心资源类型(2)
- 工作负载型资源负责应用编排
服务发现和负载均衡型资源完成服务注册、发现及流量调度


http://www.magedu.com
API资源规范
资源规范
◼ 绝大多数的Kubernetes对象都包含spec和status两个嵌套字段
- spec字段存储对象的期望状态(或称为应有状态) ⚫
由用户在创建时提供,随后也可按需进行更新(但有些属性并不支持就地更新机制)
⚫ 不同资源类型的spec格式不尽相同
◆ status字段存储对象的实际状态(或称为当前状态)
⚫ 由Kubernetes系统控制平面相关的组件负责实时维护和更新 ◼ 对象元数据 ◆ 名称、标签、注解和隶属的名称空间(不包括集群级别的资源)等 ◼ kind和apiVersion两个字段负责指明对象的类型(资源类型)元数据
- 前者用于指定类型标识
◆ 后者负责标明该类型所隶属的API群组(API Group)
apiVersion: <GROUP/VERSION> kind:

http://www.magedu.com
API资源规范(2)
-
API Server
-
基于HTTP(S)协议暴露了一个RESTful风格的API
-
kubectl命令或其它UI通过该API查询或请求变更API对象的状态
-
施加于对象之上的基本操作包括增、删、改、查等
-
通过HTTP协议的GET、POST、DELETE和PUT等方法完成,而对应于kubectl命令,它们则是create、get、describe、 delete、patch和edit等子命令
-
-
-
API对象管理
-
创建对象时,必须向API Server提供描述其所需状态的对象规范、对象元数据及类型元数据
-
需要在请求报文的body中以JSON格式提供
- 用户也能够以YAML格式定义对象,提交给API Server后由其自行完成格式转换
-
-
资源规范的具体格式
-
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/
-
内建文档:kubectl explain 命令获取
-
参考现有资源对象:kubectl get TYPE/NAME -o {yaml|json}
-

http://www.magedu.com


3 应用编排快速入门
API资源对象管理
-
使用客户端程序,对API Server的REST服务端点发请求
- 请求的body部分要遵循API资源规范
-
kubectl命令提供了三种类型的对象管理机制
-
指令式命令(Imperative commands)
-
直接作用于集群上的活动对象(Live objects)
-
适合在开发环境中完成一次性的操作任务
-
-
指令式对象配置(Imperative object configuration)
- 基于资源配置文件执行对象管理操作,但只能独立引用每个配置清单文件
-

-
可用于生产环境的管理任务
-
声明式对象配置(Declarative object configuration)
-
基于配置文件执行对象管理操作
-
可直接引用目录下的所有配置清单文件,也可直接作用于单个配置文件
-

http://www.magedu.com
部署并访问应用
-
部署应用
-
依照编排需求,选定合适类型的工作负载型控制器
-
创建工作负载型控制器对象,由其确保运行合适数量的Pod对象
-
创建Service对象,为该组Pod对象提供固定的访问入口
-


http://www.magedu.com
指令式命令
编排应用
◼ 仅打印资源清单
◆ kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --port=80 --dry-run=client --replicas=3 -o yaml
◼ 创建deployment对象
- kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --port=80 --replicas=3
◆ Deployment控制器确保deployment/demoapp中定义,
◼ 了解完整的资源规范及状态
◆ kubectl get deployments [-o yaml|json]
◼ 了解Pod对象的相关信息
◆ kubectl get pods -l app=demoapp -o wide
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels:
app: demoapp
name: demoapp
spec: replicas: 3 selector: matchLabels:
app: demoapp
strategy: {} template:
metadata: creationTimestamp: null labels:
app: demoapp
spec: containers:
- image: ikubernetes/demoapp:v1.0
name: demoapp resources: {} status: {}

http://www.magedu.com
指令式命令(2)
创建Service对象
◼ 仅打印资源清单
◆ kubectl create service clusterip demoapp --tcp=80:80 --dry-run=client -o yaml ◼ 创建Service对象
◆ kubectl create service clusterip demoapp --tcp=80:80
◼ 了解Service的相关信息
◆ kubectl get services demoapp -o wide
◼ 访问Service
◆ demoappIP=$(kubectl get services demoapp -o jsonpath={.spec.clusterIP}) ◆ curl $demoappIP
apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: demoapp name: demoapp spec: ports: - name: 80-80 port: 80 protocol: TCP targetPort: 80 selector: app: demoapp type: ClusterIP status: loadBalancer: {}

http://www.magedu.com

Pod和容器设计模式
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
-
Pod及资源规范
-
Pod资源规范
-
创建Pod资源配置文件
-
管理Pod资源对象
-
-
配置Pod
-
容器探针及示例
-
安全上下文及使用示例
-
资源需求、资源限制及使用示例
-
-
容器设计模式

-
Sidecar容器及示例
-
Ambassador容器及示例
-
Adapter容器及示例
-
Init容器及示例

http://www.magedu.com


1 定义Pod资源
关于Pod
-
什么是Pod?
-
一个或多个容器的集合,因而也可称为容器集,但却是Kubernetes调度、部署和运行应用的原子单元
-
◼ 另外封装的内容:可被该组容器共享的存储资源、网络协议栈及容器的运行控制策略等
-
依赖于 pause 容器事先创建出可被各应用容器共享的基础环境,它默认共享Network、IPC和UTS名称空间给各容器,PID名称空间也可以共享,但需要用户显式定义
-
-
Pod的组成形式有两种
-
单容器Pod:仅含有单个容器
-
多容器Pod:含有多个具有“超亲密”关系的容器
- 同一Pod内的所有容器都将运行于由Scheduler选定的同一个节点上
-


http://www.magedu.com
Pod资源规范的基础框架
一个极简的Pod定义,仅需要为其指定一个要运行的容器即可
- 给出该容器的名称和使用的Image
Pod资源规范的基础框架
apiVersion:v1 kind: Pod metadata: name: … # Pod的标识名,在名称空间中必须惟一; namespace: … # 该Pod所属的名称空间,省略时使用默认名称空间default; spec: containers: # 定义容器,它是一个列表对象,可包括多个容器的定义,至少得有一个; - name: … # 容器名称,必选字段,在当前Pod中必须惟一; image: … # 创建容器时使用的镜像;
-
pause容器无需定义
-
下面是一个简单的Pod资源示例
apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0

http://www.magedu.com
阿里云知行实验室
-
更加便捷的在线实验室
-
后面几节的内容将以实验场景“Kubernetes CKAD 认证实践”中实验为基础进行
-
◼ https://start.aliyun.com
-
.jpg)

http://www.magedu.com
了解Pod的运行状况
打印Pod完整的资源规范,通过status字段了解
◼ kubectl get TYPE NAME -o yaml|json
-
例如
- kubectl get pods demoapp -o yaml
◆ kubectl get pods demoapp -o json
- 打印Pod资源的详细状态
◼ kubectl describe TYPE NAME
- 例如
◆ kubectl describe pods demoapp
- 获取Pod中容器应用的日志
◼ kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]
- 例如
◆ kubectl logs demoapp -c demoapp

http://www.magedu.com
阿里云知行实验室上的实验
- “K8SAPI基础及Pod基本应用”一节


http://www.magedu.com
Pod的phase和重启策略
Pod的相位

- 容器的状态

Pod的重启策略:决定了容器终止后是否应该重启
- Always:无论何种exit code,都要重启容器
◼ OnFailure:仅在exit code为非0值(即错误退出)时才重启容器
◼ Never:无论何种exit code,都不重启容器
图片来源:https://livebook.manning.com/book/kubernetes-in-action-second-edition/chapter-6/v-6/18

http://www.magedu.com


2 配置Pod
通过环境变量向容器传递参数
环境变量是容器化应用的常用配置方式之一
在容器上嵌套使用env字段
◼ 每个环境变量需要通过name给出既定的名称
◼ 传递的值则定义在value字段上
apiVersion: v1 kind: Pod metadata: name: mydb namespace: default spec: containers: - name: mysql image: mysql:8.0 env: - name: MYSQL_RANDOM_ROOT_PASSWORD value: 1 - name: MYSQL_DATABASE value: wpdb - name: MYSQL_USER value: wpuser - name: MYSQL_PASSWORD value: magedu.com
apiVersion: v1 kind: Pod metadata: name: wordpress namespace: default spec: containers: - name: wordpress image: wordpress:5.7 env: - name: WORDPRESS_DB_HOST value: ??? - name: WORDPRESS_DB_NAME value: wpdb - name: WORDPRESS_DB_USER value: wpuser - name: WORDPRESS_DB_PASSWORD value: magedu.com

http://www.magedu.com
应用监控
-
容器式运行的应用类似于“黑盒”,为了便于平台对其进行监测,云原生应用应该输出用于监视自身 API
-
包括健康状态、指标、分布式跟踪和日志等
-
至少应该提供用于健康状态监测的API
-


图片来源:https://www.Redhat.com
http://www.magedu.com
Pod的健康状态监测机制
Pod支持的监测类型
-
startup Probe
-
liveness Probe
-
readiness Probe
-
监测机制
-
Exec Action:根据指定命令的结果状态码判定
-
TcpSocket Action:根据相应TCP套接字连接建立状态判定
-
HTTPGet Action:根据指定https/http服务URL的响应结果判定
-
-
配置参数
-
initialDelaySeconds
-
periodSeconds
-
timeoutSeconds
-
successThreshold
-
failureThreshold
-
图片来源:https://loft.sh/blog


http://www.magedu.com
健康探针配置示例
同时定义了三种探针
◼ startup使用了Exec Action
◼ liveness和readiness使用HTTPGet Action
测试效果
◼ liveness
- URL “/livez” 支持以POST方法为livez参数设定不同值, 非OK值都以5xx响应码响应;
◼ readiness
◆ URL “/readyz” 支持以POST方法为readyz参数设定不同值,非OK值都以5xx响应码响应;
apiVersion: v1 kind: Pod metadata: name: pod-probe-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent startupProbe: exec: command: ['/bin/sh','-c','test','"$(curl -s 127.0.0.1/livez)"=="OK"'] initialDelaySeconds: 0 failureThreshold: 3 periodSeconds: 2 livenessProbe: httpGet: path: '/livez' port: 80 scheme: HTTP initialDelaySeconds: 3 timeoutSeconds: 2 readinessProbe: httpGet: path: '/readyz' port: 80 scheme: HTTP initialDelaySeconds: 15 timeoutSeconds: 2 restartPolicy: Always

http://www.magedu.com
阿里云知行实验室上的实验
- “容器存活状态及就绪状态探测”一节


http://www.magedu.com
Security Context
-
Pod及容器的安全上下文
-
一组用来决定容器是如何创建和运行的约束条件,这些条件代表创建和运行容器时使用的运行时参数
-
◼ 给了用户为Pod或容器定义特权和访问控制机制
-
-
Pod和容器的安全上下文设置主要包括以下几个方面
-
自主访问控制DAC
-
容器进程运行身份及资源访问权限
-
Linux Capabilities
-
seccomp
-
AppArmor
-
SELinux
-
Privilgege Mode
-
Privilege Escalation
-
-
Kubernetes支持在Pod及容器级别分别使用安全上下文
-
阿里云知行实验室上的实验:“理解及使用Security Context”

http://www.magedu.com
资源需求(requests)和限制(limits)
资源需求和资源限制
-
资源需求(requests)
-
定义需要系统预留给该容器使用的资源最小可用值
-
容器运行时可能用不到这些额度的资源,但用到时必须确保有相应数量的资源可用
-
资源需求的定义会影响调度器的决策
-
-
资源限制(limits)
-
定义该容器可以申请使用的资源最大可用值,超出该额度的资源使用请求将被拒绝
-
该限制需要大于等于requests的值,但系统在其某项资源紧张时,会从容器那里回收其使用的超出其requests值的那部分
-
-
requests和limits定义在容器级别,主要围绕cpu、memory和hugepages三种资源
-
阿里云知行实验室上的实验:“资源需求和资源限制”

http://www.magedu.com


3 Pod设计模式
关于容器设计模式
-
基于容器的分布式系统中常用的3类设计模式
-
单容器模式:单一容器形式运行的应用
-
单节点模式:由强耦合的多个容器协同共生
-
多节点模式:基于特定部署单元(Pod)实现分布式算法
-
单节点多容器模式
-
一种跨容器的设计模式
-
目的是在单个节点之上同时运行多个共生关系的容器,因而容器管理系统需要由将它们作为一个原子单位进行统一调度
-
Pod概念就是这个设计模式的实现之一

http://www.magedu.com
容器设计模式(2)
-
单节点多容器模式的常见实现
-
Sidecar模式
-
Pod中的应用由主应用程序(通常是基于HTTP协议的应用程序)以及一个Sidecar容器组成
-
辅助容器用于为主容器提供辅助服务以增强主容器的功能,是主应用程序是必不可少的一部分,但却未必非得运行为应用的一部分
-
-
Ambassador模式
-
Pod中的应用由主应用程序和一个Ambassador容器组成
-
辅助容器代表主容器发送网络请求至外部环境中,因此可以将其视作主容器应用的“大使”
-
应用场景:云原生应用程序需要诸如断路、路由、计量和监视等功能,但更新已有的应用程序或现有代码库以添加这些功能可能很困难,甚至难以实现,进程外代理便成了一种有效的解决方案
-
-

http://www.magedu.com
容器设计模式(3)
-
单节点多容器模式的常见实现
-
Adapter模式
-
Pod中的应用由主应用程序和一个Adapter容器组成
-
Adapter容器为主应用程序提供一致的接口,实现了模块重用,支持标准化和规范化主容器应用程序的输出以便于外部服务进行聚合
-
-
Init Container模式
-
一个Pod中可以同时定义多个Init容器
-
Init容器负责以不同于主容器的生命周期来完成那些必要的初始化任务,包括在文件系统上设置必要的特殊权限、 数据库模式设置或为主应用程序提供初始数据等,但这些初始化逻辑无法包含在应用程序的镜像文件中,或者出于安全原因,应用程序镜像没有执行初始化活动的权限等等
-
Init容器需要串行运行,且在所有Init容器均正常终止后,才能运行主容器
-
-

http://www.magedu.com

存储卷
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
-
存储卷基础
-
存储卷的基础概念
-
卷类型及卷插件
-
卷规范及基本用法
-
-
持久卷
-
持久卷的功用及工作逻辑
-
PV和PVC规范及用法
-
StorageClass及用法
-
-
Kubernetes存储架构及CSI简介
-
存储架构简介
-
CSI存储组件及部署架构
-

- 示例:基于NFS的CSI

http://www.magedu.com


1 存储卷基础
存储卷基础
-
从概念上讲,存储卷是可供Pod中的所有容器访问的目录
-
Pod规范中声明的存储卷来源决定了目录的创建方式、使用的存储介质以及目录的初始内容
-
存储卷插件(存储驱动)决定了支持的后端存储介质或存储服务,例如 hostPath插件使用宿主机文件系统,而nfs插件则对接指定的NFS存储服务等
-
kubelet内置支持多种存储卷插件
-
-
Pod在规范中需要指定其包含的卷以及这些卷在容器中的挂载路径
-
-
存储卷对象并非Kubernetes系统一等公民,它定义在Pod上,因而卷本身的生命周期同Pod,但其后端的存储及相关数据的生命周期通常要取决于存储介质

图源https://medium.com/

http://www.magedu.com
存储卷类型和相应的插件
In-Tree存储卷插件
◼ 临时存储卷
◆ emptyDir
◼ 节点本地存储卷
◆ hostPath, local
◼ 网络存储卷
◆ 文件系统:NFS、GlusterFS、CephFS和Cinder
◆ 块设备:iSCSI、FC、RBD和vSphereVolume

◆ 存储平台:Quobyte、PortworxVolume、StorageOS和ScaleIO
◆ 云存储:awsElasticBlockStore、gcePersistentDisk、azureDisk和azureFile
◼ 特殊存储卷
◆ Secret、ConfigMap、DownwardAPI和Projected
◼ 扩展接口
◆ CSI和FlexVolume
Out-of-Tree存储卷插件
◼ 经由CSI或FlexVolume接口扩展出的存储系统称为Out-of-Tree类的存储插件

http://www.magedu.com
存储卷资源规范
-
定义存储卷
-
存储卷对象并非Kubernetes系统一等公民,它需要定义在 Pod上
-
卷本身的生命周期同Pod,但其后端的存储及相关数据的生命周期通常要取决于存储介质
-
-
存储卷的配置由两部分组成
-
通过.spec.volumes字段定义在Pod之上的存储卷列表,它经由特定的存储卷插件并结合特定的存储供给方的访问接口进行定义
-
嵌套定义在容器的volumeMounts字段上的存储卷挂载列表, 它只能挂载当前Pod对象中定义的存储卷
-
spec:
volumes:
-
name
-
卷名称标识,仅可使用DNS标签格式的字符,在当前Pod中必须惟一;
-
VOL_TYPE
-
存储卷插件及具体的目标存储供给方的相关配置;
containers:
-
name: … image: … volumeMounts:
-
name
-
要挂载的存储卷的名称,必须匹配存储卷列表中某项的定义;
-
mountPath
-
容器文件系统上的挂载点路径;
-
readOnly
-
是否挂载为只读模式,默认为否;
subPath
-
挂载存储卷上的一个子目录至指定的挂载点;
subPathExpr
-
挂载由指定的模式匹配到的存储卷的文件或目录至挂载点;
mountPropagation
-
挂载卷的传播模式;

http://www.magedu.com
emptyDir存储卷
-
emptyDir存储卷
-
Pod对象上的一个临时目录
-
在Pod对象启动时即被创建,而在Pod对象被移除时一并被删除
-
通常只能用于某些特殊场景中
-
同一Pod内的多个容器间文件共享
-
作为容器数据的临时存储目录用于数据缓存系统
-
-
-
配置参数
-
medium:此目录所在的存储介质的类型,可用值为“default”或“Memory”
-
sizeLimit:当前存储卷的空间限额,默认值为nil, 表示不限制
-
apiVersion: v1 kind: Pod metadata: name: volumes-emptydir-demo spec: initContainers: - name: config-file-downloader image: ikubernetes/admin-box imagePullPolicy: IfNotPresent command: ['/bin/sh','-c','wget -O /data/envoy.yaml https://code.aliyun.com/MageEdu/kubernetes-start/raw/master/tutorials/handson/volume-basics01/envoy.yaml'] volumeMounts: - name: config-file-store mountPath: /data containers: - name: envoy image: envoyproxy/envoy-alpine:v1.16.2 command: ['/bin/sh','-c'] args: ['envoy -c /etc/envoy/envoy.yaml'] volumeMounts: - name: config-file-store mountPath: /etc/envoy readOnly: true volumes: - name: config-file-store emptyDir: medium: Memory sizeLimit: 16Mi

http://www.magedu.com
hostPath存储卷
hostPath卷
◼ 将Pod所在节点上的文件系统的某目录用作存储卷
◼ 数据的生命周期与节点相同
配置参数
◼ path:指定工作节点上的目录路径,必选字段 ◼ type:指定节点之上存储类型
apiVersion: v1 kind: Pod metadata: name: volumes-hostpath-demo labels: app: redis spec: containers: - name: redis image: redis:alpine ports: - containerPort: 6379 name: redisport securityContext: runAsUser: 999 volumeMounts: - mountPath: /data name: redisdata volumes: - name: redisdata hostPath: path: /appdatas/redis/ type: DirectoryOrCreate

http://www.magedu.com
NFS存储卷
- nfs存储卷
◼ 将nfs服务器上导出(export)的文件系统用作存储卷
-
nfs是文件系统级共享服务,它支持多路挂载请求,可由多个Pod对象同时用作存储卷后端
-
配置参数
◼ server
◼ readOnly
apiVersion: v1 kind: Pod metadata: name: volumes-nfs-demo labels: app: redis spec: containers: - name: redis image: redis:alpine ports: - containerPort: 6379 name: redisport securityContext: runAsUser: 999 volumeMounts: - mountPath: /data name: redisdata volumes: - name: redisdata nfs: server: nfs.magedu.com path: /data/redis readOnly: false

http://www.magedu.com



2 持久卷
PV和PVC
-
在Pod级别定义存储卷有两个弊端
-
卷对象的生命周期无法独立于Pod而存在
-
用户必须要足够熟悉可用的存储及其详情才能在Pod上配置和使用卷
-
-
PV和PVC可用于降低这种耦合关系
-
PV(Persistent Volume)是集群级别的资源,负责将存储空间引入到集群中,通常由管理员定义
-
PVC(Persistent Volume Claim)是名称空间级别的资源,由用户定义,用于在空闲的PV中申请使用符合过滤条件的PV之一,与选定的PV是“一对一”的关系
-
用户在Pod上通过pvc插件请求绑定使用定义好的PVC资源
-
-
StorageClass资源支持PV的动态预配(Provision)


http://www.magedu.com
PV和PVC(2)
-
PV资源
-
PV是标准的资源类型,除了负责关联至后端存储系统外,它通常还需要定义支持的存储特性
-
Volume Mode:当前PV卷提供的存储空间模型,分为块设备和文件系统两种
-
StorageClassName:当前PV隶属的存储类;
-
AccessMode:支持的访问模型,分为单路读写、多路读写和多路只读三种
-
Size:当前PV允许使用的空间上限
-
-
在对象元数据上,还能够根据需要定义标签
-
一般需要定义回收策略:Retain、Recycle和Delete
-
-
PVC资源
-
PVC也是标准的资源类型,它允许用户按需指定期望的存储特性,并以之为条件,按特定的条件顺序进行PV 过滤
- VolumeMode → LabelSelector → StorageClassName → AccessMode → Size
-
支持动态预配的存储类,还可以根据PVC的条件按需完成PV创建
-

http://www.magedu.com
使用静态PV和PVC
使用静态PV和PVC的配置卷的步骤


图源:https://stackoverflow.com/
http://www.magedu.com
PV和PVC示例
基于NFS的静态PV和PVC示例
NFS PV 资源定义示例
PVC 资源定义示例
apiVersion: v1 apiVersion: v1 kind: PersistentVolume kind: PersistentVolumeClaim metadata: metadata: name: pv-nfs-demo name: pvc-demo spec: namespace: default capacity: spec: storage: 5Gi accessModes: ["ReadWriteMany"] volumeMode: Filesystem volumeMode: Filesystem accessModes: resources: - ReadWriteMany requests: persistentVolumeReclaimPolicy: Retain storage: 3Gi mountOptions: limits: - hard storage: 10Gi
- nfsvers=4.1 nfs: path: "/data/redis" server: nfs.magedu.com
在Pod上使用PVC卷
apiVersion: v1 kind: Pod metadata: name: volumes-pvc-demo namespace: default spec: containers: - name: redis image: redis:alpine imagePullPolicy: IfNotPresent ports: - containerPort: 6379 name: redisport volumeMounts: - mountPath: /data name: redis-rbd-vol volumes:
- name: redis-rbd-vol persistentVolumeClaim: claimName: pvc-demo

http://www.magedu.com
StorageClass
StorageClass资源
StorageClass资源示例
- Kubernetes支持的标准资源类型之一
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-csi provisioner: nfs.csi.k8s.io parameters: server: nfs-server.default.svc.cluster.local share: / reclaimPolicy: Delete volumeBindingMode: Immediate mountOptions:
-
为管理PV资源之便而按需创建的存储资源类别(逻辑组)
-
◼ 是PVC筛选PV时的过滤条件之一
-
为动态创建PV提供“模板”
- 需要存储服务提供管理API
◆ StorageClass资源上配置接入API的各种参数
- ⚫
定义在parameters字段中
⚫ 还需要使用provisioner字段指明存储服务类型
- hard - nfsvers=4.1
◼ 一般由集群管理员定义,隶属集群级别
~# kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE nfs-csi nfs.csi.k8s.io Delete Immediate false
5s

http://www.magedu.com
PVC和动态PV示例
-
有些存储类型默认并不支持动态PV机制,如右图所示
-
多数CSI存储都支持动态PV,且支持卷扩展和卷快照等功能
| PVC向StorageClass申请绑定PV |
|---|
| apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nfs-dynamic |
| spec: accessModes: - ReadWriteMany |
| resources: requests: |
| storage: 10Gi |
| storageClassName: nfs-csi |


http://www.magedu.com



3 Kubernetes存储架构及CSI简介
Kubernetes存储架构
存储卷的具体的管理操作由相关的控制器向卷插件发起调用请求来完成
-
AD控制器:负责存储设备的Attach/Detach操作
-
Attach:将设备附加到目标节点
-
Detach:将设备从目标节点上拆除
-
-
存储卷管理器:负责完成卷的Mount/Umount操作,以及设备的格式化操作等
-
PV控制器:负责PV/PVC的绑定、生命周期管理,以及存储卷的Provision/Delete操作
Scheduler:特定调度插件的调度决策会受到目标节点上的存储卷的影响


http://www.magedu.com
Out-of-Tree存储
-
CSI简介
-
容器存储接口规范,与平台无关
-
驱动程序组件
-
CSI Controller:负责与存储服务的API通信从而完成后端存储的管理操作
-
Node Plugin:也称为CSI Node,负责在节点级别完成存储卷的管理
-
-


图源:https://www.inovex.de/
http://www.magedu.com
CSI存储组件和部署架构
-
CSI Controller:由StatefulSet控制器对象编排运行,副本量需要设置为1,以保证只会该存储服务运行单个CSI Controller实例;
-
Node Plugin:由DaemonSet控制器对象编排运行,以确保每个节点上精确运行一个相关的Pod副本


http://www.magedu.com
CSI存储组件和部署架构(2)
-
CSI Controller Pod中的Sidecar容器
-
CSI Controller被假定为不受信任而不允许运行于Master节点之上,因此,kube-controller-manager无法借助 UnixSock套接字与之通信,而是要经由API Server进行;
-
该通用需求由Kubernetes提供的external-attacher和external-provisioner程序完成,此两者通常会以一个Sidecar容器运行于CSI Controller Pod中
-
external-attacher:负责针对CSI上的卷执行attach和detach操作,类似于CSI专用的AD Controller
-
external-provisioner:负责针对CSI上的卷进行Provision和Delete操作等,类似于CSI专用的PV Controller
-
-
CSI支持卷扩展和快照时,可能还会用到external-resizer和external-snapshotter一类的程序
-
-
CSI Node Pod中的Sidecar容器
-
kubelet(实现卷的Mount/Umount操作)将UnixSock套接字与CSI Node Plugin进行通信
-
将Node Plugin注册到kubelet上,并初始化NodeID(获取从Kubernetes节点名称到CSI驱动程序NodeID的映射) 的功能由通用的node-driver-registrar程序提供,它通用运行为CSI Node Pod的Sidecar容器
-
.jpg)
http://www.magedu.com
部署及使用NFS CSI
-
kubernetes-csi/csi-driver-nfs项目在其代码仓库中提供了示例性的部署及测试配置文件,它们都位于 deploy目录下
-
我们采用将代码仓库克隆到本地,而后基于本地的配置清单完成部署
-
① 部署NFS Provisioner
-
示例配置文件为deploy/example/nfs-provisioner/nfs-server.yaml,可按需定义节点上用于存储数据的目录路径
-
~$ kubectl apply -f deploy/example/nfs-provisioner/nfs-server.yaml
-
-
② 部署NFS CSI Driver
-
首先需要确认deploy/csi-nfs-driverinfo.yaml文件中,CSIDriver资源隶属的API群组为“storage.k8s.io/v1”
- ⚫
提示:废除了对“storage.k8s.io/v1beta1”群组支持的较新版本的Kubernetes有此要求
- ⚫
-
示例部署脚本为deploy/install-driver.sh,向其传递参数即可完成部署,例如如下
- ⚫
./deploy/install-driver.sh master local
- ⚫
-
-
③ 测试
-
首先需要创建基于NFS CSI的PVC,或者创建一个支持动态PV创建的StorageClass,这些deploy/example/nfsprovisioner/nginx-pod.yaml文件中有示例
-
kubectl apply -f deploy/example/nfs-provisioner/nginx-pod.yaml
-
-

http://www.magedu.com
阿里云的CSI插件简介
阿里云CSI插件实现了在Kubernetes中对阿里云云存储卷的生命周期管理
◼ CSI-Plugin组件遵循标准CSI规范,提供了EBS、NAS、OSS等类型阿里云云存储服务的挂载能力
◼ 自ACK 1.16版本的集群开始,部署集群时默认即会自动安装最新版本的CSI组件
◼ CSI Plugin提供了数据卷的全生命周期管理,包括数据卷的:创建、挂载、卸载、删除、扩容等服务


http://www.magedu.com

应用配置
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
-
ConfigMap和Secret资源介绍
-
应用配置的常用方式
-
ConfigMap和Secret的功用
-
-
ConfigMap资源
-
创建ConfigMap的方式
-
在Pod上引用ConfigMap中的数据
-
-
Secret资源
-
Secret资源类型
-
创建Secret资源的方式
-
Image Pull Secret
-


http://www.magedu.com



1 ConfigMap和Secret基础
ConfigMap和Secret资源
-
ConfigMap和Secret是Kubernetes系统上两种特殊类型的存储卷
-
ConfigMap用于为容器中的应用提供配置数据以定制程序的行为,而敏感的配置信息,例如密钥、证书等则通常由Secret来配置
-
ConfigMap和Secret将相应的配置信息保存于资源对象中,而后在Pod对象上支持以存储卷的形式将其挂载并加载相关的配置,从而降低了配置与镜像文件的耦合关系,提高了镜像复用能力
-
Kubernetes借助于ConfigMap对象实现了将配置文件从容器镜像中解耦,从而增强了工作负载的可移植性,使其配置更易于更改和管理,并避免了将配置数据硬编码到Pod配置清单中
-
-
此二者都属于名称空间级别,只能被同一名称空间中的Pod引用


http://www.magedu.com
ConfigMap和Secret资源(2)
ConfigMap和Secret资源都是数据承载类的组件,是Kubernetes API的标准资源类型,是一等公民 ◼ 主要负责提供key-value格式的数据项,其值支持
◆ 单行字符串:常用于保存环境变量值,或者命令行参数等 ◆ 多行字串:常用于保存配置文件的内容
apiVersion: v1 kind: ConfigMap metadata: name: myapp-confs data: PORT: "8080" myserver-status.cfg: | location /nginx-status { stub_status on; access_log off; }
◼ 资源规范中不使用spec字段,而是直接使用特定的字段嵌套定义key-value数据 ◆ ConfigMap支持使用data或binaryData字段嵌套一至多个键值数据项 ◆ Secret支持使用data或stringData(非base64编码的明文格式)字段嵌套一至多个键值数据项 ◼ 从Kubernetes v1.19版本开始,ConfigMap和Secret支持使用immutable字段创建不可变实例

http://www.magedu.com



2 ConfigMap
创建ConfigMap对象
创建ConfigMap对象的方法有两种
- 命令式命令
◆ 字面量:kubectl create configmap NAME --from-literal=key1=value1
◆ 从文件加载:kubectl create configmap NAME --from-file=[key=]/PATH/TO/FILE
-
从目录加载:kubectl create configmap NAME --from-file=[key=]/PATH/TO/DIR/
-
配置文件
◆ 命令式:kubectl create -f
◆ 声明式:kubectl apply -f
提示:基于文件内容生成时,可以使用命令式命令以dry-run模式生成并保存
apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance }

http://www.magedu.com
资源示例
命令式命令
◼ kubectl create configmap nginx-confs --from-file=./nginx-conf.d/myserver.conf --from-file=status.cfg=./nginxconf.d/myserver-status.cfg
配置文件
apiVersion: v1 kind: ConfigMap metadata: name: nginx-confs namespace: default data: status.cfg: | # “|”是键名及多行键值的分割符,多行键值要进行固定缩进 location /nginx-status { # 该缩进范围内的文本块即为多行键值 stub_status on; access_log off; } myserver.conf: | server { listen 8080; server_name www.ik8s.io; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; } }

http://www.magedu.com
引用ConfigMap对象
ConfigMap资源对象中以key-value保存的数据,在Pod中引用的方式通常有两种
-
环境变量
-
引用ConfigMap对象上特定的key,以valueFrom赋值给Pod上指定的环境变量
-
在Pod上使用envFrom一次性导入ConfigMap对象上的所有key-value,key(也可以统一附加特定前缀)即为环境变量名, value自动成为相应的变量值
-
-
configMap卷
-
在Pod上将ConfigMap对象引用为存储卷,而后整体由容器mount至某个目录下
- ⚫
key转为文件名,value即为相应的文件内容
- ⚫
-
在Pod上定义configMap卷时,仅引用其中的部分key,而后由容器mount至目录下
-
在容器上仅mount configMap卷上指定的key
-

http://www.magedu.com
在Pod上配置使用ConfigMap示例
通过环境变量引用
通过存储卷引用
apiVersion: v1 apiVersion: v1 kind: Pod kind: Pod metadata: metadata: name: configmaps-env-demo name: configmaps-volume-demo spec: spec: containers: containers: - image: ikubernetes/demoapp:v1.0 - image: nginx:alpine name: demoapp name: nginx-server env: volumeMounts: - name: PORT - name: ngxconfs valueFrom: mountPath: /etc/nginx/conf.d/ configMapKeyRef: readOnly: true name: demoapp-config volumes: key: demoapp.port - name: ngxconfs optional: false configMap: - name: HOST name: nginx-config-files valueFrom: optional: false configMapKeyRef: name: demoapp-config key: demoapp.host optional: true

http://www.magedu.com



3 Secret
Secret资源
- Secret主要用于存储密钥、OAuth令牌和SSH 密钥等敏感信息,这些敏感信息采用base64编码保存,略好于明文存储
Secret根据其用途等,还有类型上的区分

注意:不同类型的Secret,在定义时支持使用的标准字段也有所不同,例如ssh-auth类型的Secret应该使用ssh-privatekey,而basiauth类型的Secret则需要使用username和 password等。
提示:另外也可能存在一些特殊的用于支撑第三方需求的类型,例如ceph的keyring信息使用的kubernetes.io/rbd等

http://www.magedu.com
创建Secret资源
-
支持类似于ConfigMap的创建方式,但Secret有类型子命令,而且不同类型在data或stringData字段中支持嵌套使用的key亦会有所有同;
-
命令式命令
-
generic
-
kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1]
-
除了后面docker-registry和tls命令之外的其它类型,都可以使用该命令中的--type选项进行定义,但有些类型有key的特定要求
-
-
tls
-
kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file
-
通常,其保存cert文件内容的key为tls.crt,而保存private key的key为tls.key
-
-
docker-registry
-
kubectl create secret docker-registry NAME --docker-username=user --docker-password=password --docker-email=email [-docker-server=string] [--from-file=[key=]source]
-
通常,从已有的json格式的文件加载生成的就是dockerconfigjson类型,命令行直接量生成的也是该类型
-

http://www.magedu.com
资源示例
命令式命令
◼ kubectl create secret generic mysql-root-authn --from-literal=username=root --from-literal=password=MagEdu.c0m 配置文件
apiVersion: v1 data: password: TWFnRWR1LmMwbQ== username: cm9vdA== kind: Secret metadata: name: mysql-root-authn namespace: default type: Opaque
apiVersion: v1 data: tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ……SNGQ0PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== tls.key: LS0tLS1CRUdJTiBSU0EgUFJJ……nN0d5U28rCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== kind: Secret metadata: name: nginx-ssl-secret namespace: default type: kubernetes.io/tls

http://www.magedu.com





引用Secret对象
Secret资源在Pod中引用的方式同样有两种
-
⚫ 环境变量
-
引用Secret对象上特定的key,以valueFrom赋值给Pod上指定的环境变量
-
在Pod上使用envFrom一次性导入Secret对象上的所有key-value,key(也可以统一附加特定前缀)即为环境变量名,value自动成为相应的变量值
-
-
⚫ secret卷



-
在Pod上将Secret对象引用为存储卷,而后整体由容器mount至某个目录下
- key转为文件名,value即为相应的文件内容
-
在Pod上定义Secret卷时,仅引用其中的部分key,而后由容器mount至目录下


-
在容器上仅mount Secret卷上指定的key
-
注意:容器很可能会将环境变量打印到日志中,因而不建议以环境变量方式引用Secret中的数据







http://www.magedu.com





在Pod上引用Secret的示例
在Pod上引用Secret资源






apiVersion: v1 kind: Pod metadata: name: secrets-volume-demo spec: containers: - image: nginx:alpine name: ngxserver volumeMounts: - name: nginxcerts mountPath: /etc/nginx/certs/ readOnly: true - name: nginxconfs mountPath: /etc/nginx/conf.d/ readOnly: true volumes: - name: nginxcerts secret: secretName: nginx-ssl-secret - name: nginxconfs configMap: name: nginx-sslvhosts-confs optional: false










.jpg)


http://www.magedu.com


Image Pull Secret
dockercfg及dockerconfigjson类型的Secret主要用于从私有Image Registry中下载容器镜像 ⚫ 其引用定义在pod.spec.imagePullSecrets字段上


示例
apiVersion: v1 kind: Pod metadata: name: demoapp namespace: default spec: containers: - name: demoapp image: ikubernetes/demoapp:v1.0 imagePullSecrets: - name: ikuberneteskey





















http://www.magedu.com

Service与服务发现
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
-
Service资源基础
-
Service的功用
-
Service的类型
-
-
流量转发
-
Service规范及创建
-
标签和标签选择器
-
外部流量策略
-
Load Balancer类型的Service
-
-
Service名称解析
-
CoreDNS和Service的名称资源记录
-
Headless Service和ExternalName Service
-

- 流量转发机制

http://www.magedu.com



1 Service资源基础概念
Service资源
Service是Kubernetes标准的API资源类型之一
-
为动态的Pod资源提供近似静态的流量入口
-
服务发现:通过标签选择器筛选同一名称空间下的Pod资源的标签, 完成Pod筛选
- ⚫
实际上是由与Service同名的Endpoint或EndpointSlice资源及控制器完成
- ⚫
-
流量调度:由运行各工作节点的kube-proxy根据配置的模式生成相应的流量调度规则
-
⚫
iptables -
⚫
ipvs
-
-
-
持续监视着相关Pod资源的变动,并实时反映至相应的流量调度规则之上


http://www.magedu.com
动态可配置负载均衡
- 从Service的视角来看,Kubernetes集群的每个工作节点都是动态可配置的负载均衡器 ⚫ 对于隶属某Service的一组Pod资源,该Service资源能够将集群中的每个工作节点配置为该组Pod的负载均衡器

-
⚫ 客户端可以是来自集群之上的Pod,也可以是集群外部的其它端点
-
⚫ 对于一个特定的工作节点上的某Service来说,其客户端通常有两类
-
该节点之上的进程,可通过该Service的Cluster IP进入
- Service_IP:Service_Port
-
该节点之外的端点,可经由该Service的NodePort进入
- Node_IP:Node_Port
-
-
显然,若客户端进入的节点,并非目标Pod所在的节点
-
时,报文转发的路径中必然存在跃点






http://www.magedu.com




Service类型
- Service根据其所支持的客户端接入的方式,可以分为4种类型


-
⚫ ClusterIP:支持Service_IP:Service_Port接入;
-
⚫ NodePort:支持Node_IP:Node_Port接入,同时支持ClusterIP;
-
⚫ LoadBalancer:支持通过外部的LoadBalancer的LB_IP:LB_Port接入,同时支持NodePort和ClusterIP;
- Kubernetes集群外部的LoadBalancer负责将接入的流量转发至工作节点上的NodePort

-
LoadBalancer需与相关的NodePort的Service生命周期联动
-
LoadBalancer应该是由软件定义
-
Kubernetes需要同LoadBalancer所属的管理API联动
-
-
⚫ ExternalName

-
负责将集群外部的服务引入到集群中
-
需要借助于ClusterDNS上的CNAME资源记录完成
-
特殊类型,无需ClusterIP和NodePort
-
无须定义标签选择器发现Pod对象





http://www.magedu.com



2 Service及流量转发




创建Service资源
- 由Service表示的负载均衡器,主要定义如下内容


-
⚫ 负载均衡器入口:ClusterIP及相关的Service Port、NodePort(每个节点的Node IP都可用)
- 根据通信需求,确定选择的类型
-
⚫ 标签选择器:用于筛选Pod,并基于筛选出的Pod的IP生成后端端点列表(被调度的上游端点)
-
⚫ Service类型的专有配置














http://www.magedu.com



.jpg)

标签和标签选择器
- 标签:附加在资源对象上的键值型元数据


-
⚫ 键标识:由“键前缀(可选)”和“键名”组成,格式为“key_prefix/key_name”
-
键前缀必须使用DNS域名格式
-
键名的命名格式:支持字母、数字、连接号、下划线和点号,且只能以字母或数字开头;最长63个字符;
-
-
⚫ “kubectl label”命令可管理对象的标签




-
标签选择器:基于标签筛选对象的过滤条件,支持两种类型
-
⚫ 基于等值关系的选择器
- 操作符:=或==、!=
-
⚫ 基于集合关系的选择器
-


-
操作符:in、notin和exists
-
使用格式:KEY in (VALUE1, VALUE2, …)、KEY notin (VALUE1, VALUE2, …)、KEY 和!KEY
.jpg)





.jpg)
http://www.magedu.com





Service资源规范
Kubernetes上标准的API资源类型


apiVersion: v1 kind: Service metadata: name: … namespace: … spec: type


.jpg)








http://www.magedu.com




Service资源示例
NodePort Service
ClusterIP Service

kind: Service apiVersion: v1 metadata: name: demoapp spec: type: ClusterIP # 类型标识,默认即为ClusterIP; selector: app: demoapp ports: - name: http # 端口名称标识 protocol: TCP # 协议,支持TCP、UDP和SCTP port: 80 # Service的端口号 targetPort: 80 # 目标端口号,即后端端点提供服务的监听端口号
kind: Service apiVersion: v1 metadata: name: demoapp spec: type: NodePort # 必须明确给出Service类型 selector: app: demoapp ports: - name: http protocol: TCP port: 80 targetPort: 80 nodePort : 30080 # 可选,为避免冲突,建议由系统动态分配




.jpg)











http://www.magedu.com
NodePort Service流量策略(1)
流量策略一:Cluster,表示在整个Kubernetes集群范围内调度;

.jpg)

- ⚫ 该流量策略下,请求报文从某个节点上的NodePort进入,该节点上的Service会将其调度至任何一个可用后端Pod之上,而不关心Pod运行于哪个节点;












http://www.magedu.com



NodePort Service流量策略(2)
-
流量策略二:Local,表示仅将请求调度至当前节点上运行的可用后端端点;
-
⚫ 该流量策略下,请求报文从某节点NodePort进入后,该节点上的Service仅会将请求调度至当前节点上适配到该Service的后端端点
-
⚫ 仅应该从运行有目标Service对象后端Pod对象的节点的NodePort发起访问
-








http://www.magedu.com


.jpg)

LoadBalancer类型的Service
在接入外部流量方面,NodePort存在着几个方面的问题

- ⚫ 非知名端口、私网IP地址、节点故障转移、节点间负载均衡、识别能适配到某Service的Local流量策略的节点等 ⚫ 外置的Cloud Load Balancer可以解决以上诸问题












http://www.magedu.com



3 Service名称解析

Service和Cluster DNS
Cluster DNS(CoreDNS)是Kubernetes集群的必备附件,负责为Kubernetes提供名称解析和服务发现

-
⚫ 每个Service资源对象,在CoreDNS上都会自动生成一个遵循“
. .svc. ”格式的名称 -
:当前Service对象的名称 -
:当前Service对象所属的名称空间
-

:当前Kubernetes集群使用的域名后缀,默认为“cluster.local”

-
⚫ 围绕该名称会生成一些DNS格式的资源记录
-
CoreDNS会持续监视API Server上的Service资源对象的变动,并实时反映到相关的DNS资源记录中
-
Pod中各容器默认会在/etc/resolv.conf中,将nameserver指向CoreDNS相关的Service的ClusterIP





- ⚫ 由kubelet创建Pod时根据指定的配置自动注入







http://www.magedu.com


.jpg)
Service在Cluster DNS上的资源记录
每个Service,在CoreDNS上都会有A/AAAA、SRV和PTR资源记录




- ⚫ A/AAAA资源记录
◆
-
. .svc. . IN AAAA -
⚫ 为每个定义了名称的端口生成一个SRV记录,以支持服务发现

-
. . . .svc. . IN SRV . .svc. . -
⚫ 为每个A记录(例如a.b.c.d)或AAAA记录生成对应的PTR记录,例如
-
h4.h3.h2.h1.g4.g3.g2.g1.f4.f3.f2.f1.e4.e3.e2.e1.d4.d3.d2.d1.c4.c3.c2.c1.b4.b3.b2.b1.a4.a3.a2.a1.ip6.arpa
IN PTR . .svc. .




- Pod可基于Service的DNS名称向其发起服务访问请求







http://www.magedu.com



Pod上的DNS解析策略
Kubernetes支持在单个Pod资源规范上自定义DNS解析策略和配置,并组合生效




- ⚫ spec.dnsPolicy:解析策略
⚫ spec.dnsConfig:名称解析机制
-
DNS解析策略
- ⚫ Default:从运行在的节点继承DNS名称解析相关的配置

-
⚫ ClusterFirst:于集群DNS服务上解析集群域内的名称,其他域名的解析则交由从节点继承而来的上游名称服务器
-
⚫ ClusterFirstWithHostNet:专用于在设置了hostNetwork的Pod对象上使用的ClusterFirst策略
⚫ None:用于忽略Kubernetes集群的默认设定,而仅使用由dnsConfig自定义的配置
- DNS解析机制


-
⚫ nameservers <[]string>:DNS名称服务器列表,附加于由dnsPolicy生成的DNS名称服务器之后
-
⚫ searches <[]string>:DNS名称解析时的搜索域,附加由于dnsPolicy生成的搜索域之后
-
⚫ options <[]Object>:DNS解析选项列表,同dnsPolicy生成的解析选项合并成最终生效的定义







http://www.magedu.com

Headless Service
- Service的各类型中,ClusterIP、NodePort和LoadBalancer都为其Service配置一个ClusterIP,CoreDNS上,这些 Service对象的A记录也解析为它的ClusterIP;

-
广义上,那些没有ClusterIP的Service则称为Headless Service,它们又可以为分两种情形
-
⚫ 有标签选择器,或者没有标签选择器,但有着与Service对象同名的Endpoint资源
- Service的DNS名称直接解析为后端各就绪状态的Pod的IP地址
-


-
调度功能也将由DNS完成
-
各Pod IP相关PTR记录将解析至Pod自身的名称,假设Pod IP为a.b.c.d,则其名称为a-b-c-d.
. .svc. -
这种类型也就是狭义上的Headless Service
-
⚫ 无标签选择器且也没有与Service对象同名的Endpoint资源

◆


- Service的DNS名称将会生成一条CNAME记录,对应值由Service对象上的spec.externalName字段指定







http://www.magedu.com




示例
Headless Service示例
External Service示例




kind: Service apiVersion: v1 metadata: name: externalname-mageedu spec: type: ExternalName externalName: www.magedu.com ports: - protocol: TCP port: 80 targetPort: 80 selector: {}
kind: Service apiVersion: v1 metadata: name: demoapp-headless-svc spec: clusterIP: None selector: app: demoapp ports: - port: 80 targetPort: 80 name: http



















http://www.magedu.com



4 Service流量转发简析






Service流量转发机制
ClusterIP类型

-
⚫ 源自Pod
-
没启动masquerade-all:请求报文的目标IP和目标端口由Service转为挑选出的后端Pod的IP和端口,并由后端Pod直接响应给客户端Pod
-
发夹问题:Pod访问自身所属的Service后,由Service又调度回该Pod
-
存在发夹问题(haripin)的场景中,需要启用源IP地址转换
-
-

-
启用masquerade-all:请求报文的源IP和目标IP都将由Service进行转换,原IP将转为客户端Pod所在节点在Pod网络中的IP地址
-
⚫ 源自非Pod网络中的请求流量
- 接入流量的节点充当NAT网关,请求报文的源IP和目标IP都将由Service进行转换
-
NodePort和LoadBalancer类型
- ⚫ 流量来自集群外部,节点扮演网关的角色,请求报文的源IP和目标IP都将由Service进行转换,原IP将转为客户端Pod所在节点的IP地址,以确保响应报文能正确送达







http://www.magedu.com

Service流量转发机制(2)
- 流量转发示意图:请求报文,目标地址转换都会进行,未启用masquerade-all时,源地址转换将视情况进行 ⚫ Pod网络是虚拟网络,最终还是要通过节点网络完成报文传送,因此,SNAT通常会使用节点网络中的地址








http://www.magedu.com

应用编排
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
-
控制器模式
- 声明式API和控制器模式
◼ Kubernetes上常用的工作负载裁型控制器
-
Deployment控制器及资源
-
Deployment控制器简介
-
ReplicaSet和Deployment资源规范
-
更新策略
-
◼ 扩容和缩容
- DaemonSet控制器及资源

-
DaemonSet控制器的应用编排特性
-
资源规范及更新策略
-
Job和CronJob控制器、资源 ◼ Job及CronJob的应用编排机制
-
Job及并行式Job
-
CronJob及用法
-

http://www.magedu.com



1 Kubernetes控制器模式
声明式API
API设计方法
-
命令式API
-
也称为指令式API,用户需要一步步地告诉机器该如何做(How),机器自身不具有任何“智能”,只被动接受指令
-
◆ 高度依赖用户自身理解和达成目标的能力和处理各类异常问题的经验,实现的是“命令式编程(Imperative Programming)”
-
-
声明式API
-
也称为申明式API,用户只需要告诉机器想要的结果(What),机器自身需要确定如何达成该目标
-
◆ 机器需要一定的“智能”,但通常只能支持事先预设和可被其理解的特定任务
-
实现的是“声明式编程(Declarative Programming)”
-

Programming
Declarative Imperative
Logic Functional Object-oriented Procedural

http://www.magedu.com
声明式API和控制器模式
-
相较于命令式编程,声明式编程是一个更高的层次上的编程
-
声明式API允许用户以给出最终期望目标的方式编写代码,但具体的执行过程(即机器智能的那部分代码),最终仍然需要以命令式编程实现,只不过,它们可由不同的人群完成
-
◼ 类比来说,声明式编程的用户类似于企业的高管,只用关心和交待最终目标;而命令式编程的用户类似于企业部门经理,他需要理解目标的达成路径,并组织人力完成目标
-
-
Kubernetes的声明式API
-
用户能够以声明式定义资源对象的目标状态(spec)
-
由控制器代码(机器智能组件)负责确保实际状态(status)与期望状态一致
- 控制器即“部门经理”,负责确保部门内的各项具体任务得以落地
-

-
控制器通常由API的提供者负责编写
-
用户需要做的是根据资源类型及其控制器提供的DSL进行声明式编程

http://www.magedu.com
声明式API和控制器模式(2)
-
控制器模型(控制回路)
-
初始,Controller负责根据Input(目标状态)控制System,并生成Output(结果状态)
-
Feedback根据Output生成Feedback Signal,而后由Error Detector基于Feedback Signal和Input来判定是否存在错误,并在有错误时生成Error Signal
-
Error Signal将驱动Controller生成Actuating Signal,并控制 System的行为与Input要求相同
-
-
Kubernetes Controller的控制回路
-
Controller根据spec,控制System生成Status
-
Controller借助于Sensor持续监视System的Spec和Status,在每一次控制回路中都会对二者进行比较,并确保System的 Status不断逼近或完全等同Status
-



http://www.magedu.com
Kubernetes的控制器
Kubernetes的控制器类型
-
打包于Controller Manager中内置提供的控制器,例如Service Controller、Deployment Controller等
-
基础型、核心型控制器
-
打包运行于kube-controller-manager中
-
-
插件或第三方应用的专用控制器,例如Ingress插件ingress-nginx的Controller,网络插件Project Calico的 Controller等
-
高级控制器,通常需要借助于基础型控制器完成其功能
-
以Pod形式托管运行于Kubernetes之上,而且这些Pod很可能会由内置的控制器所控制
-
-
以编排Pod化运行的应用为核心的控制器,通常被统称为工作负载型控制器
-
无状态应用编排:ReplicaSet、Deployment
-
有状态应用编排:StatefulSet、第三方专用的Operator
-
系统级应用:DaemonSet
-
作业类应用:Job和CronJob
-

http://www.magedu.com
应用编排
-
定义工作负载型控制器资源对象以编排应用
-
内置的各工作负载型控制器都有对应的资源类型,控制器专用于管控其对应类型的资源对象
-
例如,Deployment控制器对应有Deployment资源类型
-
这些资源类型都是Kubernetes上标准的API资源,并遵循资源规范的通用格式
-
-
用户需要编排某应用时,需要事先确认好应用的运行目标模式,例如实例数据及结束条件等,并根据模式选出对应的工作负载控制器类型
-
而后根据相应控制器的资源类型的规范,编写资源配置,并提交给API Server即可
-
相应控制器监视到API Server上新建的资源后,即会运行代码确保对象实例的实际状态(Status)与期望状态 (Spec)一致
-
-
注意:控制器对象仅负责确保API Server上有相应数量的符合标签选择器的Pod对象的定义,至于Pod 对象的Status如何与Spec保持一致,则要由相应节点上的kubelet负责保证

http://www.magedu.com



2 Deployment资源及控制器
Deployment控制器简介
-
负责编排无状态应用的基础控制器是ReplicaSet,相应的资源类型通过三个关键组件定义如何编排一个无状态应用
-
replicas:期望运行的Pod副本数
-
selector:标签选择器
-
podTemplate:Pod模板
-
-
Deployment是建立在ReplicaSet控制器上层的更高级的控制器
-
借助于ReplicaSet完成无状态应用的基本编排任务
-
它位于ReplicaSet更上面一层,基于ReplicaSet提供了滚动更新 、 回滚等更为强大的应用编排功能
-
是ReplicaSet资源的编排工具
-
Deployment编排ReplicaSet
-
ReplicaSet编排Pod
-
-
但是,应该直接定义Deployment资源来编排Pod应用,ReplicaSet无须显式给出
-


http://www.magedu.com
ReplicaSet和Deployment资源规范
ReplicaSet资源示例
apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-example spec: replicas: 2 selector: matchLabels: app: demoapp release: stable template: metadata: labels: app: demoapp release: stable 各Pod的名字以ReplicaSet名称为前缀,后缀随机生成 spec: containers: - name: demoapp image: ikubernetes/demoapp:v1.0
Deployment资源示例
apiVersion: apps/v1 kind: Deployment metadata: name: deploy-example spec: replicas: 2 selector: matchLabels: app: demoapp release: stable template: ReplicaSet对象名称以 metadata: Deployment名称为前缀,后 labels: 缀是Pod模板的hash码 app: demoapp release: stable spec: 各Pod的名字以Deployment containers: 名称为前缀,中间是Pod模板的hash码,后缀随机生成 - name: demoapp image: ikubernetes/demoapp:v1.0

http://www.magedu.com





获取资源状态
获取ReplicaSet资源对象的状态



~$ kubectl get replicasets/rs-example NAME DESIRED CURRENT READY AGE rs-example 2 2 2 115s
DESIRED:期望的Pod数量 CURRENT:当前的Pod数量 READY:就绪状态的Pod数量 AGE:当前资源的创建后生存时长
获取Deployment资源对象的状态

~$ kubectl get deployment/deploy-example NAME READY UP-TO-DATE AVAILABLE AGE deploy-example 2/2 2 2 27s ⚫ Deployment自动创建的ReplicaSet被添加等同于Pod对象的标签 ~$ kubectl get replicasets -l app=demoapp,release=stable NAME DESIRED CURRENT READY AGE
READY:就绪的Pod数量/期望的Pod数量 UP-TO-DATE:到达期望的版本的Pod数量 AVAILABE:运行中并可用的Pod数量 AGE:当前资源的创建后生存时长




deploy-example-66db74fcfc 2 2 2 6m







http://www.magedu.com
更新策略
-
Deployment控制器支持两种更新策略
- 滚动式更新(rolling updates)
◆ 逐批次更新Pod的方式,支持按百分比或具体的数量定义批次规模,默认策略
- 触发条件:podTemplate的hash码变动
⚫ 仅podTemplate的配置变动才会导致hash码改变
-
⚫
replicas和selector的变更不会导致podTemplate的hash变动 -
◼ 重建式更新(recreate)
◆ 在Pod资源被删除时,使用新的模板定义被足缺失的Pod数量,完成更新
strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate
◆ 触发条件:现有Pod被删除

http://www.magedu.com
触发更新
-
触发滚动更新
-
最为常见的更新需求是应用升级,即镜像文件更新,常用方法
-
~$ kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ...
-
~$ kubectl patch (-f FILENAME | TYPE NAME) [-p PATCH|--patch-file FILE] [options]
-
直接更新原配置文件,而后使用“kubectl apply”命令触发更新
-
-
上面第二和第三种方法可用于模板中任何必要配置的更新
-
-
查看更新
-
更新状态:kubectl rollout status (TYPE NAME | TYPE/NAME) [flags] [options]
-
更新历史:kubectl rollout history (TYPE NAME | TYPE/NAME) [flags] [options]
-
-
回滚
-
回滚到前一版本:kubectl rollout undo (TYPE NAME | TYPE/NAME)
-
回滚到指定版本:kubectl rollout undo (TYPE NAME | TYPE/NAME) --to-revision=X
-

http://www.magedu.com
配置滚动更新策略
-
Deployment的滚动更新支持使用如下两个字段来配置相关的策略
-
maxSurge:指定升级期间存在的总Pod对象数量最多可超出期望值的个数,其值可以是0或正整数,也可以是相对于期望值的一个百分比
-
maxUnavailable:升级期间正常可用的Pod副本数(包括新旧版本)最多不能低于期望值的个数,其值可以是0或正整数,也可以是相对于期望值的一个百分比,默认值为1
-

- 存在的问题:必须以Pod为原子单位切割规模比例,且无法控制流量路由比例;

http://www.magedu.com
扩容和缩容
容量管理类型
◼ 横向伸缩:增加或减少Pod数量
◼ 纵向(垂直)伸缩:调整Pod上的资源需求和资源限制
变动Deployment资源对象中的replicas字段的值即会触发应用规模的扩容或缩容 ◼ 扩容和缩容是ReplicaSet的功能,具体操作由ReplicaSet完成 ◼ 根据应用规模的需要进行手动配置
操作方法
◼ patch命令
◆ kubectl patch (-f FILENAME | TYPE NAME) [-p PATCH|--patch-file FILE] [options]
◆ 例如:kubectl patch deployment deploy-example -p '{"spec":{"replicas":3}}'
◼ 直接更新原配置文件,而后使用“kubectl apply”命令触发更新
扩展:自动扩容和缩容
◼ HPA(Horizontal Pod Autoscaler)控制器
◼ VPA(Vertical Pod Autoscaler)控制器

http://www.magedu.com



3 DaemonSet
DaemonSet的应用编排机制
-
使用DaemonSet编排应用
-
同Deployment相似,DaemonSet基于标签选择器管控一组Pod副本;
-
但是,DaemonSet用于确保所有或选定的工作节点上都运行有一个Pod副本
-
提示:DaemonSet的根本目标在于让每个节点一个Pod
-
有符合条件的新节点进入时,DaemonSet会将Pod自动添加至相应节点;而节点的移出,相应的Pod副本也将被回收;
-
-
-
常用场景
-
特定类型的系统化应用,例如kube-proxy,以及Calico 网络插件的节点代理calico-node等
-
集群存储守护进程、集群日志收集守护进程以及节点监控守护进程等
-

图源:https://medium.com/

http://www.magedu.com



apiVersion: apps/v1


DaemonSet的资源规范
与Deployment相似,DaemonSet对象也使用标签选择器和Pod模板,区别之处在于,DaemonSet不需要定义replicas(Pod副本数量),其Pod数量随节点数量而定;
apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-demo namespace: default spec: selector: matchLabels: app: prometheus component: node-exporter template: metadata: name: prometheus-node-exporter labels: app: prometheus component: node-exporter spec: containers: - image: prom/node-exporter:v1.2.0 name: prometheus-node-exporter ports:

apiVersion: apps/v1 # API群组及版本; kind: DaemonSet # 资源类型特有标识; metadata:

name

- name: prom-node-exp containerPort: 9100 hostPort: 9100 hostNetwork: true hostPID: true







http://www.magedu.com
查看DaemonSet状态
使用kubectl get daemonset命令
~$ kubectl get daemonsets/daemonset-demo
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-demo 2 2 2 2 2
状态描述(示例集群中共有两个工作节点):
DESIRED:期望存在的Pod副本数 AVAILABLE:可用的Pod副本数 CURRENT:当前已存在的Pod副本数 NODE SELECTOR:节点选择器,
- 使用kubectl describe daemonsets命令

http://www.magedu.com
更新策略
-
更新策略
-
rollingUpdate:滚动更新,自动触发
-
onDelete:删除时更新,手动触发
-
-
滚动更新
-
配置策略:rollingUpdate更新策略支持使用maxUnavailable参数来定义单批次允许更新的最大副本数量
-
◼ 更新方式
-
~$ kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ...
-
~$ kubectl patch (-f FILENAME | TYPE NAME) [-p PATCH|--patch-file FILE] [options]
-
直接更新原配置文件,而后使用“kubectl apply”命令触发更新
-
-

http://www.magedu.com



4 Job和CronJob
Job控制器的应用编排机制
-
Job负责编排运行有结束时间的“一次性”任务,而前面的 Deployment和DaemonSet主要负责编排始终运行的守护进程类应用;
-
控制器要确保Pod内的进程“正常(成功完成任务)”地退出
-
非正常退出的Pod可以根据需要重启,并在重试一次的次数后终止
-
有些Job是单次任务,也有些Job需要运行多次(次数通常固定)
-
有些任务支持同时创建及并行运行多个Pod以加快任务处理速度, Job控制器还允许用户自定义其并行度
-
-
需要周期性运行的Job,则由CronJob控制器负责编排
-
CronJob建立在Job的功能之上,是更高层级的控制器
-
它以Job控制器完成单批次的任务编排,而后为这种Job作业提供需要运行的周期定义
-

图源:https://www.magalix.com/blog

http://www.magedu.com
Job资源规范
-
Job资源同样需要标签选择器和Pod模板,但它不需要指定replicas,而是应该给定completions,即需要完成的作业次数,默认为 1次;
-
Job资源会为其Pod对象自动添加“job-name=JOB_NAME”和“controller-uid=UID”标签,并使用标签选择器完成对controller-uid标签的关联,因此,selector并非必选字段
-
Pod的命名格式:`$(job-name)-$(index)-$(random-string),其中的$(index)字段取值与completions和completionMode有关
-
◼ 注意
- Job资源所在群组为“batch/v1”-
Job资源中,Pod的RestartPolicy的取值
-
只能为Never或OnFailure
-
-
apiVersion: batch/v1 # API群组及版本; kind: Job # 资源类型特有标识; metadata: name

http://www.magedu.com
Job的状态
使用kubectl get jobs命令
~$ kubectl get jobs job-demo NAME COMPLETIONS DURATION AGE job-demo 1/3 58s 58s ~$ kubectl get pods -l job-name=job-demo NAME READY STATUS RESTARTS AGE job-demo--1-4vds6 1/1 Running 0 5s job-demo--1-5xd5s 0/1 Completed 0 44s 状态描述(示例集群中共有两个工作节点):
COMPLETIONS:已经正常完成任务并退出的Pod数量 DURATION:Job业务的实际运行时长 AGE:Job资源创建后的时长 使用kubectl describe jobs命令
apiVersion: batch/v1 kind: Job metadata: name: job-demo spec: template: spec: containers: - name: myjob image: ikubernetes/admin-box:v1.0 imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "sleep 30"] restartPolicy: Never completions: 3 ttlSecondsAfterFinished: 3600 backoffLimit: 3 activeDeadlineSeconds: 300

http://www.magedu.com
并行式Job
Job对象能够支持多个Pod的可靠、并发执行
-
编排彼此间相互通信的并行进程并非Job的设计目标,它仅用于支撑一组相互独立而又有所关联的工作任务的并行处理
-
常见的场景,有如发送电子邮件、渲染视频帧、编解码文件、NoSQL数据库中扫描主键范围等
-
并行式Job的关键配置参数
-
parallelism:任务并行度,即最大可同行运行的Pod数量, 可以将其理解为工作队列的数量
-
completions:总共需要完成的任务数量,即总共需要多少个相关的Pod成功完成执行,通常要大于parallelism的值
-
apiVersion: batch/v1 kind: Job metadata: name: para-job-demo spec: template: spec: containers: - name: myjob image: ikubernetes/admin-box:v1.0 imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "sleep 30"] restartPolicy: OnFailure completions: 7 parallelism: 2 completionsMode: Indexed ttlSecondsAfterFinished: 3600 backoffLimit: 3 activeDeadlineSeconds: 1200

http://www.magedu.com
CronJob
CronJob控制器用于管理Job资源的运行时间,它允许用户在特定的时间或以指定的间隔运行Job
- CronJob控制器的功能类似于linux操作系统的周期性任务作业计划(crontab),用于控制作业运行的时间点及周期性运行的方式:
◼ 仅在未来某时间点将指定的作业运行一次
◼ 在指定的周期性时间点重复运行指定的作业
CronJob资源也是标准的API资源类型
-
注意:
-
在CronJob中,通配符“?”和“*”的意义
-
相同,它们都表示任何可用的有效值
-
apiVersion: batch/v1 # API群组及版本; kind: CronJob # 资源类型特有标识; metadata: name

http://www.magedu.com

认证体系与 Service Account
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/



1 Kubernetes的访问控制体系
API Server及其各客户端的通信模型
-
API Server是Kubernetes集群的网关,是能够与etcd通信惟一入口;
-
kube-controller-manager、kube-scheduler、kubelet、kube-proxy,以及后续部署的集群插件CoreDNS、Project Calico等,彼此间互不通信,彼此间的所有协作均经由API Server的REST API进行,它们都是API Server的客户端
-
确保对API Server的安全访问至关重要
-
客户端对API Server的访问应经过身份验证及权限检查;
-
为防止中间人攻击,各类客户端与API Server间的通信都应使用TLS进行加密
-
-
-
各kubelet也会监听一些套接字,提供一个小型的REST API ◼ 10250是具有所在节点上Pod管理权限的读写端口,应谨慎管理
-
10255仅提供只读操作,是REST API的子集
-
另外,10248是本地healthz端点使用的端口
-


http://www.magedu.com
API Server内置的访问控制机制
-
API Server内置了一个有着三级别的访问控制机制
-
认证:核验请求者身份的合法性
-
授权:核验请求的操作是否获得许可
-
准入控制:检查操作内容是否合规
-

-
插件化机制,每种访问控制机制均有一组专用的插件栈
-
认证:身份核验过程遵循“或”逻辑,且任何一个插件核验成功后都将不再进行后续的插件验证 ◆ 均不成功,则失败,或以“匿名者”身份访问
- 建议禁用“匿名者”
-
授权:鉴权过程遵循“或”逻辑,且任何一个插件对操作的许可授权后都将不再进行后续的插件验证 ◆ 均未许可,则拒绝请求的操作
-
准入控制:内容合规性检查过程遵循“与”逻辑,且无论成败,每次的操作请求都要经由所有插件的检验 ◆ 将数据写入etcd前,负责检查内容的有效性,因此仅对“写”操作有效
- 分两类:validating(校验)和mutating(补全或订正)
-

http://www.magedu.com



2 API身份验证
Kubernetes上的用户
-
“用户”即服务请求者的身份指代,一般使用身份标识符进行识别
-
用户标识:用户名或者ID
-
用户组
-
-
Kubernetes系统的用户大体可分为2 类
-
Service Account:服务账户,指Pod内的进程访问API Server时使用的身份信息
- API Server使用ServiceAccount类型的资源对象来保存该类账号
-

- 认证到API Server的认证信息称为Service Account Token,它们保存于同名的专用类型的Secret对象中
- ◆ 名称空间级别
-
User Account:用户账户,指非Pod类的客户端访问API Server时使用的身份标识,一般是现实中的“人” ◆ API Server没有为这类账户提供保存其信息的资源类型,相关的信息通常保存于外部的文件或认证系统中 ◆ 身份核验操作可由API Server进行,也可能是由外部身份认证服务完成
- 本身非由Kubernetes管理,因而作用域为整个集群级别
-
不能被识别为Service Account,也不能被识别为User Account的用户,即“匿名用户”

http://www.magedu.com
身份认证策略
X.509客户端证书认证
-
持有者令牌(bearer token)
-
静态令牌文件(Static Token File)
-
Bootstrap令牌
-
Service Account令牌
-
OIDC(OpenID Connect)令牌
-
Webhook令牌
-
-
身份认证代理(Authenticating Proxy)
匿名请求

图源:https://learnk8s.io/kubernetes-custom-authentication

http://www.magedu.com
API Server启用的身份认证机制
-
基于认证插件支持多种认证方式,而相应认证插件的启用需要经由kube-apiserver上的专用选项完成
-
kubeadm v1.22 部署的集群默认启用的认证机制如右图红框中的选项,它们依次是
-
X509客户端证书认证
-
Bootstrap令牌认证
-
身份认证代理
-
Service Account认证
-
-
注意:API Server并不保证各认证插件的生效次序与定义的次序相同


http://www.magedu.com
kubelet启用的身份认证机制
kubelet的REST API端点默认通过TCP协议的10250端口提供, 支持管理操作
| Kubelet API | 功能简介 |
|---|---|
| /pods | 列出当前kubelet节点上的Pod |
| /run | 在一个容器内运行指定的命令 |
| /exec | 在一个容器内运行指定的命令 |
| /configz | 设置Kubelet的配置文件参数 |
| /debug | 调试信息 |
-
需要对客户端身份进行认证
-
启用的身份认证
-
webhook
-
x509客户端证书认证
-
注意:建议显式禁用匿名用户
-
-
API Server是该API端点的客户端,因此,kubelet需要在验证客户端身份时信任给API Server颁发数字证书的CA
-


http://www.magedu.com
身份认证策略(2)
X.509数字证书认证
-
在双向TLS通信中,客户端持有数字证书,而API Server信任客户端证书的颁发者
- 信任的CA,需要在kube-apiserver程序启动时,通过--client-ca-file选项传递
-
认证通过后,客户端数字证书中的CN(Common Name)即被识别为用户名,而O(Organization)被识别为组名
-
kubeadm部署的Kubernetes集群,默认使用/etc/kubernetes/pki/ca.crt 进行客户端认证
- /etc/kubernetes/pki/ca.crt是kubeadm为Kubernetes各组件间颁发数字证书的CA
-
静态令牌文件
-
令牌信息保存于文本文件中
-
由kube-apiserver在启动时通过--token-auth-file选项加载
-
加载完成后的文件变动,仅能通过重启程序进行重载,因此,相关的令牌会长期有效
-
客户端在HTTP请求中,通过“Authorization Bearer TOKEN”标头附带令牌令牌以完成认证
-

http://www.magedu.com
身份认证策略(3)
Service Account令牌
◼ 该认证方式将由kube-apiserver程序内置直接启用
◼ 它借助于经过签名的Bearer Token来验证请求
◆ 签名时使用的密钥可以由--service-account-key-file选项指定,也可以默认使用API Server的tls私钥
◼ 用于将Pod认证到API Server之上,以支持集群内的进程与API Server通信
◆ Kubernetes可使用ServiceAccount准入控制器自动为Pod关联ServiceAccount
OpenID Connect(OIDC)令牌
◼ OAuth2认证机制,通常由底层的IaaS服务所提供
Webhook令牌认证
◼ 是一种用于验证Bearer Token的回调机制
◼ 能够扩展支持外部的认证服务,例如LDAP等
身份认证代理
◼ 由kube-apiserver从请求报文的特定HTTP标头中识别用户身份,相应的标头名称可由特定的选项配置指定 ◼ kube-apiserver应该基于专用的CA来验证代理服务器身份

http://www.magedu.com



3 认证功能测试
静态令牌认证
-
静态令牌认证的基础配置
- 令牌信息保存于文本文件中 - 文件格式为CSV,每行定义一个用户,由“令牌、用户名、用户ID和所属的用户组”四个字段组成,用户组为可选字段 - 格式:token,user,uid,"group1,group2,group3" - 由kube-apiserver在启动时通过--token-auth-file选项加载 - 加载完成后的文件变动,仅能通过重启程序进行重载,因此,相关的令牌会长期有效 - 客户端在HTTP请求中,通过“Authorization Bearer TOKEN”标头附带令牌令牌以完成认证 -
配置示例
-
① 生成token,命令:echo "$(openssl rand -hex 3).$(openssl rand -hex 8)"
-
② 生成static token文件
-
③ 配置kube-apiserver加载该静态令牌文件以启用相应的认证功能
-
④ 测试,命令:curl -k -H "Authorization: Bearer TOKEN" -k
- https://API_SERVER:6443/api/v1/namespaces/default/pods/
-

http://www.magedu.com
X509客户端认证
- X509客户端认证依赖于PKI证书体系,kubeadm部署Kubernetes集群时会自动生成所需要的证书,它们位于/etc/kubernetes/pki目录下

-
依赖到的PKI体系
- 如右图

- 另外,对Service Account的token进行签名还需要用到一个可选的密钥对儿

http://www.magedu.com
X509客户端认证(2)
所有的证书

-
各kubelet的证书可在Bootstrap过程中自动生成证书签署请求,而后由Kubernetes CA予以签署
-
各kube-proxy、kube-scheduler和kube-controller-manager也都有相应的数字证书以完成向API Server的身份认证

http://www.magedu.com
X509客户端认证(3)
-
X509数字证书认证测试
-
创建客户端私钥和证书签署请求,为了便于说明问题,以下操作在master节点上以/etc/kubernetes/为工作目录
-
① 生成私钥:(umask 077; openssl genrsa -out ./pki/mason.key 4096) -
② 创建证书签署请求:openssl req -new -key ./pki/mason.key -out ./pki/mason.csr -subj "/CN=mason/O=developers" -
③ 由Kubernetes CA签署证书:openssl x509 -req -days 365 -CA ./pki/ca.crt -CAkey ./pki/ca.key -CAcreateserial in ./pki/mason.csr -out ./pki/mason.crt -
④ 将pki目录下的mason.crt、mason.key和ca.crt复制到某部署了kubectl的主机上,即可进行测试-
⚫
这里以k8s-node01为示例;只需要复制mason.crt和mason.key即可,因为集群工作节点上已经有cr.crt文件 -
⚫
命令:scp -rp ./pki/{mason.crt,mason.key} k8s-node01:/etc/kubernetes/pki
-
-
-
在k8s-node01上发起访问测试
-
① 使用kubectl测试:kubectl get pods --client-certificate=$HOME/.certs/mason.crt --client-key=$HOME/.certs/mason.key -- server=https://kubeapi.magedu.com:6443/ --certificate-authority=/etc/kubernetes/pki/ca.crt -
② 也可以使用curl命令进行测试
-
-

http://www.magedu.com



4 Kubeconfig
kubeconfig基础
-
kubeconfig是YAML格式的文件,用于存储身份认证信息,以便于客户端加载并认证到API Server
-
kubeconfig保存有认证到一至多个Kubernetes集群的相关配置信息,并允许管理员按需在各配置间灵活切换
-
clusters:Kubernetes集群访问端点(API Server)列表
-
users:认证到API Server的身份凭据列表
-
contexts:将每一个user同可认证到的cluster建立关联的上下文列表
-
current-context:当前默认使用的context
-
-
-
客户端程序加载的kubeconfig文件的途径及次序
-
--kubeconfig选项
-
KUBECONFIG环境变量:其值是包含有kubeconfig 文件的列表
-
默认路径:$HOME/.kube/config
-


http://www.magedu.com
设定kubeconfig文件
命令:kubectl config SUBCOMMAND [options]
◼ 打印加载的kubeconfig
◆ view
◼ cluster相关的子命令
- get-clusters
◆ set-cluster
◆ delete-cluster
◼ user相关的子命令
◆ get-users
◼ context相关的子命令
◆ get-contexts
-
set-context
-
delete-context
◆ rename-context
◼ current-context相关的子命令
-
current-context
-
use-context
-
set-credentials
◆ delete-user

http://www.magedu.com
设定kubeconfig文件(2)
-
示例1:为静态令牌认证的用户设定一个自定义的kubeconfig文件
-
① 定义Cluster
-
提供包括集群名称、API Server URL和信任的CA的证书相关的配置;clusters配置段中的各列表项名称需要惟一;
-
◆ 命令:kubectl config set-cluster kube-test --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt -- server="https://kubeapi.magedu.com:6443" --kubeconfig=$HOME/.kube/kubeusers.conf
-
-
② 定义User
- 添加身份凭据,使用静态令牌文件认证的客户端提供令牌令牌即可
-
命令:kubectl config set-credentials jerry --token="$JERRY_TOKEN" --kubeconfig=$HOME/.kube/kubeusers.conf
-
③ 定义Context
- 为用户jerry的身份凭据与kube-test集群建立映射关系
-
命令:kubectl config set-context jerry@kube-test --cluster=kube-test --user=jerry --kubeconfig=$HOME/.kube/kubeusers.conf
-
④ 设定Current-Context
- 命令:kubectl config use-context jerry@kube-test --kubeconfig=$HOME/.kube/kubeusers.conf
-

http://www.magedu.com
设定kubeconfig文件(3)
-
示例2:将基于X509客户端证书认证的mason用户添加至kubeusers.conf文件中,同一个列表下,不同项的名称不能相同
-
① 定义Cluster
- 使用不同的身份凭据访问同一集群时,集群相关的配置无须重复定义
-
② 定义User
-
添加身份凭据,基于X509客户端证书认证时,需要提供客户端证书和私钥
-
命令:kubectl config set-credentials mason --embed-certs=true --client-certificate=/etc/kubernetes/pki/mason.crt --clientkey=/etc/kubernetes/pki/mason.key --kubeconfig=$HOME/.kube/kubeusers.conf
-
-
③ 定义Context
-
为用户mason的身份凭据与kube-test集群建立映射关系
-
命令:kubectl config set-context mason@kube-test --cluster=kube-test --user=mason -- kubeconfig=$HOME/.kube/kubeusers.conf
-
-
④ 设定Current-Context
- 命令:kubectl config use-context mason@kube-test --kubeconfig=$HOME/.kube/kubeusers.conf
-

http://www.magedu.com
合并kubeconfig文件
-
客户端能够通过多种途径获取到kubeconfig文件时,将遵循如下逻辑进行文件合并
-
设置了--kubeconfig参数时,则仅使用指定的文件,且不进行合并;该参数只能使用一次;
-
否则,若设置了KUBECONFIG环境变量,则将其值用作应合并的文件列表;处理规则
-
忽略不存的文件
-
遇到内容无法反序列化的文件时,将生成错误信息
-
文件列表中,第一个设定了特定值或映射键(map key)的文件是为生效文件
-
⚫
修改某个映射键的值时,将修改列表中第一个出现该键的文件中的内容; -
⚫
创建一个键时,其将保存于列表中的第一个文件中; -
⚫
若列表中指定的文件均不存在时,则自动创建列表中的最后一个文件;
-
-
-
否则,将使用默认的“${HOME}/.kube/config”,且不进行合并
-
-
context的判定机制
-
若使用了--context选项,则加载该选项指定要使用的上下文
-
否则,将使用合并后的kubeconfig文件中的current-context的设定
-

http://www.magedu.com



5 Service Account
Service Account基础
-
为何需要Service Account?
-
Kubernetes原生(kubernetes-native)托管运行于 Kubernetes之上,通常需要直接与API Server进行交互以获取必要的信息
-
API Server同样需要对这类来自于Pod资源中客户端程序进行身份验证,Service Account也就是设计专用于这类场景的账号
-
ServiceAccount是API Server支持的标准资源类型之一
-
-
在Pod上使用Service Account
- 自动设定:Service Account通常由API Server自动创建并通过ServiceAccount准入控制器自动关联到集群中创建的每个Pod上

- 自定义:在Pod规范上,使用serviceAccountName指定要使用的特定ServiceAccount

http://www.magedu.com
ServiceAccount资源类型
-
ServiceAccount是Kubernetes API上的标准资源类型
-
基于资源对象保存ServiceAccount的数据
-
认证信息保存于ServiceAccount对象专用的Secret中
-
隶属名称空间级别,专供集群上的Pod中的进程访问API Server时使用
-
Kubernetes基于三个组件完成Pod上serviceaccount的自动化
-
⚫
ServiceAccount Admission Controller -
⚫
Token Controller -
⚫
ServiceAccount Controller
-
-
-
需要用到特殊权限时,可为Pod指定要使用的自定义ServiceAccount资源对象
-

http://www.magedu.com
ServiceAccount专用的Secret类型
ServiceAccount使用专用的Secret类型存储相关的敏感信息
-
类型标识为“kubernetes.io/serviceaccount”
-
有三个固定的数据项,键名称分别为
-
ca.crt:Kubernetes CA的数字证书
-
namespace:该ServiceAccount可适用的名称空间
-
token:认证到API Server的令牌
-
-
ServiceAccount Admission Controller负责完成Pod上的ServiceAccount的自动化 ◼ 为每个名称空间生成一个默认的default ServiceAccount及其依赖到的Secret对象; ◼ 为未定义serviceAccountName的Pod资源自动附加名称空间下的serviceaccounts/default;
- 为定义了serviceAccountName的Pod资源检查其引用的目标对象是否存在

http://www.magedu.com
创建和使用ServiceAccount
创建ServiceAccount
◼ 命令式命令
◆ 命令:kubectl create serviceaccount NAME [--dry-run=server|client|none]
◼ 资源配置
apiVersion: v1 kind: ServiceAccount metadata: name: … namespace: … imagePullSecrets <[]Object> secrets <[]Object> automountServiceAccountToken
Pod上引用ServiceAccount对象
◼ 仅支持引用同一名称空间下的对象
apiVersion: v1 kind: Pod metadata: name: … namespace: … spec: serviceAccountName

http://www.magedu.com

鉴权体系与 RBAC
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
Kubernetes的访问控制体系简介


http://www.magedu.com



1 Kubernetes的鉴权体系
访问API Server
-
API Server内置了一个有着三级别的访问控制机制
-
认证:核验请求者身份的合法性
-
鉴权:核验请求的操作是否获得许可
-
准入控制:检查操作内容是否合规
-

-
插件化机制,每种访问控制机制均有一组专用的插件栈
-
认证:身份核验过程遵循“或”逻辑,且任何一个插件核验成功后都将不再进行后续的插件验证
-
均不成功,则失败,或以“匿名者”身份访问
-
建议禁用“匿名者”
-
-
鉴权:鉴权过程遵循“或”逻辑,且任何一个插件对操作的许可授权后都将不再进行后续的插件验证 ◆ 均未许可,则拒绝请求的操作
-
准入控制:内容合规性检查过程遵循“与”逻辑,且无论成败,每次的操作请求都要经由所有插件的检验 ◆ 将数据写入etcd前,负责检查内容的有效性,因此仅对“写”操作有效
- 分两类:validating(校验)和mutating(补全或订正)
-

http://www.magedu.com
Kubernetes鉴权体系
-
API Server中的鉴权框架及启用的鉴权模块负责鉴权
-
支持的鉴权模块
-
Node:专用的授权模块,它基于kubelet将要运行的Pod向kubelet进行授权;
-
ABAC:通过将属性(包括资源属性、用户属性、对象和环境属性等)组合在一起的策略,将访问权限授予用户;
-
◆ RBAC:基于企业内个人用户的角色来管理对计算机或网络资源的访问的鉴权方法;
-
Webhook:用于支持同Kubernetes外部的授权机制进行集成;
-
-
另外两个特殊的鉴权模块是AlwaysDeny和AlwaysAllow;
-
-
配置方法
-
在kube-apiserver上使用--authorization-mode 选项进行定义
- kubeadm部署的集群,默认启用了Node和RBAC
-
多个模块彼此间以逗号分隔
-


http://www.magedu.com



2 RBAC鉴权模型
RBAC基础
-
RBAC基础概念
-
实体(Entity):在RBAC也称为Subject,通常指的是User、Group或者是ServiceAccount;
-
角色(Role):承载资源操作权限的容器;
-
资源(Resource):在RBAC中也称为Object,指代Subject期望操作的目标,例如Secret、Pod及Service对象等; ◆ 仅限于/api/v1/…及/apis/
/ /…起始的路径; - 其它路径对应的端点均被视作“非资源类请求(Non-Resource Requests)”,例如/api或/healthz等端点;
-
动作(Actions):Subject可以于Object上执行的特定操作,具体的可用动作取决于Kubernetes的定义; ◆ 资源型对象
- ⚫ `只读操作:get、list、watch等` - ⚫ `读写操作:create、update、patch、delete、deletecollection等`- 非资源型端点仅支持get操作
-
角色绑定(Role Binding):将角色关联至实体上,它能够将角色具体的操作权限赋予给实体;
-

http://www.magedu.com
RBAC基础(2)
-
角色的类型
-
Cluster级别:称为ClusterRole,定义集群范围内的资源操作权限集合, 包括集群级别及名称空间级别的资源对象;
-
Namespace级别:称为Role,定义名称空间范围内的资源操作权限集合;
-
-
角色绑定的类型
-
Cluster级别:称为ClusterRoleBinding,可以将实体(User、Group或 ServiceAccount)关联至ClusterRole;
-
Namespace级别:称为RoleBinding,可以将实体关联至ClusterRole或 Role;
- 即便将Subject使用RoleBinding关联到了ClusterRole上,该角色赋予到 Subject的权限也会降级到RoleBinding所属的Namespace范围之内;
-

图源:https://res.cloudinary.com/

http://www.magedu.com
RBAC的基本工作逻辑
Namespace、Subject、Role和RoleBinding之间的关系

图源:https://software.danielwatrous.com/
.jpg)
http://www.magedu.com
RoleBinding and ClusterRoleBinding

Cluster-level resources
namespace testing namespace ……
ClusterRole
configmaps-reader
RoleBinding
User or Group
ClusterRoleBinding
namespace testing ClusterRole namespace ……
secrets-reader
Cluster-level resources

http://www.magedu.com
默认的ClusterRole及ClusterRoleBinding
启用RBAC鉴权模块时,API Server会自动创建一组ClusterRole和ClusterRoleBinding对象 ◼ 多数都以“system:”为前缀,也有几个面向用户的ClusterRole未使用该前缀,如cluster-admin、admin等 ◼ 它们都默认使用“kubernetes.io/bootstrapping: rbac-defaults”这一标签
默认的ClusterRole大体可以分为如下5个类别
◼ API发现相关的角色
◆ 包括system:basic-user、system:discovery和system:public-info-viewer
◼ 面向用户的角色
◆ 包括cluster-admin、admin、edit和view
◼ 核心组件专用的角色
◆ 包括system:kube-scheduler、system:volume-scheduler、system:kube-controller-manager、system:node和system:node-proxier等 ◼ 其它组件专用的角色
◆ 包括system:kube-dns、system:node-bootstrapper、system:node-problem-detector和system:monitoring等 ◼ 内置控制器专用的角色

http://www.magedu.com
User-facing Roles
- Some of the default roles are not system: prefixed. These are intended to be user-facing roles.
They include super-user roles (cluster-admin), roles intended to be granted cluster-wide using ClusterRoleBindings (cluster-status), and roles intended to be granted within particular namespaces using RoleBindings (admin, edit, view).

ClusterRole
cluster-admin cluster-status admin edit view
ClusterRoleBinding
ClusterRoleBinding
RoleBinding RoleBinding
Namespace A Namespace B
Clutser-level resources

http://www.magedu.com
面向用户的角色
用于交互式用户授权目的的几个角色
| 默认的ClusterRole | 默认的 ClusterRoleBinding |
描述 |
|---|---|---|
| cluster-admin | system:masters 组 | 允许用户在目标范围内的任意资源上执行任意操作;使用ClusterRoleBinding关联至用户时,授权操作集群及所有名称空间中任何资源;使用RoleBinding关联至用户时,授权控制其所属名称空间中的所有资源,包括Namespace资源自身; |
| admin | 管理员权限,主要用于结合RoleBinding为特定名称空间快速授权生成管理员用户,它能够将 RoleBinding所属名称空间中的大多数资源的读/写权限授予目标用户,包括创建Role和 RoleBinding的能力;但不支持对ResourceQuota及Namespace本身进行操作; |
|
| edit | 接近于admin的权限,支持对名称空间内的大多数对象进行读/写操作,包括Secret,但不允许查看或修改Role及RoleBinding; | |
| view | 允许以只读方式访问名称空间中的大多数对象,但不包括Role、RoleBinding和Secret; |

http://www.magedu.com



3 使用RBAC鉴权机制
Role
命令式命令
◼ kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] ◆ verb:允许在资源上使用的操作(verb)列表
◆ resources.group/subresource:操作可施加的目标资源类型或子资源列表
◆ resourcename:特定的资源对象列表,可选
◼ 示例:kubectl create role pods-viewer --verb="get,list,watch" --resource="pods" --namespace=default 生成的资源对象的资源配置
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pods-viewer namespace: default rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch

http://www.magedu.com
RoleBinding
-
命令式命令
-
命令:kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname]
-
可以绑定到Role,也可以绑定到ClusterRole,后者会将ClusterRole的权限缩减至当前名称空间之内
-
Subject可以是User、Group或者ServiceAccount
-
-
示例:将用户tom绑定至角色pods-viewer之上
-
命令:kubectl create rolebinding tom-attachto-pods-viewer --role=pods-viewer --user=tom --namespace=default
-
而后可测试tom用户是否可读取default名称空间内的pods资源,以及其它资源
-
-
-
引用ClusterRole
-
命令:kubectl create rolebinding jerry-attachto-cluster-admin --clusterrole=cluster-admin --user=jerry --namespace=test
-
◼ 而后可测试jerry用户对test及其它名称空间中的资源对象的访问权限
-

http://www.magedu.com
RoleBinding资源配置
如下示例中,左侧的RoleBinding关联到了Role之上,而右侧的则关联至ClusterRole
| apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding |
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding |
|---|---|
| metadata: | metadata: |
| name: tom-attachto-pods-viewer namespace: default |
name: jerry-attachto-cluster-admin namespace: test |
| roleRef: | roleRef: |
| apiGroup: rbac.authorization.k8s.io kind: Role |
apiGroup: rbac.authorization.k8s.io kind: ClusterRole |
| name: pods-viewer | name: cluster-admin |
| subjects: | subjects: |
| - apiGroup: rbac.authorization.k8s.io kind: User |
- apiGroup: rbac.authorization.k8s.io kind: User |
| name: tom | name: jerry |

http://www.magedu.com
ClusterRole和ClusterRoleBinding
-
命令式命令
-
ClusterRole:kubectl create clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename]
-
◼ ClusterRoleBinding:kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username] [-group=groupname] [--serviceaccount= namespace: serviceaccountname]
-
示例:
-
◆ kubectl create clusterrolebinding mason --clusterrole=view --group=developers
-
资源规范
-
ClusterRole的资源规范同Role相似
-
ClusterRoleBidning的资源规范跟RoleBinding相似
-

http://www.magedu.com



4 使用示例
Prometheus的权限需求
将Prometheus部署运行于Kubernetes之上并监控集群时,需要使用专用的ServiceAccount运行prometheusserver相关的Pod;
| --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: prometheus |
--- apiVersion: v1 kind: ServiceAccount metadata: name: prometheus |
|---|---|
| rules: - apiGroups: [""] resources: - nodes - nodes/proxy - services - endpoints - pods verbs: ["get", "list", "watch"] - apiGroups: - extensions resources: - ingresses verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"] verbs: ["get"] |
namespace: prom --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: prometheus roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus subjects: - kind: ServiceAccount name: prometheus namespace: prom |

http://www.magedu.com
Jenkins的权限需求
运行于Kubernetes之上的Jenkins,为了能够动态创建jenkins-slave相关的Pod,也需要以拥有特定权限的 ServiceAccount运行
| apiVersion: rbac.authorization.k8s.io/v1 | --- |
|---|---|
| kind: ClusterRole | apiVersion: v1 |
| metadata: name: jenkins-master |
kind: ServiceAccount metadata: |
| namespace: jenkins | name: jenkins-master |
| rules: - apiGroups: [""] resources: ["pods"] verbs: ["create","delete","get","list","patch","update","watch"] - apiGroups: [""] resources: ["pods/exec"] verbs: ["create","delete","get","list","patch","update","watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get","list","watch"] - apiGroups: [""] resources: [“events"] verbs: ["watch"] - apiGroups: [""] resources: ["secrets"] verbs: ["get"] |
namespace: jenkins --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jenkins-master namespace: jenkins roleRef: kind: ClusterRole name: jenkins-master apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: jenkins-master namespace: jenkins |

http://www.magedu.com
综合案例
定义资源配置文件,部署并运行Prometheus监控系统


部署并运行Jenkins


http://www.magedu.com
Jenkins Master-Slave on Kubernetes
Jenkins Master以Pod运行于特定的名称空间中,例如jenkins名称空间,且使用了特定的Service Account, 该Service Account有jenkins名称空间中的特定权限

.jpg)

http://www.magedu.com
Jenkins Master-Slave on Kubernetes
设置Slave Pod模板


http://www.magedu.com
Jenkins Master-Slave on Kubernetes
运行pipeline,完成测试
pipeline { agent { kubernetes { inheritFrom 'jenkins-slave' } } stages { stage('Testing...') { steps { sh 'java -version' } } } }


http://www.magedu.com
Jenkins Master-Slave on Kubernetes
设置maven构建环境

pipeline {
agent {
kubernetes {
inheritFrom 'maven-3.8'
}
}
stages {
stage('Build...') {
steps {
container('maven') {
sh 'mvn -version'
}
}
}
}
}


http://www.magedu.com
Jenkins Master-Slave on Kubernetes
maven和docker
pipeline { agent { kubernetes { inheritFrom 'maven-and-docker' } } stages { stage('maven version') { steps { container('maven') { sh 'mvn -version' } } } stage('docker info') { steps { container('docker') { sh 'docker info' } } } } }



http://www.magedu.com

Ingress与应用发布
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
本节大纲
Kubernetes的访问控制体系简介


http://www.magedu.com



1 Ingress和Ingress Controller
Kubernetes集群的流量管理
-
Service
-
基于iptables或ipvs实现的四层负载均衡机制
-
不支持基于URL等机制对HTTP/HTTPS协议进行高级路由、超时/重试、基于流量的灰度等高级流量治理机制
-
难以将多个Service流量统一管理
-
-
Ingress
-
由Ingress API和Ingress Controller共同组成
- 前者负责以k8s标准的资源格式定义流量调度、路由等规则-
后者负责监视(watch)Ingress并生成自身的配置,并据
-
此完成流量转发
-
-
Ingress Controller非为内置的控制器,需要额外部署
- 通常以Pod形式运行于Kubernetes集群之上 - 一般应该由专用的LB Service负责为其接入集群外部流量
-


http://www.magedu.com
Ingress和Ingress Controller
-
Ingress
-
Kubernetes上的标准API资源类型之一
-
仅定义了抽象路由配置信息,只是元数据,需要由相应的控制器动态加载
-
-
Ingress Controller
-
反向代理服务程序,需要监视API Server上Ingress资源的变动,并将其反映至自身的配置文件中
-
◼ Kubernetes的非内置的控制器,需要额外选择部署
-
实现方案有很多,包括Ingress-Nginx、HAProxy、Traefik、Gloo、Contour和Kong等
-
Kubernetes支持同时部署二个或以上的数量的Ingress Controller
-
Ingress资源配置可通过特定的annotation或spec中嵌套专有的字段指明期望加载该资源的Ingress Controller
-
⚫
专用的annotation:kubernetes.io/ingress.class -
⚫
v1.18版本起,Ingress资源配置中增添了新字段:ingressClassName,引用的IngressClass是一种特定的资源类型
-
-
-

http://www.magedu.com
Ingress和Ingress Controller
-
Ingress需要借助于Service资源来发现后端端点
-
但Ingress Controller会基于Ingress的定义将流量直接发往其相关Service的后端端点,该转发过程并不会
-
再经由Service进行


http://www.magedu.com
部署Ingress Controller
-
以Kubernetes社区维护的Ingress-Nginx为例
-
参考https://kubernetes.github.io/ingress-nginx/deploy/
-
根据环境选择,例如,对于kubeadm部署的集群,我们可以选择“Bare-metal”
-
以v1.1.0版为例
- ⚫ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/cloud/deploy.yaml
-
-


http://www.magedu.com
Ingress Nginx的部署模式

external-LB external-LB
External External
Clients Clients
NodePort
kubernetes
NodeX
cluster
ingress-nginx kubernetes
cluster
ingress-nginx
ingress-nginx
api.ikubernetes.io
api.ikubernetes.io
wap.ikubernetes.io
wap.ikubernetes.io

http://www.magedu.com



2 Ingress的类型
类型一:Simple fanout
-
在同一个FQDN下通过不同的URI完成不同应用间的流量分发
-
基于单个虚拟主机接收多个应用的流量
-
常用于将流量分发至同一个应用下的多个不同子应用,同一个应用内的流量由调度算法分发至该应用的各后端端点
-
不需要为每个应用配置专用的域名
-


http://www.magedu.com
类型二:Name based virtual hosting
为每个应用使用一个专有的主机名,并基于这些名称完成不同应用间的流量转发
- 每个FQDN对应于Ingress Controller上的一个虚拟主机的定义
◼ 同一组内的应用的流量,由Ingress Controller根据调度算法完成请求调度


http://www.magedu.com
类型三:TLS
-
Ingress也可以提供TLS支持,但仅限于443/TCP端口
-
若TLS配置部分指定了不同的主机,则它们会根据通过SNI TLS扩展指定的主机名
- 前提:Ingress控制器支持SNI在同一端口上复用
-
TLS Secret必须包含名为tls.crt和的密钥tls.key,它们分别含有TLS的证书和私钥
-


http://www.magedu.com



3 Ingress资源
配置示例
命令式命令
◼ 创建Ingress的命令:kubectl create ingress NAME --rule=host/path=service:port[,tls[=secret]] ◼ 常用选项
◆ --annotation=[]:提供注解,格式为“annotation=value”
◆ --rule=[]:代理规则,格式为“host/path=service:port[,tls=secretname]”
◆ --class=‘’:该Ingress适配的Ingress Class
准备环境:两个Service(demoapp10和demoapp11)
◼ 部署demoapp v1.0
◆ kubectl create deployment demoapp10 --image=ikubernetes/demoapp:v1.0 --replicas=3
◆ kubectl create service clusterip demoapp10 --tcp=80:80
◼ 部署demoapp v1.1
◆ kubectl create deployment demoapp11 --image=ikubernetes/demoapp:v1.1 --replicas=2
◆ kubectl create service clusterip demoapp11 --tcp=80:80

http://www.magedu.com
配置示例(2)
创建Ingress资源
◼ Simple fanout
-
基于URI方式代理不同应用的请求时,后端应用的URI若与代理时使用的URI不同,则需要启用URL Rewrite完成URI的重写
- ⚫ Ingress-Nginx支持使用“annotation nginx.ingress.kubernetes.io/rewrite-target”注解进行
-
示例:对于发往demoapp.magedu.com的请求,将“/v10”代理至service/demoapp10,将“/v11”代理至 service/demoapp11
- ⚫ kubectl create ingress demo --rule="demoapp.magedu.com/v10=demoapp10:80" --rule="demoapp.magedu.com/v11=demoapp11:80" -- class=nginx --annotation nginx.ingress.kubernetes.io/rewrite-target="/"
-
示例2:功能同上,但使用URI的前缀匹配,而非精确匹配,且基于正则表达式模式进行url rewrite
-
⚫ kubectl create ingress demo --rule='demoapp.magedu.com/v10(/|$)(.*)=demoapp10:80' --
- rule='demoapp.magedu.com/v11(/|$)(.*)=demoapp11:80' --class=nginx --annotation nginx.ingress.kubernetes.io/rewrite-target='/$2'
-
-
Name based virtual hosting
-
基于FQDN名称代理不同应用的请求时,需要事先准备好多个域名,且确保对这些域名的解析能够到达Ingress Controller
-
示例:对demoapp10.magedu.com的请求代理至service/demoapp10,对demoapp11.magedu.com请求代理至 service/demoapp11
- ⚫ kubectl create ingress demoapp --rule="demoapp10.magedu.com/=demoapp10:80" --rule="demoapp11.magedu.com/=demoapp11:80" -- class=nginx
-

http://www.magedu.com
配置示例(3)
创建Ingress资源(续)
-
TLS
-
基于TLS的Ingress要求事先准备好专用的“kubernetes.io/tls”类型的Secret对象
-
⚫ (umask 077; openssl genrsa -out magedu.key 2048)
-
⚫ openssl req -new -x509 -key magedu.key -out magedu.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=services.magedu.com
-
⚫ kubectl create secret tls tls-magedu --cert=./magedu.crt --key=./magedu.key
-
-
创建常规的虚拟主机代理规则,同时将该主机定义为TLS类型
- ⚫ kubectl create ingress tls-demo --rule='demoapp.magedu.com/*=demoapp10:80 ,tls=tls-magedu ' --class=nginx
-
注意:启用tls后,该域名下的所有URI默认为强制将http请求跳转至https,若不希望使用该功能,可以使用如下注解选项
- ⚫
--annotation nginx.ingress.kubernetes.io/ssl-redirect=false
- ⚫
-

http://www.magedu.com
Ingress资源规范
Ingress资源规范的v1版本隶属于“networking.k8s.io”群组
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1 kind: Ingress kind: Ingress kind: Ingress metadata: metadata: metadata: annotations: name: demoapp name: tls-demo nginx.ingress.kubernetes.io/rewrite-target: /$2 namespace: default namespace: default nginx.ingress.kubernetes.io/ssl-redirect: "false" spec: spec: name: demo ingressClassName: nginx ingressClassName: nginx namespace: default rules: rules: spec: - host: demoapp10.magedu.com - host: demoapp.magedu.com ingressClassName: nginx http: http: rules: paths: paths: - host: demoapp.magedu.com - backend: - backend: http: service: service: paths: name: demoapp10 name: demoapp10 - backend: port: port: service: number: 80 number: 80 name: demoapp10 path: / path: / port: pathType: Prefix pathType: Prefix number: 80 - host: demoapp11.magedu.com tls: path: /v10(/|$)(.) http: - hosts: pathType: Exact paths: - demoapp.magedu.com - backend: - backend: secretName: tls-magedu service: service: name: demoapp11 name: demoapp11 port: port: number: 80 number: 80 path: /v11(/|$)(.) path: / pathType: Exact pathType: Prefix

http://www.magedu.com



4 基于Ingress Nginx进行灰度发布
基于Ingress Nginx的灰度发布
- Ingress-Nginx支持配置Ingress Annotations来实现不同场景下的灰度发布和测试,它能够满足金丝雀发布、蓝绿部署与A/B测试等不同的业务场景

图源:https://medium.com/

http://www.magedu.com
基于Ingress Nginx的Canary规则
-
Ingress Nginx Annotations支持的Canary规则
-
nginx.ingress.kubernetes.io/canary-by-header:基于该Annotation中指定Request Header进行流量切分,适用于灰度发布以及A/B测试
-
在请求报文中,若存在该Header且其值为 always 时,请求将会被发送到Canary版本
-
若存在该Header且其值为 never 时,请求将不会被发送至Canary版本
-
对于任何其它值,将忽略该Annotation指定的Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较
-
-
nginx.ingress.kubernetes.io/canary-by-header-value:基于该Annotation中指定的Request Header的值进行流量切分, 标头名称则由前一个Annotation(nginx.ingress.kubernetes.io/canary-by-header)进行指定
-
请求报文中存在指定的标头,且其值与该Annotation的值匹配时,它将被路由到Canary版本
-
对于任何其它值,将忽略该Annotation
-
-
nginx.ingress.kubernetes.io/canary-by-header-pattern
-
同canary-by-header-value的功能类似,但该Annotation基于正则表达式匹配Request Header的值
-
若该Annotation与canary-by-header-value同时存在,则该Annotation会被忽略
-
-
.jpg)
http://www.magedu.com
基于Ingress Nginx的Canary规则(2)
-
Ingress Nginx Annotations支持的Canary规则(续)
-
nginx.ingress.kubernetes.io/canary-weight:基于服务权重进行流量切分,适用于蓝绿部署,权重范围0 - 100按百分比将请求路由到Canary Ingress中指定的服务
-
权重为0 意味着该金丝雀规则不会向Canary入口的服务发送任何请求
-
权重为100意味着所有请求都将被发送到Canary 入
-
-
nginx.ingress.kubernetes.io/canary-by-cookie:基于cookie 的流量切分,适用于灰度发布与A/B 测试
-
cookie的值设置为always时,它将被路由到Canary入口
-
cookie的值设置为never时,请求不会被发送到Canary入口
-
对于任何其他值,将忽略cookie 并将请求与其他金丝雀规则进行优先级的比较
-
-
-
规则的应用次序
-
Canary规则会按特定的次序进行评估
-
次序:canary-by-header -> canary-by-cookie -> canary-weight
-

http://www.magedu.com
配置示例
两个示例
-
第一个是基于标头的金丝雀发布
-
第二个是基于权重的金丝雀发布
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1 kind: Ingress kind: Ingress metadata: metadata: annotations: annotations: kubernetes.io/ingress.class: nginx kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "Username" nginx.ingress.kubernetes.io/canary-weight: "10" nginx.ingress.kubernetes.io/canary-by-header-pattern: "(vip|VIP)_.*" name: demoapp-canary-by-weight name: demoapp-canary-by-header-pattern spec: spec: rules: rules: - host: demoapp.magedu.com - host: demoapp.magedu.com http: http: paths: paths: - backend: - backend: service: service: name: demoapp-v11 name: demoapp-v11 port: port: number: 80 number: 80 path: / path: / pathType: Prefix pathType: Prefix

http://www.magedu.com

网络插件及流量转发机制
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/



1 Pod网络的解决方案
Kubernetes网络模型
Kubernetes集群上会存在三个分别用于节点、Pod和Service的网络
- 三个网络于集群节点上完成交汇
◼ 由节点内核中的路由模块,以及iptables/netfilter和ipvs等完成网络间的流量转发


http://www.magedu.com
Kubernetes的Pod网络
-
Kubernetes将Pod网络功能通过CNI委托给了外部的插件,该类插件主要负责解决如下4个问题 ◼ 同一Pod内容器间的通信(Container to Container)
-
Pod间的通信(Pod to Pod)
-
Service到Pod间的通信(Service to Pod)
-
集群外部与Service之间的通信(external to Service)
-

图源:https://medium.com/

http://www.magedu.com
CNI网络插件基础
-
CNI的全称为“容器网络接口”,它是容器引擎与遵循该规范网络插件的中间层,专用于为容器配置
-
网络子系统
-
简单来说,目前的CNI规范主要由NetPlugin(网络插件)和IPAM两个插件API组成
-
网络插件也称Main插件,负责创建/删除网络以及向网络添加/删除容器
- 它专注于连通容器与容器之间以及容器与宿主机之间的通信,同容器相关网络设备通常都由该类插件所创建,例如 bridge、ipvlan、macvlan、loopback、ptp、veth以及vlan等虚拟设备;
-
IPAM的全称“IP Address Management”,该类插件负责创建/删除地址池以及分配/回收容器的IP地址
- 目前,该类型插件的实现主要有host-local和dhcp两个,前一个基于预置的地址范围进行地址分配,而后一个通过dhcp 协议获取地址;
-


http://www.magedu.com
配置容器网络接口的常用方法
-
不同的容器虚拟化网络解决方案中为Pod的网络名称空间创建虚拟接口设备的方式也会有所不同,目前,较为注流的实现方式有虚拟以太网设备(veth)、多路复用及硬件交换三种
-
veth设备:创建一个网桥,并为每个容器创建一对虚拟以太网接口(veth),一个接入容器内部,另一个留置于根名称空间内添加为Linux内核桥接功能或OpenVSwitch(OVS)网桥的从设备
-
多路复用:多路复用可以由一个中间网络设备组成,它暴露多个虚拟接口,使用数据包转发规则来控制每个数据包转到的目标接口
- MACVLAN技术为每个虚拟接口配置一个MAC地址并基于此地址完成二层报文收发,IPVLAN则是分配一个IP地址并共享单个MAC并根据目标IP完成容器报文转发;
-
硬件交换:现今市面上有相当数量的NIC都支持单根I/O虚拟化(SR-IOV),它是创建虚拟设备的一种实现方式,每个虚拟设备自身表现为一个独立的PCI设备,并有着自己的VLAN及硬件强制关联的QoS;SR-IOV提供了接近硬件级别的性能;
-


http://www.magedu.com
Kubernetes的网络解决方案
-
NetPlugin目前常用的实现方案有叠加网络(Overlay Network)和承载网络(Underlay Network)两类 ◼ 叠加网络借助于VXLAN、UDP、IPIP或GRE等隧道协议,通过隧道协议报文封装Pod间的通信报文(IP报文或以太网帧)来构建虚拟网络
- 承载网络通常使用direct routing(直接路由)技术在Pod的各子网间路由Pod的IP报文,或使用bridge、macvlan 或ipvlan等技术直接将容器暴露至外部网络中
-
叠加网络的底层网络也就是承载网络
-
承载网络的解决方案也就是一类非借助于隧道协议而构建的容器通信网络
-
相较于承载网络,叠加网络由于存在额外的隧道报文封装,会存在一定程度的性能开销
-
但希望创建跨越多个L2或L3的逻辑网络子网时,只能借助于叠加封装协议实现
-


http://www.magedu.com
Overlay网络模型
-
VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网)
-
目前最流行的叠加网络隧道协议之一
-
也是由IETF定义的NVO3(Network Virtualization over Layer 3)标准技术之一
-
采用L2 over L4(MAC-in-UDP)的报文封装模式,将二层报文用三层协议进行封装,可实现二层网络在三层范围内进行扩展
-


http://www.magedu.com
Underlay网络模型
-
容器网络中的承载网络是指借助驱动程序将宿主机的底层网络接口直接暴露给容器使用的一种网络构建技术,较为常见的解决方案有macvlan、ipvlan和直接路由等
-
MACVLAN
-
MACVLAN支持在同一个以太网接口上虚拟出多个网络接口,每个虚拟接口都拥有惟一的MAC地址,并可按需配置IP地址
-
MACVLAN允许传输广播和多播流量,它要求物理接口工作于混杂模式
-
与Bridge模式相比,MACVLAN不再依赖虚拟网桥、NAT和端口映射,它允许容器以虚拟接口方式直接连接至物理接口
-


http://www.magedu.com
Underlay网络模型(2)
-
IPVLAN
- IPVLAN类似于MACVLAN,它同样创建新的虚拟网络接口并为每个接口分配惟一的IP地址,不同之处在于, 每个虚拟接口将共享使用物理接口的MAC地址,从而不再违反防止MAC欺骗的交换机的安全策略,且不要求在物理接口上启用混杂模式


http://www.magedu.com
Underlay网络模型(3)
-
Direct Routing(直接路由)
-
放弃跨主机的容器在L2的连通性,而专注于通过路由协议解决它们在L3的通信的解决方案通常可简称为“直接路由”模型
-
跨主机的容器间通信,需要借助于主机上的路由表指示完成报文路由,因此每个主机的物理接口地址都有可能被引用为另一个主机路由报文时的“下一跳(nexthop)”,这就要求各主机的物理接口必须位于同一个L2 网络中
-


http://www.magedu.com



2 主流的网络插件
常见网络插件对比
安装及配置的便捷性


图源:https://itnext.io/

http://www.magedu.com
常见网络插件对比(2)
安全特性


图源:https://itnext.io/

http://www.magedu.com
常见网络插件对比(3)
性能对比


http://www.magedu.com
常见网络插件对比(4)
性能对比(续)



http://www.magedu.com
常见网络插件对比(5)
资源消耗


http://www.magedu.com
常见网络插件对比(6)
资源消耗(续)



http://www.magedu.com
常见的网络插件
综合对比


图源:https://itnext.io/

http://www.magedu.com
如何选择网络插件
-
通常来说,选择网络插件时应该通过底层系统环境限制、容器网络的功能需求和性能需求三个重要的评估标准来衡量插件的适用性
-
底层系统环境限制:公有云环境多有专有的实现,例如Google GCE、Azure CNI、AWS VPC CNI和Aliyun Terway等,它们通常是相应环境上较佳的选择;否则,虚拟化环境限制较多,除叠加网络模型别无选择,可用有Flannel vxlan、Calico ipip、Weave和Antrea等;物理机环境几乎支持任何类型的网络插件,此时一般应该选择性能较好的的Calico BGP、Flannel host-gw或DAMM IPVLAN等
-
容器网络功能需求:支持NetworkPolicy的解决方案以Calico、WeaveNet和Antrea为代表,而且后两个支持节点到节点间的通信加密;而大量Pod需要与集群外部资源互联互通时应该选择承载网络模型一类的解决方案
-
◼ 容器网络性能需求:Overlay网络中的协议报文有隧道开销,性能略差,而Underlay网络则几乎不存这方面的问题;但Overlay或Underlay路由模型的网络插件支持较快的Pod创建速度,而Underlay模型中IPVLAN或 MACVLAN模式中较慢
-

http://www.magedu.com
如何选择网络插件(2)
-
更少的资源消耗及更好的性能,选flannel
-
更在意网络加密等安全因素,选WeaveNet
-
更好的各因素的均衡特征,选Calico


http://www.magedu.com



3 Flannel的网络模型
Flannel简介
-
Flannel
-
由CoreOS研发,兼容CNI插件API,支持Kubernetes、OpenShift、Cloud Foundry、Mesos、Amazon ECS、 Singularity和OpenSVC等平台
-
使用“虚拟网桥和veth设备”的方式为Pod创建虚拟网络接口,通过可配置的“后端”定义Pod间的通信网络, 支持基于VXLAN和UDP的Overlay网络,以及基于三层路由的Underlay网络
-
在IP地址分配方面,它将预留的一个专用网络(默认为10.244.0.0/16)切分成多个子网后作为每个节点的
-
podCIDR,而后由节点以IPAM插件host-local进行地址分配,并将子网分配信息保存于etcd之中
-


http://www.magedu.com
Flannel支持的“后端”
-
flanneld
-
Flannel在每个主机上运行一个名为flanneld的二进制代理程序
-
该程序负责从预留的网络中按照指定或默认的掩码长度为当前节点申请分配一个子网,并将网络配置、已分配的子网和辅助数据(例如主机的公网IP等)存储于Kubernetes API或etcd之中
-
-
Flannel使用称为后端(backend)的容器网络机制转发跨节点的Pod报文,它目前支持的主流backend如下
-
vxlan
-
使用Linux内核中的vxlan模块封装隧道报文,以叠加网络模型支持跨节点的Pod间互联互通
-
额外支持直接路由(Direct Routing)模式,该模式下位于同二层网络内的节点之上的Pod间通信可通过路由模式直接
-
发送,而跨网络的节点之上的Pod间通信仍要使用VXLAN隧道协议转发
-
vxlan后端模式中,flanneld监听于8472/UDP发送封装的数据包;
-
-
host-gw
-
类似于VXLAN中的直接路由模式,但不支持跨网络的节点,因此这种方式强制要求各节点本身必须在同一个二层网络中,不太适用于较大的网络规模
-
有着较好的转发性能,且易于设定,推荐对报文转发性能要求较高的场景使用
-
-
udp
-
使用常规UDP报文封装完成隧道转发,性能较前两种方式低很多,它仅应该用在不支持前两种后端的环境中使用
-
◆ UDP后端模式中,flanneld监听于8285/UDP发送封装的报文
-
-

http://www.magedu.com
Flannel的“后端”
VXLAN后端


net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "VxLAN"
}
}

http://www.magedu.com
Flannel的“后端”(2)
VXLAN Direct Routing


net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "VxLAN",
"Directrouting": true
}
}

http://www.magedu.com
Flannel的“后端”(3)
host-gw后端


net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "host-gw"
}
}

http://www.magedu.com



4 Calico网络插件
Calico简介
-
ProjectCalico
-
三层的虚拟网络方案
-
它把每个节点都当作虚拟路由器(vRouter),把每个节点上的Pod都当作是“节点路由器”后的一个终端设备并为其分配一个IP地址
-
各节点路由器通过BGP(Border Gateway Protocol)协议学习生成路由规则从而实现不同节点上Pod间的互联互通
-
-
Calico在每一个计算节点利用Linux内核实现了一个高效的vRouter(虚拟路由器)进行报文转发,而每
-
个vRouter通过BGP协议负责把自身所属的节点上运行的Pod资源的IP地址信息基于节点的agent程序 (Felix)直接由vRouter生成路由规则向整个Calico网络内传播


http://www.magedu.com
Calico的网络
-
Calico的工作机制
-
Calico把Kubernetes集群环境中的每个节点上的Pod所组成的网络视为一个自治系统,各节点也就是各自治系统的边界网关,它们彼此间通过BGP协议交换路由信息生成路由规则
-
考虑到并非所有网络都能支持BGP,以及BGP路由模型要求所有节点必须要位于同一个二层网络,Calico还支持基于IPIP和VXLAN的叠加网络模型
-
类似于Flannel在VXLAN后端中启用DirectRouting时的网络模型,Calico也支持混合使用路由和叠加网络模型, BGP路由模型用于二层网络的高性能通信,IPIP或VXLAN用于跨子网的节点间(Cross-Subnet)报文转发
-


http://www.magedu.com
Calico架构
-
概括来说,Calico主要由Felix、Orchestrator Plugin、etcd、BIRD和BGP Router Reflector等组件组成 ◼ Felix:Calico Agent,运行于每个节点,主要负责维护虚拟接口设备和路由信息
-
Orchestrator Plugin:编排系统(例如Kubernetes、OpenStack等)用于将Calico整合进行系统中的插件,例如 Kubernetes的CNI
-
etcd:持久存储Calico数据的存储管理系统
-
BIRD:负责分发路由信息的BGP客户端
-
BGP Route Reflector:BGP路由反射器,可选组件,用于较大规模的网络场景
-


http://www.magedu.com

使用Helm管理 Kubernetes应用
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
Helm及应用部署

要部署的应用的资源配置文件以模板形式定义在 Chart 中,
并内置了一个缺省的值文件为基于一个Chart,可以生成一到多模板字串提供默认值个 Release ,即部署实例;
如果部署在同一名称空间下,这些Release需要具有不同的名字;

Helm的工作机制

http://www.magedu.com
Helm及应用部署
-
Helm Client
-
API Server的客户端程序
-
支持使用kubeconfig文件认证到API Server
-
从Chart Repository中下载Chart至本地缓存
-
利用values.yaml完成对Chart中的模板字串的渲染,生成API Server可接受的配置文件
-
用户可以借助于自定义的值文件和命令行选项“--set”等自定义模板字串值,从而完成自定义部署
-
-
Chart
-
主要由部署某应用需要用到的对象配置所构成的配置文件组成
-
这些配置中通常使用了模板字串,以便用户根据需要自定义以完成定制
-
可从社区中获取(https://artifacthub.io/),也可自行创建,并通过社区分发
-
需要先将Chart Repository的信息配置在Helm上才能从中下载Chart
-
Chart保存在本地缓存中
-
-

http://www.magedu.com
Helm及应用
-
部署Helm
-
下载程序文件
-
https://github.com/helm/helm/releases
-
选择合适的版本及适用的系统和平台,例如Linux amd64平台上的helm-v3.10.2-linux-amd64.tar.gz
-
-
展开程序文件
-
而后把helm程序文件复制到$PATH的搜索路径中
-
确保helm有可用的kubeconfig文件认证到API Server
-
-
使用示例
-
~# helm repo add bitnami https://charts.bitnami.com/bitnami
-
~# helm install mysql bitnami/mysql --set auth.rootPassword=[ROOT_PASSWORD] --set primary.persistence.existingClaim=[EXISTING_PVC] --set auth.database=[DB_NAME] --set auth.username=[USER_NAME] --set auth.password=[PASSWORD]
-

http://www.magedu.com
案例:Helm部署WordPress

使用ingress发布服务

http://www.magedu.com
案例:Helm部署Harbor

使用ingress发布服务,并由
harbor自动生成自签证书

http://www.magedu.com
Helm的常用命令
Helm
-
repo
-
search
-
install
-
uninstall
-
list
-
show
-
status
-
upgrade
-
verify
-
pull
-
push
-
history


http://www.magedu.com

部署高可用的 K8S集群
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
高可用控制平面

Master01 Master02 Master03
Controller Controller Controller
Scheduler Scheduler Scheduler
Manager Manager Manager
API Server etcd01 API Server etcd02 API Server etcd03
Keepalived
Nginx Nginx
VIP
kubelet kube-proxy kubelet kube-proxy

http://www.magedu.com
高可用控制平面(2)

kubectl
node X
kube-proxy
load balancer apiserver apiserver
HA cluster load balancer 1 load balancer 0 kubelet
master-0 master-1 master-2
etcd etcd etcd etcd cluster
apiserver apiserver apiserver
controller-manager controller-manager controller-manager leader election
scheduler scheduler scheduler leader election

http://www.magedu.com
高可用控制平面示例架构

Master01 Master02 Master03
Controller Controller Controller
Scheduler Scheduler Scheduler
Manager Manager Manager
API Server etcd01 API Server etcd02 API Server etcd03
要点:
1、使用一个FQDN统一作为API Server的接入点;
2、加入集群之前,每个节点都将该
FQDN解析至第一个Master;
3、加入集群之后,每个Master节点将该
FQDN都解析至自身的IP地址;
4、加入集群之后,在Worker上配置
nginx以对API Server进行代理,并将该
FQDN解析至自身的IP地址;
Nginx Nginx
kubelet kube-proxy kubelet kube-proxy

http://www.magedu.com
节点上的负载均衡器配置示例
各工作节点上的Nginx配置示例

stream {
upstream apiservers {
server k8s-master01.magedu.com:6443 max_fails=2 fail_timeout=30s;
server k8s-master02.magedu.com:6443 max_fails=2 fail_timeout=30s;
server k8s-master03.magedu.com:6443 max_fails=2 fail_timeout=30s;
}
server {
listen 6443;
proxy_pass apiservers;
}
}

http://www.magedu.com

扩展Kubernetes
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/

Node X API server Controller-Manager
nodes Node Controllers
daemonsets DaemonSet Controllers
watches
Pod statefulsets StatefulSet Controllers
deployments
Deployment Controllers
watches
myapp-deploy
kubelet pods
etcd
……
……

http://www.magedu.com

Clients
API server
Custom Resources (CRD)
Core (builtin) Resources
…… ……
Pods Services Deployment MyClusters MyLogs
ControllerService Deployment Controller …… Controller 1MyCustom Controller 2MyCustom ……
Controller Manager Custom Controllers

http://www.magedu.com

Kind: CustomResourcDefinition

kind: CustomResourceType
Custom Resource
CustomResourceType
Object
Object


http://www.magedu.com

kube-apiserver Custom API server 1
etcd
apiextensions-
Core Resources kube-aggregator
apiserver
(Pods, Services, …) (APIservice)
( CRD ) Custom API server 2
etcd

http://www.magedu.com

kube-aggregator
auth.ilinux.io Group cluster.ilinux.io Group
v1alpha2 v1beta1 v1beta2 v1
auth.ilinux.io-v1alpha2 auth.ilinux.io-v1beta1 cluster.ilinux.io-v1beta2
auth.ilinux.io auth.ilinux.io cluster.ilinux.io
Custom API server 1 Custom API server 2 Custom API server 1

http://www.magedu.com

Kubernetes 调度器
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/
Kubernetes的Pod调度框架
Kubernetes的Pod调度框架

node X
Scheduling Queue
… Pod Pod Pod
Kubernetes
Scheduler
node Y
Node List
Pod

http://www.magedu.com

API Server
bind
?watch=true pod.spec.nodeName=“” pod.spec.nodeNode=node3
kube-scheduler
node1 node1
node3
node2 node2
Predicate Priority Select
node3 node3 node1 node3
node4 node4
node5
node5 node5

http://www.magedu.com

kubectl OR Master kubectl OR Master Node X
api call api call
API Server API Server
Pod Pod predicate
customed default default priority scheduler
spec.scheduler: customed scheduler scheduler scheduler extender
bind
Multi Scheduler Scheduler Extender

http://www.magedu.com

CheckNodeUnschedulable
General
HostName
NoDiskConflict
PodFitsHostPorts
PodToleratesNodeTaints
MatchNodeSelector
PodToleratesNodeNoExecuteTaints
PodFitsResources
CheckNodeLabelPresence
CheckServiceAffinity
MaxEBSVolumeCount
MaxGCEPDVolumeCount
MaxCSIVolumeCount
MaxAzureDiskVolumeCount
MaxCinderVolumeCount
CheckVolumeBinding
NoVolumeZoneConflict
EvenPodsSpread
default Predicates
MatchInterPodAffinity
Predicates Ordering

http://www.magedu.com

BalancedResourceAllocation
LeastRequestedPriority
NodePreferAvoidPodsPriority
NodeAffinityPriority
TaintTolerationPriority
InterPodAffinityPriority
SelectorSpreadPriority
ImageLocalityPriority
ResourceLimitsPriority
RequestedToCapacityRatioPriority
EqualPriority
EvenPodsSpreadPriority
MostRequestedPriority
ServiceSpreadingPriority

http://www.magedu.com

k8s-node01 k8s-node02 k8s-node03
gpu=true zone=foo gpu=true
zone=foo zone=bar
nodeAffinity: nodeAffinity:
required: required:
zone IN [“foo”] zone IN [“foo”, “bar”]
Pod gpu EXISTS Pod

http://www.magedu.com

k8s-node01 k8s-node01 k8s-node03 zone=baz
gpu= zone=bar gpu= other nodes
other nodes
other nodes
zone=foo
weight=90 weight=30 weight=60 weight=0
nodeAffinity:
preferred:
gpu Exists, weight=60
zone IN [“foo”, ”bar”], weight=30
Pod

http://www.magedu.com

k8s-node02 k8s-node01
Pod-B Pod-A
kubernetes.io/hostname=k8s-node02 kubernetes.io/hostname=k8s-node01
k8s-node03 k8s-node04
kubernetes.io/hostname=k8s-node03 kubernetes.io/hostname=k8s-node04

k8s-node02 k8s-node01
Pod-B Pod-A
failure-domain.kubernetes.io/zone=foo
k8s-node03 k8s-node04
failure-domain.kubernetes.io/zone=bar

http://www.magedu.com

zone=foo zone=foo zone=foo zone=foo
server-f1 server-f2 server-f3 server-f4
zone foo
zone=bar zone=bar zone=bar zone=bar
app=db server-b2 server-b4
server-b3
server-b1
zone bar
myapp
pods podAffinity (required)
labelSelector:
app: db
topologyKey: zone

http://www.magedu.com

zone=bar

region=Asia region=Asia region=NA region=NA
zone=foo zone=foo zone=bar
db
pod
weight=100 weight=80 weight=20 weight=0
podAffinity (preferred)
app=db, region weight=80
pod
app=db, region

http://www.magedu.com

taints: taints:
k8s-node03
k8s-node01 k8s-node02
(no taints)
tolerations:
Pod-B
Pod-A
(no tolerations)

http://www.magedu.com

Kubernetes 指标
讲师:马永亮(马哥) http://www.magedu.com https://github.com/ikubernetes/

custom.metrics.k8s.io/v1beta1
metrics.k8s.io/v1beta1
Custom Metrics API
k8s-prometheus-adapter
Metrics API
PromQL
Prometheus
metrics-server
/metrics
kubernetes.summary_api
kubelet Pod
Pod
Pod
cAdvisor
Pod

http://www.magedu.com

Collects metrics
Pod Pod
from all nodes
cAdvisor
Pod Heapster
kubelet
Node 1
cAdvisor
Pod Pod
kubelet
Node X
cAdvisor
Collects metrics from all
kubelet
containers on the node Node 2
.jpg)
http://www.magedu.com

GET /apis/metrics.k8s.io/v1beta1
kube-aggregator
GET
another add-on
kube-apiserver metrics-server
api server

http://www.magedu.com

Collects metrics
Pod Pod
from all nodes
cAdvisor
Pod Heapster
kubelet
Node 1
cAdvisor
Pod Pod
kubelet
Node X
cAdvisor
Collects metrics from all
kubelet
containers on the node Node 2

http://www.magedu.com
GET /apis/metrics.k8s.io/v1beta1

HPA v2 kubectl top scheduler
core system metrics
Node X metrics API
resource
API server
estimator
kube-aggregator
usage+ resource
mappings estimates
kubelet
Metrics Server
usage

http://www.magedu.com

GET /apis/metrics.k8s.io/v1beta1
HPA v2 kubectl top scheduler
core system metrics
API server
Node X
kube-aggregator
custom metrics
resource
estimator
HPA API Adapter
monitoring
custom metrics node agent usage+ resource
mappings estimates
Monitoring
container/pod
Cluster Agent kubelet
mappings Metrics Server
(Heapster, Prometheus, …)
usage

http://www.magedu.com
custom.metrics.k8s.io/v1beta1

Kubernetes Metrics
Custom Metrics API
DaemonSet Metrics
k8s-prometheus-adapter Deployment Metrics
Job Metrics
LimitRange Metrics
Node Metrics
PromQL
PersistentVolume Metrics
Prometheus PersistentVolumeClaim Metrics
Pod Metrics
/metrics ……
kube-state-
Node
Application cAdvisor metrics
(exporter)

http://www.magedu.com

Thank You!
