本章概述
- kube-apiserver
- kube-scheduler
- kube-controller-manager
- kube-porxy
- Coredns
- dashboard
- etcd
- k8s其他组件
2.1 kube-apiserver
-
kube-apiserver:
官网链接:https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-apiserver/
Kubernetes API server提供了K8S各类资源对象的增删改查及watch等HTTP Rest接口,验证并配置 API 对象的数据,这些对象包括pods、services、replicationcontrollers等,API Server为REST操作提供服务,并为集群的共享状态提供前端,所有其他组件都通过该前端进行交互。
RESTful API:是REST风格的网络接口,REST描述的是在网络中client和server的一种交互形式。 -
kube-apiserver访问流程图
apiserver的访问步骤:
(1)用户认证
(2)请求确认
(3)返回数据
apiserver特点:
该端口默认值为6443,可通过启动参数--secure-port来修改。
默认IP地址为非本地(Non-Localhost)网络端口,通过启动参数--bind-address设置。
该端口用于接收客户端、dashboard等外部HTTPS请求。
用于基于Tocken文件或客户端证书及HTTP Base的认证。
用于基于策略的授权。
API的版本:
Alpha:预览版,可能包含bug或者错误,后期版本会修复且不兼容之前的版本,不建议使用。
Beta:测试版,该版本可能存在不稳定或者潜在的bug,不建议生产使用
v1:稳定版,如apps/v1,经过验证的stable版本,可以在生产环境使用
2.2 kube-scheduler
2.2.1 kube-scheduler介绍
官网链接:https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-scheduler/
Kubernetes调度器是一个控制进程,负责将Pods指派到节点上
kube-scheduler调度过程:
(1)通过调度算法为待调度Pod列表的每个Pod从可用Node列表中选择一个最适合的Node,并将信息写入etcd中。
(2)node节点上的kubelet通过API Server监听到kubernetes scheduler产生的pod绑定信息,然后获取对应的pod清单,下载image,并启动容器
node节点选择策略:
LeastRequestedPriority:优先从备节点列表中选择资源消耗最小的节点(CPU+内存)
CalculateNodeLabelPriority:优先选择含有指定Label的节点
BalancedResourceAllocation:优先从备选节点列表中选择各项资源使用率最均衡的节点
node节点选择规则:
(1)先排除不符合条件的节点
(2)在剩余的可用节点中选出一个最符合条件的节点
2.2.2 K8S pod调度流程
(1)客户端发起请求
(2)api-server验证请求是否合法
api-server收到请求,对用户进行验证,调用本地/etc/.kube/config文件,如果验证不通过,拒绝用户访问(报403,promising deny);验证通过后,对用户命令(验证命令格式、参数)进行验证
(3)api-server验证通过后,将请求指令写入etcd
(4)kube-scheduler会先从etcd获取指令后,对node节点进行资源评分(资源评估策略包括:最小资源优先,设置标签优先,资源均衡优先),把任务调度到资源最优的node上
(5)然后kube-scheduler把调度结果返回api-server,api-server把调度结果写入etcd
(6)node上的kubelet和ectd建立长链接,一直监听etcd,如果有新事件就会立即执行,因此当api-server把调度结果写入etcd后,kubelet会获取新的调度指令
(7)kubelet调用本地node上的运行时(runtime),由运行时(runtime)拉起pod创建容器,容器创建成功后把信息返回给kubelet,由kubelet返回给api-server,api-server写入etcd
(8)此时,用户可以获取到容器创建成功的信息,可以通过kubectl命令获取到pod的信息
2.3 kube-controller-manager
官网链接:https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-controller-manager/
kube-controller-manager:controller manager还包括一些子控制器(副本控制器、节点控制器、命名空间控制器和服务账号控制器等),控制器作为集群内部的管理控制中心,负责集群内的Node、Pod副本,服务端点(Endpoint)、命名空间(NameSpace)、服务账号(ServiceAcount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保及群众的pod副本始终处于预期的工作状态
kube-controller-manager检测机制:
(1)controller-manager控制器每间隔5秒检查一次节点的状态
(2)如果controller-manager控制器没有收到子节点的心跳,则将该node节点标记为不可达
(3)controller-manager将在标记为无法访问之前等待40秒
(4)如果该node节点被标记为无法访问后5分钟还没有回复,controller-manager会删除当前node节点的所有pod并在其他可用节点重建这些pod。
pod高可用机制:
node monitor period:节点监视周期,5s
node monitor grace period:节点监视器宽限期,40s
pod eviction timeout:pod驱逐超时时间,5m
2.4 kube-porxy
2.4.1 kube-proxy介绍
官网链接:https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-proxy/
kube-proxy:kubernetes网络代理运行在node上,它反映了node上kubernetes API中定义的服务,并可以通过一组后端进行简单的TCP、UDP和SCTP流转发或者在一组后端进行循环TCP、UDP和SCTP转发,用户必须使用apiserver API创建一个服务来配置代理,其实就是kube-proxy通过在主机上维护网络规则并执行链接转发来实现kubernetes服务访问
kube-proxy运行在每个节点上,监听API Server中服务对象的变化,再通过管理iptables或者ipvs规则来实现网络的转发
kube-proxy不同版本可支持三种工作模式:
UserSpace:k8s v1.1之前使用,k8s 1,2及以后就已经淘汰
Iptables:k8s 1.1版本开始支持,1.2开始为默认
IPVS:k8s 1.9引入到1.11为正式版本,需要安装ipvsadm、ipset工具包和加载ip_vs内核模块
2.4.2 kube-proxy网络模式
service网络模式
iptables网络模式:
ipvs网络模式:
IPVS相对Iptables效率会更高一些,使用IPVS模式需要在运行kube-proxy的节点上安装ipvsadm、ipset工具包和加载ip_vs内核模块,当kube-proxy以IPVS代理模式启动时,kube-proxy将验证节点上是否安装了IPVS模块,如果未安装,则kube-proxy将回退到iptables代理模式。
使用IPVS模式,kube-proxy会监听kubernetes service对象和endpoints,调用宿主机内核netlink接口以相应的创建ipvs规则并定期预kubernetes service对象、endpoints对象同步ipvs规则,以确保ipvs状态与期望一直,访问服务时,流量将被重定向到其中一个后端pod,ipvs使用哈希表作为底层数据结构并在内核空间中工作,这意味着ipvs可以更快的重定向流量,并且在同步代理规则时具有更好的性能。
此外,ipvs为负载均衡算法提供了更多的选项,例如:rr(轮询调度)、lc(最小连接数)、dh(目标哈希)、sh(源地址哈希)、sed(最短期望延迟)、nq(不排队调度)等。
2.4.3 如何更改调度算法
具体操作步骤如下:
vim /var/lib/kube-proxy/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
kubeconfig: "/etc/kubernetes/kube-proxy.kubeconfig"
clusterCIDR: "172.20.0.0/16"
conntrack:
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: "172.31.7.101"
metricsBindAddress: 0.0.0.0:10249
mode: "ipvs" #指定使用ipvs及调度算法
ipvs: #注意:如果要指定调度算法,一定要加该选项
scheduler: sh #指定使用源地址哈希调度算法
2.5 Coredns
2.5.1 coredns介绍
DNS组件历史版本有skydns、kube-dns和coredns,k8s 1.3版本之前使用skydns,之后的版本到1.17及之间的版本使用kube-dns,目前主要使用coredns,DNS组件用于解析k8s集群中service name所对应的ip地址。
官网地址:https://coredns.io/
github项目:https://github.com/coredns/coredns
coredns特性:
1. 实现域名解析
2. 自身容器状态的监控
3. 实现监控状态的输出,提供一个http接口,可以使用Prometheus监控coredns的状态
4. Coredns本身不存储数据,所有数据均存储在etcd,当需要查询域名时,需要通过apiserver在etcd查询域名对应的解析关系,etcd返回给apiserver,再由apiserver返回给coredns
2.5.2 kubernetes域名解析流程
1.K8S集群内部dns解析
逻辑图:
DNS解析流程:
(1)客户端向k8s集群发起请求
(2)请求经过外网CDN、WAF等设备到达pod,pod内的nginx对请求进行解析,静态资源请求直接返回结果,动态资源请求转发给后端的tomcat。而tomcat需要service进行调用(在tomcat前端存在一个service对tomcat进行调用),但service是一个域名,nginx并不知道service域名的对应ip地址,于是请求coredns获取service的ip地址
(3)coredns本地并不存储数据,所有数据存在etcd,于是通过apiserver向etcd查询域名对应ip地址
(4)apiserver向etcd请求tomcat前端service域名对应ip
(5)etcd通过查询本地数据把tomcat前端service域名对应ip返回给apiserver
(6)apiserver获取到域名对应ip后,返回给coredns
(7)coredns再把地址返回给nginx
(8)这样,nginx就获取到了tomcat前端service域名的ip地址,把动态请求转发给service
(9)由service把请求转发给tomcat,由tomcat处理动态资源的请求
以上是对k8s集群内部的域名解析,除此之外还有对k8s集群外部的域名解析
- K8S集群外部域名解析
K8S集群内部有些服务需要访问公网,比如公司内部服务需要调用银联或支付宝的接口完成支付服务。
逻辑图:(注意查看黄色图标以及红色指标线)
DNS解析流程:假设,公司内部应用需要调用支付宝接口完成支付 (1)tomcat不知道支付宝域名对应ip地址,向coredns请求 (2)一般情况下支付宝的权威解析服务器都在公网,在etcd上查询不到对应ip地址,coredns上会做forword转发把请求转发到k8s集群外部的公司自建DNS服务器 (3)而公司自建DNS服务器查询自身解析,如果还是查询不到,则会向上一级DNS服务器(如运营商DNS)查询 (4)一般情况下,运营商DNS服务器可以查询到大部分域名解析关系(包括支付宝),如果还是查询不到,则会继续向上一级DNS服务器(根域名服务器)查询 (5)根域名服务器查询到对应ip地址后,把地址返回给运行商DNS服务器 (6)运营商DNS服务器把ip地址返回给公司自建DNS服务器 (7)公司自建DNS服务器再转发给coredns (8)由coredns把支付宝域名对应ip地址返回给tomcat 这样tomcat就获取到支付宝域名的ip地址,把请求转发出去
注意:为了便于理解,这里把K8S集群内部DNS解析和集群外部(公网)流程拆分来看,一般情况下,一个完整的请求处理既包括集群内部的DNS解析还包括了集群外部的DNS解析,需要二者结合来看。
2.5.3 coredns配置
配置文件主要内容:
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes magedu.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . 223.6.6.6 {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
myserver.online { #自定义forward转发,请求myserver.onlne域名的请求都转发给172.16.16.16的53端口,172.16.16.16一般为公司内部自建DNS服务器
forward . 172.16.16.16:53 #转发到172.16.16.16的53端口
}
字段说明:
errors:错误信息标准输出
health:在CoreDNS的http://localhosts:8080/health端口提供CoreDNS服务的健康报告
ready:监听8181端口,当coredns的插件都已就绪时,访问该接口会返回200 OK
kubernetes:CoreDNS将基于kubernetes service name进行DNS查询并返回查询记录给客户端(注意:配置文件中的kubernetes的解析地址就是coredns的地址)
Prometheus:CoreDNS的度量指标数据以Prometheus的key-value格式在http://localhost:9153/metrics URI上提供
forward:不是kubernetes集群内的其他任何域名查询豆浆转发到预定义的目的server,如(/etc/resolv.conf或IP(如8.8.8.8))
cache:启用service解析缓存,单位为秒
loop:检测域名解析是否有死循环,如coredns转发给内网DNS服务器,而内网DNS服务器又转发给coredns,如果发现解析是死循环,则强制终止CoreDNS进程(kubernetes会重建)
reload:检测corefile是否更改,在重新编辑configmap配置后,默认2分钟后会优雅的自动加载
loadbalance:轮询DNS域名解析,如果一个域名存在多个记录则轮询解析
2.6 dashboard
github官网链接:https://github.com/kubernetes/dashboard
Kubernetes dashboard是用于kubernetes集群的前端UI组件,允许用户管理集群中运行的应用程序并对其进行故障排查,以及管理集群本身。
除了官方的dashboard之外,国内一些公有云厂商也提供了他们自己研发的dashboard,内容更详细,功能更丰富。如:阿里、京东、腾讯等。
还有社区开发的dashboard,如rancher(国外社区开发)、kuboard(国内社区开发)、kubesphere(青云)等。
rancher链接:https://rancher.com/docs/rancher/v1.6/zh/
rancher安装:https://rancher.com/quick-start
kuboard链接:https://kuboard.cn/support/#kuboard-%E4%BB%8B%E7%BB%8D
kuboard安装:https://kuboard.cn/install/v3/install-built-in.html#%E9%83%A8%E7%BD%B2%E8%AE%A1%E5%88%92
kubesphere链接:https://kubesphere.io/zh/
kubesphere安装:https://kubesphere.io/zh/docs/quick-start/all-in-one-on-linux/
或https://kubesphere.io/zh/docs/installing-on-linux/introduction/multioverview/
注意:官方dashboard和K8S版本有兼容问题,在部署之前要先查看k8s集群版本是否和dashboard完全兼容,如下图所示,dashboard v2.5.1兼容k8s 1.23之前的版本,超过该版本则存在兼容性问题,部分功能可能不支持,部署时需要注意
2.7 etcd
2.7.1 etcd介绍
官方网站:https://etcd.io/
github地址:https://github.com/etcd-io/etcd
https://etcd.io/docs/v3.4/op-guide/hardware/ #官方硬件推荐
etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现。(注意:etcd中的key是指存储数据的路径,和redis中的key并不相同,这是因为k8s中一个pod下可能存在多个容器,通过路径来区分不同pod数据)
etcd具有下面这些属性:
完全复制:集群中的每个节点都可以使用完整的存档
高可用性:Etcd可用于避免硬件的单点故障或网络问题
一致性:每次读取都会返回跨多主机的最新写入
简单:包括一个定义良好、面向用户的API(gRPC)
安全:实现了带有可选的客户端证书身份验证的自动化TLS
快速:每秒10000次写入的基准速度
可靠:使用Raft算法实现了存储的合理分布Etcd的工作原理
K8S集群硬件配置推荐:
etcd:
8C 8G SSD硬盘 可支持数百个pod
8C 16G SSD硬盘 可支持数千个pod
16G 32G SSD硬盘 可支持上万个pod
node:
系统盘可以使用机械盘,推荐使用SSD
数据盘使用SSD,一般将容器的/var/lib/docker目录挂载到SSD硬盘上
master:
要求CPU性能要足够强
k8s集群的master上的各组件均通过api-server和etcd进行交互
2.7.2 etcd配置介绍
查看etcd节点(172.31.7.106)配置文件:
内容如下:
cat /etc/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd #数据保存目录
ExecStart=/usr/local/bin/etcd \ #二进制文件路径
--name=etcd-172.31.7.107 \ #etcd名称,k8s集群内etcd节点名称不能相同
--cert-file=/etc/kubernetes/ssl/etcd.pem \ #公钥文件路径
--key-file=/etc/kubernetes/ssl/etcd-key.pem \ #私钥文件路径
--peer-cert-file=/etc/kubernetes/ssl/etcd.pem \
--peer-key-file=/etc/kubernetes/ssl/etcd-key.pem \
--trusted-ca-file=/etc/kubernetes/ssl/ca.pem \ #ca证书
--peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
--initial-advertise-peer-urls=https://172.31.7.107:2380 \ #初始化时通告自己的集群端口
--listen-peer-urls=https://172.31.7.107:2380 \ #集群之间通讯端口
--listen-client-urls=https://172.31.7.107:2379,http://127.0.0.1:2379 \ #客户端访问地址,https的地址可以通过外部访问,http的地址只能在内部访问
--advertise-client-urls=https://172.31.7.107:2379 \ #通告自己的客户端端口
--initial-cluster-token=etcd-cluster-0 \ #创建集群使用的token,一个集群内的节点保持一致
--initial-cluster=etcd-172.31.7.106=https://172.31.7.106:2380,etcd-172.31.7.107=https://172.31.7.107:2380,etcd-172.31.7.108=https://172.31.7.108:2380 \ #集群所有的节点信息
--initial-cluster-state=new \ #新建集群的时候的值为new,如果是已经存在的集群为existing
--data-dir=/var/lib/etcd \ #数据目录路径,该目录存储etcd全部数据,一旦出现问题,k8s集群将会出现问题
--wal-dir= \
--snapshot-count=50000 \ #指定快照数量,快照是用于对etcd做数据备份的
--auto-compaction-retention=10 \ #假设值为10,表示第一次等待10小时后进行压缩,10小时以后每隔10小时*10%=1小时压缩一次
--auto-compaction-mode=periodic \ #对etcd数据进行周期性压缩
--max-request-bytes=10485760 \ #request size limit(请求的最大字节数,即一个请求的最大值是多少,默认一个key最大1.5M,官方推荐最大10M)
--quota-backend-bytes=8589934592 #storage size limit(磁盘存储空间大小限制,默认为2G,此值超过8G启动会有告警信息)
Restart=always
RestartSec=15
LimitNOFILE=65536
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
查看etcd数据目录
wal是预写式日志,在插入数据时,先写完成日志再保存数据,如果日志没有写入成功就相当于数据没有写入完成,后期可通过日志恢复etcd数据,类似于mysql的binlog日志
etcd碎片整理:
ETCDCTL_API=3 /usr/local/bin/etcdctl defrag --cluster --endpoints=https://172.31.7.106:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/etcd.pem --key=/etc/kubernetes/ssl/etcd-key.pem
备注:可以配置计划任务,每周整理一次
2.8 k8s其他组件
2.8.1 kubelet
官网链接:https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet/
kubelet是运行在每个worker节点的代理组件,它会监视已分配给节点的pod,具体功能如下:
向master汇报node节点的状态信息
接受指令并在pod中创建docker容器
准备pod所需的数据卷
返回pod的运行状态
在node节点执行容器健康检查
2.8.2 kubectl
官网链接:https://kubernetes.io/zh/docs/reference/kubectl/kubectl/
kubectl是一个通过命令行对kubernetes集群进行管理的客户端工具
文章评论