Kubernetes教程

概述

什么是Kubernetes

Kubernestes简称K8S,是由Google开源的容器引擎编排工具。可以高效、快速实现应用部署、高可用的实现。

k8s架构

k8s架构图可以看出,主要分为两种节点:MasterNode

  • Master:运行kube-apikube-controller-managerkube-scheduleretc等组件实现k8s资源的调度、健康检查等。
  • Node:运行kube-proxykubelet主要实现k8s PodService的生命周期管理。

image-20250207171719612

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来管理容器。
  • Nodek8s集群中的工作节点,用来管理运行在Node节点上的容器、容器网络等资源。
  • Namespace:用来隔离k8s集群中提供的资源。不同的namespace相互隔离无法访问。
  • ServicePod的网络实现,由kube-proxy组件将服务IP负载均衡到Podendpoints上。
  • Label:识别kubernetes对象资源的标签,以key/value的方式附加到资源对象上。需要配合标签选择器来实现。
  • Label Selector:支持等式(app=nginx)、集合(env inproduction)这两种方式。比如给Node节点设置app=nginx标签,创建Pod的时候使用等式标签选择器,让其调度到app=nginx的节点。
  • Annotations:注解。
  • Replication Controller:简称RCPod副本控制器。通过监控运行中Pod来保证集群中运行指定数量的Pod副本。
  • ReplicaSet:简称RS,和RC的功能一样都是用来实现管理Pod副本。通过管理ReplicaSetDeployment对象来控制副本。这是因为Deployment提供了更高级别的功能,如滚动更新和回滚等,这些功能使得应用部署和管理更加便捷和可靠。
  • Deployment:无状态Pod副本控制器,调用ReplicaSet管理Pod副本。
  • StatefulSet:用来部署有状态服务,比如:数据库、缓存等需要持久化存储数据的中间件或服务。
  • DaemonSet:和Deployment一样都是用来部署Pod,区别在于Deployment只在一个或多个节点部署Pod,而DaemonSetk8s集群每个Node节点部署一个pod
  • ServicePod网络的实现。
  • Jobk8s用来控制批处理型人物的API对象。
  • Volumek8s集群的存储卷和Docker的存储卷类似,不过Docker存储卷作用范围为一个容器,而k8s的存储卷的生命周期和作用范围是一个Pod。每个Pod中声明的存储卷由Pod中的所有容器共享。
  • Persistent Volume Claim:简称PVCPVPVC的关系: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  
kind: CronJob
metadata:
name: hello-cronjob
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- "date; echo Hello from the Kubernetes cluster"
restartPolicy: OnFailure

查看cronjob

$kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello-cronjob */1 * * * * False 1 1s 31s

查看jobs

$kubectl get jobs
NAME COMPLETIONS DURATION AGE
hello-cronjob-28512943 1/1 12s 65s
hello-cronjob-28512944 1/1 5s 5s

DaemonSet

保证每个Node节点上都运行一个Pod副本,通常用来部署一些集群日志、监控或其他应用。

滚动更新

v1.6+支持DaemonSet的滚动更新,可以通过.spec.updateStrategy.type设置更新策略,目前支持两种策略:

  • OnDelete:默认策略,更新模板后,只有手动删除了旧的Pod后才会创建新的Pod。
  • RollingUpdate:更新DaemonSet模板后,自动删除旧的Pod并创建新的Pod。

在使用RollingUpdate策略时,还可以设置:

  • .spec.updateStrategy.rollingUpdate.maxUnavailable,默认1
  • spec.minReadySeconds,默认0

回滚

v1.7+还支持回滚

# 查询历史版本
kubectl rollout history daemonset <daemonset-name>
#查询某个历史版本详细信息
kubectl rollout history daemonset <daemonset-name> --revision=1
#回滚
kubectl rollout undo daemonset <daemonset-name> --to-revision=<revision>
#查询回滚状态
kubectl rollout status ds/<daemonset-name>

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将会平衡已存在的activeReplicaSets和新加入的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内部可以访问的虚拟IP
  • NodePort:在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提供身份的一种机制,可以用来控制PodAPI的访问权限。

ServiceAccount会自动生成一个唯一的tokenPod通过token访问APItoken会随着ServiceAccount的变化而变化。

ServiceAccount可以绑定到Pod上,这样Pod就可以使用绑定的Service Account的权限。

StatefulSet

StatefulSet是用来管理有状态应用的控制器,它可以保证Pod的持久化存储,即Pod中的容器可以访问之前创建的持久化存储。

StatefulSet的特点:

  • 保证每个Pod的名称和主机名是唯一的。
  • 保证Pod的持久化存储。
  • 管理Pod的生命周期,比如重启、删除等。
  • 有序部署和扩展。

k8s访问控制

KubernetesAPI访问提供了三种安全访问控制措施:

  • 认证:认证用户
  • 授权:认证用户权限
  • Admission Control:主要负责资源管理

认证

Kubernetes集群开启TLS时,所有请求都需要先认证。Kubernetes支持多种认证机制,并支持同时开启多个认证插件,只要有一个插件认证通过即可。

如果认证成功,则用户的username会传入授权模块做授权验证。否则返回401错误。

目前Kubernetes支持以下认证插件:

  • X509证书
  • 静态Token文件
  • 引导Token
  • 静态密码文件
  • Service Account
  • OpenID
  • Webhook
  • 认证代理
  • Openstack Keystone密码

RBAC授权

Kubernetes1.6开始支持基于角色的访问控制机制(Role-Based AccessRBAC),集群管理员可以对用户或服务账号的角色进行更精确的资源访问控制。

RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。

Role与ClusterRole

Role是一系列权限的集合,只能给某个指定的namespace的资源做鉴权。对于多namespace和集群级的资源或是非资源类的API(如:/healthz)使用ClusterRole

Role示例:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] #"" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]

ClusterRole示例:

# ClusterRole 示例
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]

RoleBinding和ClusterRoleBinding

RoleBinding:把Role的权限映射到用户或用户组,从而让这些用户继承角色在namespace中的权限。

ClusterRoleBinding:让用户继承ClusterRole在这个集群中的权限。

RoleBinding引用Role示例:

# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

RoleBinding引用ClusterRole示例:

# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-secrets
namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
文章作者: 慕容峻才
文章链接: https://www.acaiblog.top/Kubernetes教程/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 阿才的博客
微信打赏
支付宝打赏