概述
什么是Kubernetes
Kubernestes
简称K8S
,是由Google
开源的容器引擎编排工具。可以高效、快速实现应用部署、高可用的实现。
k8s架构
从k8s
架构图可以看出,主要分为两种节点:Master
、Node
Master
:运行kube-api
、kube-controller-manager
、kube-scheduler
、etc
等组件实现k8s
资源的调度、健康检查等。Node
:运行kube-proxy
、kubelet
主要实现k8s Pod
、Service
的生命周期管理。
k8s组件
组件名称 | 主要功能 |
---|---|
kube-api-server | 提供集群管理的 REST API 接口,包括认证授权、数据校验以及集群状态变更等。提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd)。 |
kube-controller-manager | 控制资源(如Deployment、ReplicaSet、StatefulSet、DaemonSet、Job、Node等)生命周期。 |
kube-scheduler | 主要负责整个集群资源的调度功能,根据特定的调度算法和策略,将Pod调度到最优的工作节点上面去,从而更加合理、更加充分的利用集群的资源。 |
etcd | 分布式键值存储数据库,保存集群状态数据(如Pod、Service等)。通常部署奇数个实例(如3、5、7个),可与Master节点分离部署。 |
kubelet | 运行在每个Node上的代理,负责Pod和容器的生命周期管理。监听Master下发的任务(如创建/更新/终止Pod),控制容器运行时执行操作。定期向api-server上报节点资源使用情况。 |
kube-proxy | kube-proxy是Kubernetes的一个组件,它是一个网络代理,用于实现Kubernetes集群中Service和Pod之间的网络通信。主要作用是将Kubernetes Service中定义的虚拟IP地址和端口转发到集群中的Pod,以实现服务的访问。 |
container-runtime | 容器运行时环境(如containerd、CRI-O等),负责运行容器。Kubernetes已弃用Docker,推荐使用符合CRI标准的运行时(如containerd)。 |
kubelet
kubelet的作用:
- 节点管理:kubelet启动时会向api-server进行注册,然后会定时的向api-server汇报本节点信息状态,资源使用状态等,这样master就能够知道node节点的资源剩余,节点是否失联等等相关的信息了。
- pod管理:kubelet负责维护node节点上pod的生命周期,当kubelet监听到master的下发到自己节点的任务时,比如要创建、更新、删除一个pod,kubelet 就会通过CRI(容器运行时接口)插件来调用不同的容器运行时来创建、更新、删除容器。
- 容器监控检查:pod中可以定义启动探针、存活探针、就绪探针等3种,我们最常用的就是存活探针、就绪探针,kubelet 会定期调用容器中的探针来检测容器是否存活,是否就绪,如果是存活探针,则会根据探测结果对检查失败的容器进行相应的重启策略。
k8s基本概念
Pod
:是k8s
最小的调度单位,一个Pod
可以包含一个或多个容器。k8s
通过Pod
来管理容器。Node
:k8s
集群中的工作节点,用来管理运行在Node
节点上的容器、容器网络等资源。Namespace
:用来隔离k8s
集群中提供的资源。不同的namespace
相互隔离无法访问。Service
:Pod
的网络实现,由kube-proxy
组件将服务IP
负载均衡到Pod
的endpoints
上。Label
:识别kubernetes
对象资源的标签,以key/value
的方式附加到资源对象上。需要配合标签选择器来实现。Label Selector
:支持等式(app=nginx)
、集合(env inproduction)
这两种方式。比如给Node
节点设置app=nginx
标签,创建Pod
的时候使用等式标签选择器,让其调度到app=nginx
的节点。Annotations
:注解。Replication Controller
:简称RC
,Pod
副本控制器。通过监控运行中Pod
来保证集群中运行指定数量的Pod
副本。ReplicaSet
:简称RS
,和RC
的功能一样都是用来实现管理Pod
副本。通过管理ReplicaSet
的Deployment
对象来控制副本。这是因为Deployment
提供了更高级别的功能,如滚动更新和回滚等,这些功能使得应用部署和管理更加便捷和可靠。Deployment
:无状态Pod
副本控制器,调用ReplicaSet
管理Pod
副本。StatefulSet
:用来部署有状态服务,比如:数据库、缓存等需要持久化存储数据的中间件或服务。DaemonSet
:和Deployment
一样都是用来部署Pod
,区别在于Deployment
只在一个或多个节点部署Pod
,而DaemonSet
在k8s
集群每个Node
节点部署一个pod
。Service
:Pod
网络的实现。Job
:k8s
用来控制批处理型人物的API对象。Volume
:k8s
集群的存储卷和Docker
的存储卷类似,不过Docker
存储卷作用范围为一个容器,而k8s
的存储卷的生命周期和作用范围是一个Pod
。每个Pod
中声明的存储卷由Pod
中的所有容器共享。Persistent Volume Claim
:简称PVC
,PV
和PVC
的关系:PVC
提供配置持久化存储,PV
提供持久化存储。Secret
:用来保存密码、密钥、认证凭证等敏感的对象。Service Account
:为了方便Pod
里面的进程调用Kubernetes API
或其他外部服务而设计的。- RBAC:Role-based Access Control简称RBAC,是k8s集群中基于角色的访问控制。
资源对象
HPA
Horizontal Pod Autoscaling简称HPA,可以根据CPU使用率或应用自定义metrics自动扩展Pod数量。支持replication controller、deployment和replica set。
HPA特点:
- 控制管理器每隔30s查询metrics的资源使用情况,可通过–horizontal-pod-autoscaler-sync-period参数修改。
- 支持三种metrics类型。
- 预定义metrics以利用率的方式计算,如:Pod的CPU。
- 自定义的Pod metrics的方式计算。
- 自定义的object metrics。
- 支持两种metrics查询方式:Heapster和自定义的REST API。
- 支持多种metrics。
CronJob
CronJob 即定时任务,就类似于 Linux 系统的 crontab,在指定的时间周期运行指定的任务。
CronJob Spec
- .spec.schedule:指定任务运行周期,格式同cron
- .spec.jobTemplate:指定需要运行的任务,格式同Job
- .spec.startingDeadlineSeconds:指定任务开始的截止期限
- .spec.concurrencyPolicy:指定任务的并发策略,支持Allow、Forbid和Replace三个选项
使用方式
创建一个cronjob
apiVersion: batch/v1beta1 |
查看cronjob
$kubectl get cronjob |
查看jobs
$kubectl get jobs |
DaemonSet
保证每个Node节点上都运行一个Pod副本,通常用来部署一些集群日志、监控或其他应用。
滚动更新
v1.6+支持DaemonSet的滚动更新,可以通过.spec.updateStrategy.type
设置更新策略,目前支持两种策略:
- OnDelete:默认策略,更新模板后,只有手动删除了旧的Pod后才会创建新的Pod。
- RollingUpdate:更新DaemonSet模板后,自动删除旧的Pod并创建新的Pod。
在使用RollingUpdate策略时,还可以设置:
.spec.updateStrategy.rollingUpdate.maxUnavailable
,默认1spec.minReadySeconds
,默认0
回滚
v1.7+还支持回滚
# 查询历史版本 |
Deployment
deployment是kubernetes中无状态控制器,使用RS为Pod提供声明式部署。
创建deployment
将kubectl的–record的flag设置为true,可以在annotation中记录当前命令创建或升级了该资源。例如查看每个deployment revision中执行了哪些命令
kubectl create -f xxx.yaml --record |
执行以下命令可以看到创建的rs
kubectl get rs |
更新deployment
如果要更新deployment的pod的image,使用以下命令
kubectl set image deployment/<deployment_name> nginx=nginx=1.9.1 |
也可以使用edit命令编辑deployment修改image为1.9.1
kubectl edit deployment/<deployment_name> |
回退deployment
如果想要回退某个deployment,默认情况下kubernetes会在系统中保留所有的deployment的rollout历史记录,方便随时回退。可以修改revision hostory limit
来更改保存的revision
数。
只要deployment的rollout被处罚就会传教概念一个revision。也就是说当deployment的pod template被更新,就会创建一个新的revision。
如果扩容deployment不会创建revision
,当你回退到历史revision
时,只有deployment
中的pod template
才会回退。
deployment历史记录
查看deployment历史记录
kubectl rollout history deployment/nginx-deployment |
查看某个revision的详细记录
kubectl rollout history deployment/nginx-deployment --revision=2 |
回退到历史版本
使用以下命令可以回退到历史记录,使用--to-revision=2
参数指定某个历史记录。
kubectl rollout undo deployment/nginx-deployment --to-revision=2 |
清理Policy
可以通过设置.spec.revisionHistoryLimit
来指定deployment
最多保留多少revision
历史记录。默认会保留所有的revision
,如果设置为0,deployment
不允许回退。
deployment扩容
使用以下命令进行扩容
kubectl scale deployment nginx-deployment --replicas 10 |
如果集群中启用了HPA,可以给deployment设置一个autoscaler,基于当前pod的cpu利用率选择最少和最多的pod数
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80 |
比例扩容deployment
RollingUpdate Deployment
支持同时运行一个应用的多个版本,当你autoscaler
扩容一个正在rollout
中的RollingUpdate Deployment
的时候,为了降低风险Deployment Controller
将会平衡已存在的active
的ReplicaSets
和新加入的replicas
,被称为比例扩容。
暂停或恢复deployment
暂停deployment
kubectl rollout pause deployment/nginx-deployment |
恢复deployment
kubectl rollout resume deploy nginx |
deployment状态
- Progressing:正在创建、扩容、缩容一个
ReplicaSet
。 - Complete:正常的deployment。
- Failed:镜像拉去错误、Pod运行错误、权限不足等。
Ingress
Ingress 是 Kubernetes 中管理外部访问的 API 对象,属于七层转发,将外部请求转发到集群内部的服务(Service)
Resource Quotas
资源配额Resource Quotas
时用来限制用户资源用量的一种机制,应用在Namespace上
,并且每个Namespace
只能有一个ResourceQuota
对象。 开启计算资源配额后创建容器必须配置计算资源请求或限制,用户超额后禁止创建新的资源。
Service
Service
是对一组提供相同功能的·Pods·的抽象,并为他们提供统一的入口。·Service·通过标签来选取服务后端,一般配合Replication Controller
或者Deployment
来保证后端容器的正常运行。
这些匹配的标签的Pod IP
和端口列表组成endpoints
,由kube-proxy
负责将服务IP负载均衡到这些endpoints
上。
Service的四种类型
ClusterIP
:默认类型,子弟哦那个分配一个仅cluster内部可以访问的虚拟IPNodePort
:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过IP+端口访问应用服务。LoadBalancer
:在NodePort
的基础上,借助cloud provider
创建一个外部的负载均衡器,将请求转发到Node IP:NodePort
上ExternalName
:将服务通过DNS CNAME
记录方式转发到指定的域名,需要kube-dns
版本在1.7
以上。
协议
Service、Endpoints、Pod支持三种类型的协议:TCP、UDP、STCP
ServiceAccount
ServiceAccount
是用来给Pod
提供身份的一种机制,可以用来控制Pod
对API
的访问权限。
ServiceAccount
会自动生成一个唯一的token
,Pod
通过token
访问API
,token
会随着ServiceAccount
的变化而变化。
ServiceAccount
可以绑定到Pod
上,这样Pod
就可以使用绑定的Service Account
的权限。
StatefulSet
StatefulSet
是用来管理有状态应用的控制器,它可以保证Pod的持久化存储,即Pod中的容器可以访问之前创建的持久化存储。
StatefulSet
的特点:
- 保证每个
Pod
的名称和主机名是唯一的。 - 保证
Pod
的持久化存储。 - 管理Pod的生命周期,比如重启、删除等。
- 有序部署和扩展。
k8s访问控制
Kubernetes
对API
访问提供了三种安全访问控制措施:
- 认证:认证用户
- 授权:认证用户权限
Admission Control
:主要负责资源管理
认证
Kubernetes
集群开启TLS
时,所有请求都需要先认证。Kubernetes
支持多种认证机制,并支持同时开启多个认证插件,只要有一个插件认证通过即可。
如果认证成功,则用户的username
会传入授权模块做授权验证。否则返回401错误。
目前Kubernetes
支持以下认证插件:
X509
证书- 静态
Token
文件 - 引导
Token
- 静态密码文件
Service Account
OpenID
Webhook
- 认证代理
Openstack Keystone
密码
RBAC授权
Kubernetes
从1.6
开始支持基于角色的访问控制机制(Role-Based Access
,RBAC
),集群管理员可以对用户或服务账号的角色进行更精确的资源访问控制。
在RBAC
中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。
Role与ClusterRole
Role
是一系列权限的集合,只能给某个指定的namespace
的资源做鉴权。对于多namespace
和集群级的资源或是非资源类的API
(如:/healthz
)使用ClusterRole
。
Role示例:
kind: Role |
ClusterRole示例:
# ClusterRole 示例 |
RoleBinding和ClusterRoleBinding
RoleBinding
:把Role
的权限映射到用户或用户组,从而让这些用户继承角色在namespace
中的权限。
ClusterRoleBinding
:让用户继承ClusterRole
在这个集群中的权限。
RoleBinding
引用Role
示例:
# This role binding allows "jane" to read pods in the "default" namespace. |
RoleBinding
引用ClusterRole
示例:
# This role binding allows "dave" to read secrets in the "development" namespace. |