文章目录
一. k8s介绍
概念介绍
Kubernetes 有如下几个核心的功能
- 服务的发现与负载的均衡;
- 容器的自动装箱,我们也会把它叫做 scheduling,就是“调度”,把一 个容器放到一个集群的某一个机器上,Kubernetes 会帮助我们去做 存储的编排,让存储的声明周期与容器的生命周期能有一个连接;
- Kubernetes 会帮助我们去做
自动化的容器的恢复
。在一个集群中, 经常会出现宿主机的问题或者说是 OS 的问题,导致容器本身的不可 用,Kubernetes 会自动地对这些不可用的容器进行恢复; - Kubernetes 会帮助我们去做
应用的自动发布与应用的回滚
,以及与 应用相关的配置密文的管理; - 对于 job 类型任务,Kubernetes 可以去做
批量的执行
; - 为了让这个集群、这个应用
更富有弹性
,Kubernetes 也支持水平的 伸缩
。
kubernetes功能详解
- 调度 Kubernetes 可以把用户提交的容器放到 Kubernetes 管理的集群的某 一台节点上去。Kubernetes 的调度器是执行这项能力的组件,它会观察 正在被调度的这个容器的大小、规格。
比如说它所需要的CPU
以及它所需要的memory
,然后在集群中找一台 相对比较空闲的机器来进行一次 placement,也就是一次放置的操作。在 这个例子中,它可能会把红颜色的这个容器放置到第二个空闲的机器上, 来完成一次调度的工作
- 自动修复 Kubernetes 有一个节点健康检查的功能,它会监测这个集群中所有的宿 主机,当宿主机本身出现故障,或者软件出现故障的时候,这个节点健康 检查会自动对它进行发现。 下面 Kubernetes 会把运行在这些失败节点上的容器进行自动迁移,迁移 到一个正在健康运行的宿主机上,来完成集群内容器的一个
自动恢复
3. 水平伸缩 Kubernetes 有业务负载检查的能力,它会监测业务上所承担的负载,如 果这个业务本身的 CPU 利用率过高,或者响应时间过长,它可以对这个 业务进行一次扩容
。
比如说在下面的例子中,黄颜色的过度忙碌,Kubernetes 就可以把黄颜 色负载从一份变为三份。接下来,它就可以通过负载均衡把原来打到第一 个黄颜色上的负载平均分到三个黄颜色的负载上去,以此来提高响应的时 间。
Kubernetes 的架构()
Kubernetes 架 构 是 一 个 比 较 典 型 的 二 层 架 构
和 server-client
架 构 。
Master 作为中央的管控节点,会去与 Node 进行一个连接所有 UI 的、clients、这些 user 侧的组件,只会和 Master 进行连接, 把希望的状态或者想执行的命令下发给 Master,Master 会把这些命令或 者状态下发给相应的节点,进行最终的执行。
从上图,我们可以看到K8S组件和逻辑及其复杂,但是这并不可怕,我们从宏观上先了解K8S是怎么用的,从上图我们可以看出:
Kubernetes集群主要由Master和Node两类节点组成
- Master的组件包括:
apiserver
、controller-manager
、scheduler
和etcd
等几个组件,其中apiserver是整个集群的网关。 - Node主要由
kubelet
、kube-proxy
、docker
引擎等组件组成。kubelet是K8S集群的工作与节点上的代理组件。 - 一个完整的K8S集群,还包括
CoreDNS
、Prometheus
(或HeapSter)、Dashboard
、Ingress
,Controller
等几个附加组件。
其中cAdivsor组件作用于各个节点(master和node节点)之上,用于收集及收集容器及节点的CPU、内存以及磁盘资源的利用率指标数据,这些统计数据由Heapster
聚合后,可以通过apiserver访问。
二. k8s 组件介绍(kubernetes)
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-apiserver/
-
kube-
api
server:Kubernetes API server为 api 对象验证并配置数据
,包括 pods、services、 replication,controllers 和其它 api 对象,API Server 提供 REST 操作和到集群共享状态的前端,所有其他组件通过它进行交互。
主要作用:组件与组件之间的通信
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-scheduler/ -
Kubernetes
scheduler
:调度器是一个拥有丰富策略、能够感知拓扑变化、支持特定负载的功能组件
,它对集群的可用性、性能表现以及容量都影响巨大。
scheduler需要考虑独立的和集体的资源需求
、服务质量需求、硬件/软件/策略限制、亲和与反亲和规范、数据位置、内部负载接口、截止时间等等。如有必要,特定的负载需求可以通过 API 暴露出来。
主要作用:依据 它对 CPU、对 memory 请求大小,找一台合适的节点,进行放置
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-controller-manager/
- kube-
controller
-manager:控制器Controller Manager 作为集群内部的管理控制中心
,负责集群内的 Node、Pod 副本
、服务端点
(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个 Node意外宕机时,Controller Manager 会及时发现并执行自动化修复流程
,确保集群始终处于预期
的工作状态。
主要用于:自动
对容器进行修复
、水平扩张
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-proxy/
- kube-proxy : Kubernetes
网 络 代 理
运 行 在 node 上,它反映了 node 上Kubernetes API 中定义的服务,并可以通过一组后端进行简单的 TCP、UDP 流转发或循环模式(round robin))的 TCP、UDP 转发,用户必须使用 apiserver API 创建一个服务来配置代理,其实就是 kube-proxy 通过在主机上维护网络规则并执行连接转发来实现 Kubernetes 服务访问
。
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet/
- kubelet:是主要的节点代理,它会
监视已分配给节点的 pod
,具体功能如 下:
向 master汇报 node 节点的状态信息
接受指令并在 Pod 中创建 docker 容器
准备 Pod 所需的数据卷
返回 pod 的运行状态
在 node 节点执行容器健康检查
https://github.com/etcd-io/etcd
- etcd 是 Kubernetes 提供默认的存储系统,
保存所有集群数据
,使用时需要为 etcd数据提供备份计划
,key-value存储
API Server 中所需要的这些原 信息都被放置在 etcd 中,etcd 本身是一个高可用系统,通过 etcd 保证整个 Kubernetes 的 Master 组件的高可用性。
Server端 和node端 组件有哪些
Server端
Server控制端:通过API接受用户指令
创建,删除容器,代码升级
apiserver
controller-manager
scheduler
etcd
kubectl 命令行工具
kube-proxy
node节点
node节点:真正运行容器的地方,是真正运行业务负载的
每个业务负载会以 Pod 的形式运行
kublelet
kube-proxy
在 OS 上去创建容器所需要运行的环境,最终把容器或者 Pod 运行起 来,也需要对存储跟网络进行管理。Kubernetes 并不会直接进行网络存 储的操作,他们会靠 Storage Plugin 或者是网络的 Plugin 来进行操作。 用 户 自 己 或 者 云 厂 商 都 会 去 写 相 应 的 Storage Plugin 或 者 Network Plugin,去完成存储操作或网络操作。 在 Kubernetes 自己的环境中,也会有 Kubernetes 的 Network,它是 为了提供 Service network 来进行搭网组网的。(等一下我们也会去介 绍“service”这个概念。)真正完成 service 组网的组件的是 Kube-proxy
, 它是利用了 iptable 的能力来进行组建 Kubernetes 的 Network,就是 cluster network,以上就是 Node 上面的四个组件。
用户可以通过 UI 或者 CLI 提交一个 Pod 给 Kubernetes 进行部署, 这 个 Pod 请 求 首 先 会 通 过 CLI 或 者 UI 提 交 给 Kubernetes API Server,下一步 API Server 会把这个信息写入到它的存储系统 etcd, 之后 Scheduler 会通过 API Server 的 watch 或者叫做 notification 机制得到这个信息:有一个 Pod 需要被调度。
这个时候 Scheduler 会根据它的内存状态进行一次调度决策,在完成这 次调度之后,它会向 API Server report 说:“OK!这个 Pod 需要被调 度到某一个节点上。”
这个时候 API Server 接收到这次操作之后,会把这次的结果再次写到 etcd 中,然后 API Server 会通知相应的节点进行这次 Pod 真正的执 行 启 动 。 相 应 节 点 的 kubelet 会 得 到 这 个 通 知 , kubelet 就 会 去 调 Container runtime 来真正去启动配置这个容器和这个容器的运行环境, 去调度 Storage Plugin 来去配置存储,network Plugin 去配置网络。
客户端
kubectl
dashboard
部署工具:
使用批量部署工具如(ansible/ saltstack)、手动二进制
、apt-get/yum 等方式安装,以守护进程的方式启动在宿主机上
,类似于是 Nginx 一样使用 service 脚本启动。
master,node作用
-
Master:是集群的网关和中枢枢纽,
主要作用
:暴露API接口,跟踪其他服务器的健康状态、以最优方式调度负载,以及编排其他组件之间的通信。单个的Master节点可以完成所有的功能,但是考虑单点故障的痛点,生产环境中通常要部署多个Master节点,组成Cluster。 -
Node:是Kubernetes的工作节点,负责接收来自Master的工作指令,并根据指令相应地创建和销毁Pod对象,以及调整网络规则进行合理路由和流量转发。生产环境中,Node节点可以有N个。
三. master运行机制
1. kube-apiserver:
k8s API Server提供了k8s各类资源对象(pod
,RC,Service等)的增删改查
及watch等HTTP Rest接口,是整个系统的数据总线和数据中心。
apiserver 目前在master监听两个端口,
- 通过
--insecure-port int
监听一个非安全的127.0.0.1本地端口(默认为8080
)
该端口用于接收HTTP请求;
该端口默认值为8080,可以通过API Server的启动参数“–insecure-port”的值来修改默认值;
默认的IP地址为“localhost”,可以通过启动参数“–insecure-bind-address”的值来修改该IP地址;
非认证或授权的HTTP请求通过该端口访问API Server。
- 通过参数
--bind-address=1.1.1.1
监听一个安全的端口(默认为6443
)
该端口默认值为6443,可通过启动参数“–secure-port”的值来修改默认值;
默认IP地址为非本地(Non-Localhost)网络端口,通过启动参数“–bind-address”设置该值;
该端口用于接收HTTPS请求;
用于基于Tocken文件或客户端证书及HTTP Base的认证;
用于基于策略的授权;
- kubernetes API Server的
功能
与使用:
提供了集群管理的REST API接口(包括认证授权、数据校验以及集群状态变更);
提供其他模块之间的数据交互和通信的枢纽(其他模块通过API
Server查询或修改数据,只有API Server才直 接操作etcd);
是资源配额控制的入口;
拥有完备的集群安全机制.
curl 127.0.0.1:8080/apis #分组api #
curl 127.0.0.1:8080/api/v1 #带具体版本号的api #
curl 127.0.0.1:8080/ #返回核心api列表 #
curl 127.0.0.1:8080/version #api 版本信息 #
curl 127.0.0.1:8080/healthz/etcd #与etcd的心跳监测 #
curl 127.0.0.1:8080/apis/autoscaling/v1 #api的详细信息
启动脚本
cat /etc/systemd/system/kube-apiserver.service
[Service]
ExecStart=/usr/bin/kube-apiserver \
--bind-address=192.168.7.101 \ #外部监听端口
--insecure-bind-address=127.0.0.1 \ #本机监听端口
....
LimitNOFILE=65536
2. kube-controller-manager
Controller Manager作为集群内部的管理控制中心,
负责集群内的Node、Pod
副本、服务端点(Endpoint
)、命名空间(Namespace
)、服务账号(ServiceAccount
)、资源定额(ResourceQuota
)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。
例如你删一个
kubectl delete pods bet-test-1dsakjfhaskdj
等会会儿他就会自己创建
kubectl get pods
启动脚本:
vim /etc/systemd/system/kube-controller-manager.service
[Service]
ExecStart=/usr/bin/kube-controller-manager \
--master=http://127.0.0.1:8080 \ #调用kube-api-server的本地端口进行通信
...
3. kube-scheduler
Scheduler负责Pod调度
,在整个系统中起"承上启下"作用,
承上
:负责接收Controller Manager创建的新的Pod,为其选择一个合适的Node;
启下
:Node上的kubelet接管Pod的生命周期。
通过调度算法为待调度Pod列表
的每个Pod
从可用Node列表中选择一个最适合的Node
,并将信息写入etcd中 node节点上的kubelet通过API Server监听到
kubernetes Scheduler产生的Pod绑定信息
,然后获取对应的 Pod清单,下载Image,并启动容器。
优选策略
LeastRequestedPriority
优先从备选节点列表中选择资源消耗最小的节点(CPU+内存)。CalculateNodeLabelPriority
优先选择含有指定Label的节点。BalancedResourceAllocation
优先从备选节点列表中选择各项资源使用率最均衡的节点。
四. node节点运行机制
1. kubelet
在kubernetes集群中,每个Node节点都会启动kubelet进程,用来处理Master节点下发到本节点的任务,管理Pod和其中的容器。kubelet会在API Server上注册节点信息,定期向Master汇报节点资源使用情况,并通过cAdvisor监控容器和节点资源
。
可以把kubelet理解成Server/Agent架构中的agent,kubelet是Node上的pod管家。
启动脚本:
#kubelet cAdvisor 默认在所有接口监听 4194 端口的请求, 以下iptables限制内网访问
ExecStartPost=/sbin/iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -s 172.16.0.0/12 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -s 192.168.0.0/16 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -p tcp --dport 4194 -j DROP
2. kube-proxy
kube-proxy 运行在每个节点上,监听 API Server 中服务对象的变化
,再通过管理 IPtables 来实现网络的转发。
Kube-Proxy 不同的版本可支持三种工作模式
UserSpace
k8s v1.2 后就已经淘汰
IPtables
目前默认方式
IPVS--------建议
需要安装ipvsadm、ipset 工具包和加载 ip_vs 内核模块
启动脚本
cat /etc/systemd/system/kube-proxy.service
[Service]
# 使用 那种工作模式
--proxy-mode=iptables
3. iptables
Kube-Proxy 监听 Kubernetes Master 增加和删除 Service
以及 Endpoint 的消息。
对于每一个 Service,KubeProxy 创建相应的 IPtables 规则,并将发送到 Service Cluster IP 的流量转发到 Service 后端提供服务的 Pod 的相应端口上。
注意: 虽然可以通过 Service 的 Cluster IP 和服务端口访问到后端 Pod 提供的服务,但该 Cluster IP 是Ping 不通的
。 其原因是 Cluster IP 只是 IPtables 中的规则,并不对应到一个任何网络设备。
IPVS 模式的 Cluster IP 是可以 Ping 通
4. IPVS
kubernetes从1.9开始测试支持ipvs(Graduate kube-proxy IPVS mode to beta),https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.9.md#ipvs,
从1.11版本正式支持ipvs(IPVS-based in-cluster load balancing is now GA),https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md#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(不排队调度)等。
五. 将iptables改为IPVS
注意:要改----所有的都必须改
(maste和node节点)
cat /etc/systemd/system/kube-proxy.service
[Service]
# 使用 那种工作模式
--proxy-mode=ipvs
systemctl daemon-reload
systemctl restart kube-proxy
查看生成的规则
ipvsadm -Ln