1. 云原生基础知识
1.1 云原生简介
- 2004年开始,Google已经开始在内部大规模使用容器技术
- 2008年,Google将Cgroups合并到Linux内核
- 2013年,Docker项目发布
- 2014年,Kubernetes项目正式发布
- 2015年,有Google、RedHat以及微软等大型云计算厂商以及一些开源公司共同牵头成立CNCF(Cloud Native Computing Foundation)云原生计算基金会
- 2017年,CNCF达到170个成员和14个基金项目
- 2018年,CNCF成立三周年有了195个成员,19个基金会项目和11个孵化项目
1.2 云原生的定义
CNCF对于云原生的定义:https://github.com/cncf/toc/blob/main/DEFINITION.md
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。
云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。
1.3 云原生的技术栈
- 容器:以docker为代表的容器运行技术。
- 服务网格:比如Service Mesh等。
- 微服务:在微服务体系结构中,一个项目是由多个松耦合且独立部署的较小组件或者服务组成。
- 不可变基础设施:不可变基础设施可以理解为一个应用运行所需要的基本运行需求,不可变最基本的就是指运行服务的服务器在部署完成后,就不在进行更改的,比如镜像等。
- 声明式API:描述应用程序的运行状态,并且由系统来决定如何创建这个环境,比如一个pod,会有K8S执行创建并维持副本。
1.4 云原生的特征
- 符合12因素应用,12要素应用程序是一种构建应用程序的方法。
- 面向微服务架构。
- 自服务敏捷架构。
- 基于API的协作
- 抗脆弱性。
什么是12因素应用:
1、基准代码:一份基准代码,多部署(用同一个代码库进行版本的控制,并可进行多次的部署)。
2、依赖:显式的声明和隔离相互之间的依赖。
3、配置:在环境中存储配置。
4、后端服务:把后端服务当作一种附加资源。
5、构建、发布、运行:对程序执行构建或打包,并严格分离构建和运行。
6、进程:以一个或多个无状态进程运行应用。
7、端口绑定:通过端口绑定提供服务。
8、并发:通过进程模型进行扩展。
9、易处理:快速的启动,优雅的终止,最大程度上保持健壮。
10、开发环境与线上环境等价:尽可能的保持开发、预发布、线上环境相同。
11、日志:将所有运行中的进程和后端服务的输出流按照时间顺序统一收集、存储和展示。
12、管理进程:一次性管理进程(数据备份等)应该和正常的常驻进程使用同样的运行环境。
1.5 云原生的全景图
https://landscape.cncf.io/
1.6 云原生项目的分类
2. kubernetes
2.1 项目简介
Kubernetes 最初是源于google内部的Borg,Borg是谷歌内部的大规模集群管理系统,负责对谷歌内部很多核心服务的调度和管理,Borg的目的是让用户能够不必操心资源管理的问题,让其专注于自己的核心业务,并做到跨多个数据中心的资源利用最大化。
Borg主要由BorgMaster、Borglet、Borgcfg和Scheduler组成
官网:https://kubernetes.io/
Github:https://github.com/kubernetes/kubernetes
2.2 组件简介
2.2.1 kube-apiserver
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-apiserver/
Kubernetes API server提供了k8s各类资源对象的增删改查以及watch等HTTP REST接口,这些对象包括pods,services,replication controller等,API server 为REST操作提供服务,并为集群的共享状态提供前端,所有其它组件都通过该前端进行交互。
RESTful API:
- 是REST 风格的网络接口,REST描述的是在网络中Client和Server的一种交互的形式。
REST:
- 是一种软件架构风格,或者说是一种规范,其强调HTTP应当以资源为中心,并且规范来URI的风格,规范了HTTP请求的动作(GET/PUT/DELETE/HEAD/OPTIONS)的使用,具有对应的语义。
- https://github.com/Arachni/arachni/wiki/REST-API
- 默认的端口是6443,可通过启动参数 “–secure-port”的值来修改默认配置。
- 默认的IP地址为非本地(Non-localhost)网络端口,通过启动参数“–bind-address”来配置该值。
- 该端口用于接收客户端、Dashboard等外部HTTPS请求。
- 用于基于Token文件或者客户端证书及HTTP Base的认证。
- 用于基于策略的授权。
Kubernetes API 访问测试:
- curl --cacert /etc/kubernetes/ssl/ca.pem -H "Authorization: Bearer your-token " https://127.0.0.1:6443
- / 返回所有的API列表
- /apis 返回API分组
- /api/v1 返回具体版本号的API
- /version 返回API版本信息
- /healthz/etcd 返回与etcd集群的心跳检测结果
- /apis/autoscaling/v1 返回API的详细信息
- /metrics 返回指标数据
2.2.2 kube-scheduler
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-scheduler/
Kube-scheduler 调度器是一个控制面进程,负责将pod指派的符合调度规则的节点上
-
通过调度算法为待调度Pod列表的每个Pod从可用的Node列表中选择一个最合适的Node,并将信息通过API-server写入etcd中。
-
Node节点上的kubelet通过API Server监听到kubernetes Scheduler 产生的Pod绑定信息,然后将获取对应的Pod清单,下载image,并启动容器。
-
策略:
- LeastRequestedPriority 从备选节点列表中选择资源消耗最小的节点(cpu+内存)。
- CalculateNodeLabelPriority 优选含有指定Label的节点。
- BalancedResourceAllocation 优选从备选节点列表中的各项资源使用率最均衡的节点。
-
原则步骤:
1.排除不符合条件的节点。
2.在剩余的可用中选出一个最符合条件的节点。
2.2.2.1 创建pod
2.2.2.2 过滤掉资源不足的节点
2.2.2.3 在剩余可用的节点中进行删选
2.2.2.4 选中节点
2.2.2.5 多Pod调度流程
2.2.2.6 总体的Pod调度创建过程
2.2.3 kube-controller-manager
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-controller-manager/
Kube-controller-manager: 包括一些子控制器(副本控制器、节点控制器、命名空间控制器和服务账号控制器等),控制器作为集群内部的管理中心,负责集群内的Node、pod副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群中的pod副本始终处于预期的工作状态。
2.2.3.1 Pod的高可用机制
- Controller Manager 控制器每间隔5s检查一次节点的状态。
- 如果Controller Manager 控制器没有收到节点的心跳信息,则将该节点标记为不可达。
- 如果40s后仍无法检测到该节点的心跳,则Controller Manager将该节点标记为无法访问,该节点将不再接受创建新的pod。
- 如果该node节点被标记为无法访问后5分钟没有恢复,Controller Manager会自动删除该节点上的所有pod,并在其它可用节点上重建。
- 对应指标:
- Node monitor period : 节点监视周期
- Node monitor grace period :节点监视器宽限期
- Pod evacuation timeout:pod驱逐时间
2.2.4 kube-proxy
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-proxy/
- kube-proxy运行在node上,它反映了node上kubernetes API中定义的服务,并可以通过一组后端进行简单的TCP、UDP和SCTP流转发或者在一组后端中循环TCP、UDP和SCTP转发,用户必须使用API server创建一个服务来配置代理,其实就是kube-proxy通过在主机上维护网络规则,并执行连续转发,从而实现Kubernetes服务的访问。
- Kube-proxy运行在每个节点上,监听API Server中服务对象的变化,在通过管理IPtables或者IPVS规则来实现网络的转发。
- Kube-proxy不同版本可支持三种工作模式
- UserSpace:K8S v1.1之前使用,K8S v1.2后淘汰。
- IPtables:K8S v1.1开始支持,v1.2开始为默认。
- IPVS:K8S v1.9引入,v1.11为正式版本,需要安装ipvsadmin、ipset工具包和加载IPVS内核模块。
2.2.4.1 IPtables 模式
2.2.4.2 IPVS模式
2.2.4.3 IPVS模式相对于IPtables模式的特点
- IPVS相对IPtables效率会高一些,使用IPVS模式需要在运行kube-proxy的节点上安装ipvsadmin、ipset工具包和加载ip_vs内核模块,当kube-proxy以IPVS模式启动时,kube-proxy将验证节点上是否安装了IPVS模块,如果未安装,则kube-proxy将回退到IPtables代理模式。
- 使用IPVS模式,kube-proxy会监视kubernetes Service对象和Endpoint,调用宿主机内核的Netlink接口,以相应的创建IPVS规则并定期与Kubernetes Service对象和Endpoint对象同步IPVS规则,以确保IPVS状态与期望一致。访问服务时,流量将被重定向到其中一个后端pod,IPVS使用hash作为底层数据结构,并在内核空间中工作,这意味着IPVS可以更快的重定向流量,并且在同步代理规则时具有更好的性能。此外,IPVS为负载均衡算法提供了更多的选项,例如:rr(轮询调度)、lc(最小连接数)、dh(目标hash)、sh(源hash)、sed(最短期望延迟)、nq(不排队调度)等。
2.2.4.4 配置使用IPVS及指定的调度算法
https://kubernetes.io/zh/docs/reference/config-api/kube-proxy-config.v1alpha1/#ClientConnectionConfiguration
# cat /var/lib/kube-proxy/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 192.168.6.79
clientConnection:
kubeconfig: "/etc/kubernetes/kube-proxy.kubeconfig"
clusterCIDR: "10.200.0.0/16"
conntrack:
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
healthzBindAddress: 192.168.6.79:10256
hostnameOverride: "192.168.6.79"
metricsBindAddress: 192.168.6.79:10249
mode: "ipvs" #指定使用IPVS规则及调度算法
ipvs:
scheduler: sh
2.2.4.5 开启会话保持
kind: Service
apiVersion: v1
metadata:
labels:
app: test-nginx-service-label
name: test-nginx-service
namespace: test
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30004
selector:
app: nginx
sessionAffinity: ClientIP
sessionAffinity:
clientIP:
timeoutSeconds: 1800
2.2.5 kubelet
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet/
Kubelet 是运行在每一个worker节点上的代理组件,它会监视已分配给节点的pod,具体功能如下:
- 向Master汇报node节点的状态信息
- 接收指令并在Pod中创建docker容器
- 准备Pod所需的数据卷
- 返回Pod的状态
- 在node节点上执行容器健康检查
2.2.6 kubectl
https://kubernetes.io/zh/docs/reference/kubectl/kubectl/
是一个通过命令行对Kubernetes集群进行管理的客户端工具
2.2.7 ETCD
https://kubernetes.io/zh/docs/tasks/administer-cluster/configure-upgrade-etcd/
Etcd是CoreOS公司开发,目前是K8S默认使用的key-value数据存储系统。用于保存K8S集群的所有数据,etcd支持分布式集群功能,生产环境使用时需要为etcd数据提供定期备份机制。
官网:https://etcd.io
github: https://github.com/etcd-io/etcd
如:
- 获取etcd中的所有数据
root@etcd1:~# etcdctl get / --keys-only --prefix
- 直接在etcd中删除K8S集群数据
root@etcd1:~# etcdctl del /registry/pods/default/net-test
root@master1:~# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default net-test1 1/1 Running 1 6d
kube-system calico-kube-controllers-759545cb9c-jw8c2 1/1 Running 1 6d1h
kube-system calico-node-4trpw 1/1 Running 2 6d
kube-system calico-node-4zxff 1/1 Running 1 6d1h
kube-system calico-node-8k6gb 1/1 Running 1 6d1h
kube-system calico-node-mbzs6 1/1 Running 21 6d1h
kube-system coredns-69d445fc94-wsp2w 1/1 Running 1 6d
kubernetes-dashboard dashboard-metrics-scraper-67c9c47fc7-fcqzq 1/1 Running 1 5d23h
kubernetes-dashboard kubernetes-dashboard-86d88bf65-l2qh5 1/1 Running 0 7h11m
2.2.8 DNS
https://kubernetes.io/zh/docs/tasks/administer-cluster/dns-custom-nameservers/
- DNS负责为整个集群提供DNS服务,从而实现服务之间的访问
- coredns
- kube-dns:1.18
- Sky-dns
2.2.9 Dashboard
https://kubernetes.io/zh/docs/tasks/access-application-cluster/web-ui-dashboard/
- Dashboard是基于网页的K8S用户界面,可以使用Dashboard获取运行在集群中的应用概览信息,也可以创建或者修改Kubenetes资源(如Deployment,Job,DaemonSet等),也可以对Deployment实现弹性伸缩,发起滚动升级,重启pod或者使用向导创建新的应用。