目录
基于StorageClass实现PV的动态供给(Dynamical Provision)
K8s中文文档地址
http://docs.kubernetes.org.cn/
K8s基础概念
什么是K8s?
- K8s全称Kubernetes,是一个能够实现自动部署、自动扩缩容、自动编排的容器管理系统。
K8s核心概念
- Pod:K8s操作的最小操作单元,包含一个或多个container,共享存储和网络;
- ReplicaSet:管理Pod的组件,实现集群中Pods的高可用;
- Deployment:管理ReplicaSet与Pod。正常情况下是使用Deployment而不是ReplicaSet,可以随时了解Pod的部署进度;
- Label:Label是附加在K8s对象(比如Pods)上的键值对;
- Service:一系列具有相同Label的Pods的集合称为Service,可Pod支持Pods的自动发现与负载均衡;
- Selector:选择器,某个组件需要选择别的组件需要通过Selector;
- Node:Pod需要运行在centos机器上,这个机器成为Node。
K8s整体架构与核心组件
- kubectl:K8s客户端;
- Master Node:K8s主节点;
- APIServer:提供了所有内部和外部的 API 请求操作的唯一入口。同时也负责整个集群的认证、授权、访问控制、服务发现等能力;
- Scheduler:负责监听未调度的 Pod,按照预定的调度策略绑定到满足条件的节点上;
- Controller Manager:它负责维护整个 Kubernetes 集群的状态,比如多副本创建、滚动更新等;
- DashBoard:集群监控面板;
- DNS:负责域名解析;
- ETCD:集群的配置中心,负责集群配置信息的存储;
- Worder Node:K8s工作节点;
- kubelet:是每个Node的节点代理,用于Pods的管理与监控,;
- kube-proxy:用于代理Pod,实现service到pod的负载均衡;
- Docker:底层容器技术;
- fluentd:日志采集技术;
K8s常用命令
创建资源
一般创建资源会有两种方式:通过文件或者命令创建。
# 【最常用的方式】基于yaml配置文件创建
kubectl apply -f deployment.yaml
# 通过kubectl命令直接创建
kubectl run nginx_app --image=nginx:1.9.1 --replicas=3
查看资源
# 一般命令的格式会如下:
kubectl get <resource_type>
# 比如获取K8s集群下pod的信息 kubectl get pod
# 更加详细的信息
kubectl get pod -o wide
# 指定资源的信息,格式:kubectl get <resource_type>/<resource_name>,比如获取deployment nginx_app的信息
kubectl get deployment/nginx_app -o wide
# 查看kube-system的pods
kubectl get pods -n kube-system
# 查看所有pods
kubectl get pods --all-namespaces
删除资源
kubectl delete -f pod_nginx_rs.yaml
scale命令
对一个Deployment、RS、StatefulSet进行扩/缩容。
# 调整replicas数值
kubectl scale deployment/nginx_app --replicas=5
autoscale命令
通过创建一个autoscaler,可以自动选择和设置在K8s集群中Pod的数量。
# 基于CPU的使用率创建3-10个pod
kubectl autoscale deployment/nginx_app --min=3 --max=10 --cpu_percent=80
K8s 网络
同一个Pod中的容器通信
- 同一个pod中的容器是共享网络ip地址和端口号的,通信显然没问题;
集群内Pod之间的通信
- 集群中的Pods之间是可以通过IP互相通信的。但是,通过Deployment管理Pod,随时可能对Pod进行扩缩容,这时候Pod的IP地址是变化的;
- K8s集群会把相同或者具有关联的Pod,打上Label,组成Service,而Service有固定的Cluster IP 或域名,不管Pod怎么创建和销毁,都可以通过Service 进行访问,Service接到请求后会基于负载均衡机制转发到具体的Pod。
外部服务访问集群中的Pods
- NodePort:将Service地址映射到宿主的一个端口上,然后可以通过宿主机 ip:port 进行访问【不推荐,因为会占用各个宿主机的端口资源】;
- HostPort:将Pod地址映射到宿主的一个端口上,然后可以通过宿主机 ip:port 进行访问【不推荐,因为会占用各个宿主机的端口资源】;
- LoadBalance:需要k8s之外的第三方支持【不推荐,每个service一个LB,比较浪费和麻烦】;
- Ingress:简单的说是一个全局的负载均衡器,可以通过配置的URL访问相关的Service【推荐的方式】。
什么是Ingress?
- 通常情况下,Service 和 Pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 Service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃。而 Ingress 就是为进入集群的请求提供路由规则的集合;
- Ingress 可以给 Service 提供集群外部访问的 URL、负载均衡、SSL 终止、HTTP 路由等。为了配置这些 Ingress 规则,集群管理员需要部署一个 Ingress Controller,它监听 Ingress 和 Service 的变化,并根据规则配置负载均衡并提供访问入口;
- Ingress 是一种反向代理的抽象,相关实现包括Nginx、HAProxy等,实际使用时选择对应的Ingress Controller部署即可。
ClusterIP与headless
- 一个Service可能有多个Pod,客户端访问时,会基于固定的ClusterIP进行访问,再根据 kube-proxy所配置的 iptables 规则负载均衡到具体Pod;
- 如果将Service的spec.clusterIP设置为 None,那么创建出来的 Service 并不会分配到一个 Cluster IP,此时它就被称为Headless Service,这时我们在其DNS记录中便可以得到所有Pod的地址,这种方式的好处有:
- 用户可以自己选择要连接哪个 Pod,通过查询 Service 的 DNS 记录来获取后端真实负载的 IP 地址,自主选择要连接哪个 IP;
- 可用于部署有状态服务(StatefulSet)。
StatefulSet有状态服务管理
什么是有状态服务?
之前接触的Pod的管理对象比如RC、Deployment、DaemonSet(管理守护进程Pod)和Job(管理一次性任务或定时任务Pod)都是面向无状态的服务,但是现实中有很多服务是有状态的,比如MySQL集群、MongoDB集群、ZK集群等,它们都有以下共同的特点:
- 每个节点都有固定的ID,通过该ID,集群中的成员可以互相发现并且通信;
- 集群的规模是比较固定的,集群规模不能随意变动;
- 集群里的每个节点都是有状态的,通常会持久化数据到永久存储中;
- 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。
StatefulSet的作用
- StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内其他的成员;
- Pod的启动顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态;
- StatefulSet里的Pod采用稳定的持久化存储卷,通过PV/PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷;
- StatefulSet需要与Headless Service配合使用。
K8s 配置管理
ConfigMap与Secret
- 在 K8s 中,一般有 ConfigMap 和 Secret 两种对象,可以用来做配置管理,实现配置信息和容器镜像进行解耦;
- ConfigMap主要用来保存一些非敏感数据,可以用作环境变量、命令行参数或者通过 Volume 方式挂载到 Pod 内的;
- Secret用法与ConfigMap类似,主要用于保存敏感数据;
- ConfigMap 和 Secret 是 K8s 常用的保存配置数据的对象,通过 Volume 方式挂载到 Pod 内的,kubelet 都会定期进行更新,但是通过环境变量注入到容器中是无法感知到 ConfigMap 或 Secret 的内容更新。
K8s Volume持久化存储
Volume管理
- K8s 基于 PersistentVolume 和 PersistentVolumeClaim 对Volume进行管理,实现Pod的持久化;
- PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod;
- PersistentVolumeClaim (PVC) 是对 PV 的申请 声明 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(任意读写、只读等)等信息,Kubernetes 会查找并提供满足条件的 PV,用户无需关注具体实现细节;
- 持久化存储的使用场景:
- MySQL、ZooKeeper、ES、MongoDB 等。
PV的静态供给(Static Provision)
- 管理员通过手动的方式在后端存储平台上提前创建好对应的 Volume,然后通过 PV 定义到 K8s,开发者通过 PVC 来使用;
基于StorageClass实现PV的动态供给(Dynamical Provision)
- 如果没有满足 PVC 条件的 PV,会动态创建 PV;
- 相比静态供给,动态供给有明显的优势:不需要提前创建 PV,减少了管理员的工作量,效率高。
Volume Plugin
- 为了丰富可以对接的存储后端,Kubernetes 中提供了很多volume plugin可供使用:
分类
描述
plugun
数据是否随着Pod删除而删除
临时存储
用于存储一些临时文件
EmptyDir
是
本地存储
用于将一些K8s中定义的配置通过volume映射到容器中使用
ConfigMap
Secret
DownwardAPI
是
(可基于Etcd存储)
使用宿主机上的存储资源
HostPathLocal
否
自建存储平台
客户自己搭建的存储平台
CephFS
GlusterFS
NFS
RBD
...
否
云厂商插件
云厂商提供的插件,供云商K8s使用
awsElasticBlockStore
...
否
Pod 水平自动伸缩
K8s如何进行Pod的自动扩缩容?
- 像 Deployment 这种支持多副本的工作负载,我们就可以通过调整spec.replicas来增加或减少副本数,从而改变整体的业务水位满足我们的需求,即整体负载高时就增加一些实例,负载低就适当减少一些实例来节省资源。
- 当然人为不断地调整spec.replicas的数值显然是不太现实的,HPA(Horizontal Pod Autoscaler)可以根据应用的 CPU 利用率等水位信息,动态地增加或者减少 Pod 副本数量。
K8s上线部署方案
金丝雀发布
- 以前旷工下矿前,会先放一只金丝雀进去用于探测洞里是否有有毒气体,看金丝雀能否活下来,金丝雀发布由此得名;
- 金丝雀发布一般是先发1台或者一个小比例的服务器,主要做流量验证用,国内常称灰度测试。
滚动更新
- 在金丝雀发布基础上的进一步优化改进,一次滚动式发布一般由若干个发布批次组成,每批的数量一般是可以配置的(可以通过发布模板定义);
- 例如,第一批1台(金丝雀),第二批10%,第三批 50%,第四批100%。每个批次之间留观察间隔,通过手工验证或监控反馈确保没有问题再发下一批次。
蓝绿部署
- 一些应用程序上线需要从旧版本立即切到新版本,这时便需要执行蓝绿部署;
- 在进行蓝绿部署时,应用程序的一个新副本(绿)将与现有版本(蓝)一起部署,然后更新应用程序的入口/路由器以切换到新版本(绿)。