kubernetes基础知识笔记--All In One

k8s组件

  • kubelet
    • 直接跟容器引擎交互,实现容器的生命周期管理
  • kubeproxy
    • 负责写入规则至IPTABLES、IPVS实现服务映射访问
  • scheduler
    • 负责接受任务,选择合适的节点进行分配任务
  • etcd
    • 键值对数据库,存储k8s集群所有重要信息(持久化)
    • 需要关注备份还原问题
    • raft(存储读写信息)
    • wal(预写日志)
    • snapshot(完整备份)
    • store(本地持久化)
  • apiserver
    • 所有服务的统一访问入口,压力大
  • controller manager
    • 维持副本期望数目
  • coredns
    • 为集群中的svc创建一个域名-IP的对应关系解析
  • dashboard
    • 给k8s集群提供一个B/S结构访问体系
  • Ingress Controller
    • 官方只能实现四层代理, ingress 可以实现七层代理
  • federation
    • 提供跨集群中心多k8s统一管理功能
  • prometheus
    • 提供k8s集群的监控能力
  • ELK
    • 提供k8s集群日志统一分析接入平台

scheduler → apiserver → etcd

replication controller → apiserver → etcd

kubectl → apiserver

web UI → apiserver

etcd v3(推荐使用)

Pod(最小单元)

  • 自主式Pod
    • 需要手动管理。
    • Pod退出后,不会自动被重新创建。
  • 控制器管理的Pod
    • 在控制器的生命周期里,始终要维持Pod的副本数量。

Pause

只要有Pod,必会启动Pause。

Pod内容器会共用Pause的网络栈、存储卷。

Pod内的不同容器要预防端口冲突。

控制器

需要掌握各种类型控制器的原理、特点及使用定义方式。

能够根据要求把Pod定义到想要的节点。

  • ReplicationController & ReplicaSet & Deployment

    • 为无状态服务而设计

    • ReplicationController(RC):

      • 用来确保容器应用的副本数始终保持在用户定义的副本数。
      • 如果有容器异常退出,会自动创建新的Pod来替代。
      • 如果异常多出来的容器也会自动回收。
      • 在新版本的kubernetes中建议使用ReplicaSet来取代ReplicationController。
    • ReplicaSet(RS):

      • 跟ReplicationController没有本质的不同,只是名字不同。
      • 支持集合式的selector。
    • Deployment:

      • 不负责Pod创建
        • DeploymentRSPod
        • (滚动更新)DeploymentRS-2Pod(v2)
      • 一般建议使用Deployment来自动管理ReplicaSet,可避免跟其他机制不兼容的问题(例如ReplicaSet不支持rolling-update但Deployment支持)
      • 为Pod和RS提供一个声明式定义(declarative)方法。
      • 滚动升级和回滚应用。
      • 可扩缩容。
      • 支持暂停和继续。
      • 可以保证在升级时,只有一定数量的Pod是down的。
        • 默认情况下,它会确保至少有比期望的Pod数量少25%是UP状态。
      • 也可以保证只创建出超过期望一定数量的Pod。
        • 默认情况下,它会确保最多比期望的Pod数量多25%是UP状态。
      • 当副本还在在创建时,对Deployment执行了更新操作,当前还在创建中的旧版本副本会被立即杀死。
      • 扩容
        • kubectl scale deployment xxxxx --replicas=xx
      • 在HPA支持的情况下,设置自动扩容
        • kubectl autoscale deployment xxxxx --min=xx --max=xx --cpu-percent=xx
      • 更新镜像
        • kubectl set image deployment/xxxxx containerName=imageLabel
      • 回滚 rollout
        • 回滚到上一版本 kubectl rollout undo deployment/xxxxx
        • rollout status 回退状态
        • rollout history 回退历史
        • rollout undo --to-revision=2 指定回退版本
        • rollout pause 暂停Deployment的更新
      • 通过设置 .spec.revisonHistoryLimit 来指定deployment最多保留多少revision历史记录。默认会保留所有。如果设置为0,则Deployment禁止回退。
  • HPA(Horizontal Pod Autoscaling)

    • 是独立对象,基于RS定义
    • 仅适用于Deployment和ReplicaSet
    • v1版本中仅支持根据Pod的CPU利用率扩缩容
    • v1alpha版本中,新增支持根据内存和用户自定义的metric扩缩容
  • DaemonSet

    • 确保全部或者一些Node上运行一个Pod的副本(有且只有一个):
      • 当有新Node加入集群时,也会新增一个Pod。
      • 当有Node从集群中移除时,这些Pod也会被回收。
      • 删除DaemonSet将会删除它创建的所有Pod。
    • 典型用法:
      • 运行集群存储daemon,例如在每个Node上运行glusted、ceph。
      • 在每个Node上运行日志收集daemon,例如fluentd、logstash。
      • 在每个Node上运行监控daemon,例如Prometheus Node Exporter。
  • Job

    • 负责批处理任务:
      • 仅执行一次的任务。
      • 保证批处理任务的一个或多个Pod成功结束。
    • RestartPolicy 仅支持Never或OnFailure。
    • 单个Pod时,默认Pod成功运行后Job即结束。
    • .spec.completions 标志Job结束需要成功运行的Pod个数,默认为 1 。
    • .spec.parallelism 标志并行运行的Pod的个数,默认为 1 。
    • .spec.activeDeadlineSeconds 标志失败Pod的重试最大时间,超过这个时间不会继续重试。
  • CronJob

    • 负责基于时间的周期性Job:
      • 在给定时间点只运行一次。
      • 周期性地在给定时间点运行,例如:数据库备份、发送邮件 。
    • RestartPolicy 仅支持Never或OnFailure。
    • 单个Pod时,默认Pod成功运行后Job即结束。
    • .spec.completions 标志Job结束需要成功运行的Pod个数,默认为 1 。
    • .spec.parallelism 标志并行运行的Pod的个数,默认为 1 。
    • .spec.activeDeadlineSeconds 标志失败Pod的重试最大时间,超过这个时间不会继续重试。
    • .spec.schedule(必需) 调度,指定任务运行周期,格式同Cron。
    • .spec.jobTemplate(必须) Job模板,指定需要运行的任务,格式同Job。
    • .spec.startingDeadlineSeconds(可选) 启动Job的期限(秒级别),不指定,则默认没有期限。如果因为任何原因而错过了被调度的时间,那么错过执行时间的Job将被认为是失败的。
    • .spec.concurrencyPolicy(可选) 并发策略,指定如何处理被CronJob创建的Job的并发执行。
      • Allow (默认),允许并发运行Job。
      • Forbid 禁止,如果前一个还没有完成,则直接跳过。
      • Replace 取消当前正在运行的Job,用一个新的来替换。
    • .spec.suspend(可选) 挂起, 对已开始执行的Job不起作用。
      • true ,后续所有执行都会被挂起。
      • false (默认),
    • .spec.successfulJobsHistoryLimit .spec.failedJobsHistoryLimit(可选) 历史限制,指定可以保留多少完成和失败的Job。默认:3(成功)和1(失败)。
    • 删除cronJob时,不会自动删除job,需要手动删除kubectl delete job
  • StatefulSet

    • 解决有状态服务的问题。
    • 稳定的持久化存储。
      • Pod重新调度后,依旧能访问到相同的持久化数据,基于PVC实现。
    • 稳定的网络标志。
      • Pod重新调度后,其PodName和Hostname不变,基于Headless Service(没有Cluster IP的Service)实现。
    • 有序部署、有序扩展。
      • Pod是有顺序的,在部署或拓展的时候要依据定义的顺序依次进行(从0到N-1,在下一个Pod运行之前,所以在这之前的Pod都必须是Running和Ready状态),基于init containers实现。
    • 有序收缩、有序删除。
    • 匹配Pod Name(网络标识)的模式为:$(statefulSet_name)-序号。
    • 为每个Pod副本创建了一个DNS域名,$(podname).(headlessSVCName),服务间是通过Pod域名来通信,而非Pod IP。
      • 容器重建后,名称不变,但IP可能漂移。
    • statefulSet使用headlessService来控制Pod域名,(servicename).(namespace).svc.cluster.local。
    • 根据volumeClaimTemplates,为每个Pod创建一个pvc。
      • pvc命名规则: (volumeClaimTemplates.name)-(podname)

phase值

  • 挂起(Pending)
    • Pod已被kubernetes接收,但有一个或多个容器未被创建。
    • 等待时间包括调度Pod的时间和通过网络下载镜像的时间。
  • 运行中(Running)
    • 该Pod已绑定到一个节点上,Pod中所有的容器都已被创建。
    • 至少有一个容器正在运行,或者正处于启动或重启状态。
  • 成功(Succeeded)
    • Pod中的所有容器都被成功终止,并且不会再重启。
  • 失败(Failed)
    • Pod中的所有容器都已终止,并且至少有一个容器是因为失败终止。
  • 未知(Unknown)
    • 因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败。

应用类型

  • 应用分类
    • 有状态应用
      • 需要实时数据更新和存储,抽离出集群再放回就无法正常工作。
      • DBMS(MySQL、MongoDB)
    • 无状态应用
      • 没有对应的存储需要实时保留。
      • LVS、APACHE

生命周期

kubectl → api → kubelet → cri → 容器初始化 → Pause(网络、存储资源共享) → Init C(零或多个) → Main C(启动和终止时都可执行命令) → 在Main C启动多少秒后,可启动Readiness、Liveness探测

Init Container

  • 先于应用容器启动。
  • 可能有一个或多个。
  • 总是运行到成功完成为止。
  • 每个init c 都必须在下一个init c 启动之前完成。
  • init c如果失败,kubernetes 会不断地重启Pod,直到init c 成功为止。如果restartPolicy设定为Never,则不会重启。
  • 如果Pod重启,所有init c 必须重新执行。
  • 对init c "spec" 字段的修改被限制在"container image"字段,修改其他字段不会生效,修改"image"后,会重启该Pod。
  • init c 具有应用容器的所有字段,除了"readinessProbe"。
  • 在pod中的每个app和init c 的名称必须唯一。
  • 具有与应用程序容器分离的单独镜像,所以init c 的启动相关代码具备一定优势:
    • 可以包含并运行实用工具,为应用容器提前做好初始化工作,优化应用容器镜像的冗余。
    • 可以包含使用工具和定制化代码来安装,但不能出现在应用程序镜像中。
    • 应用程序镜像可以分离出创建和部署的角色,没有必要联合它们构建一个单独的镜像。
    • 使用linux namespace,具备访问不同文件系统视图的权限,也具备访问secret的权限,而应用容器则不具备权限。
    • 必须在应用容器启动前运行完成,应用容器是并行运行的,故,init c能够提供一种简单的阻塞或延迟应用启动的方法。

探针

探针是由kubelet对容器执行的定期诊断。

要执行诊断,kubelet 调用由容器实现的Handler。

有三类处理程序:

  • ExecAction
    • 在容器内执行指定命令,如果命令退出时返回码为0,则认为诊断成功。
  • TCPAction
    • 对指定端口上的容器的IP地址进行TCP检查探测,如果端口访问成功,则认为诊断成功。
  • HTTPGetAction
    • 对指定的端口和路径上的容器的IP地址执行HTTP Get请求,如果响应的状态码大于等于200,小于400,则认为诊断成功。

探测有如下三种结果:

  • 成功,容器通过诊断。
  • 失败,容器未通过诊断。
  • 未知,诊断失败,不会采取任何行动。

探测方式:

  • readiness 就绪检测,判断容器是否准备好服务请求。

    • 如果就绪检测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。
    • 初始延迟之前的就绪状态默认为Failure,如果容器不提供就绪指针,则默认状态为Success。
  • liveness 存活检测,判断容器是否在运行。

    • 如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略影响。
    • 如果容器不提供存活探针,则默认状态为success。

资源限制

Kubernetes 通过 cgroup 来对资源进行限制。

cgroup 是容器的一组用来控制内核如何运行进程的相关属性集合。针对内存、CPU 和各种设备都有对应的。

默认情况下,Pod 运行没有 CPU 和内存的限额。 这意味着系统中的任何 Pod 将能够像执行该 Pod 所在的节点-样, 消耗足够多的 CPU 和内存。

一般会针对某些应用的 pod 资源进行资源限制,这个资源限制是通过resources 的requests 和limits 来实现。

网络

网络通讯方式

kubernetes的网络模型,所有Pod都在一个可以直接连通的扁平的网络空间中,这在GCE(Google Compute Engine)里面是现成的网络模型,kubernetes假定这个网络已存在。

在私有云里搭建kubernetes集群则不能假定这个网络已存在,维护人员需要自行实现这个网络假设,将不同节点上的容器之间的互相访问先打通。

  • Pod:

    • 同一个Pod内的多个容器之间: lo
      • 共用pause的网络
    • 各Pod之间的通讯: Overlay Network
    • Pod与Service之间: 各节点的IPTABLES规则
  • Flannel

    • 让集群中的不同节点主机创建的容器都具有全集群唯一的虚拟IP地址。
    • 在这些IP地址之间建立一个覆盖网络(Overlay Network)。
    • 通过覆盖网络,将数据包原封不动地传递到目标容器内。
    • 基于UDP传输。
    • Fanneld 封装/解封 数据包。
    • etcd 存储fannel可分配的IP段资源。
    • etcd 中维护 node及对应容器网段信息,建立路由表。

资源清单

在kubernetes中,一般使用yaml格式的文件来创建符合我们预期期望的pod,这样的yaml文件我们一般称为资源清单。

kubernetes中的资源

kubernetes中所有内容都抽象为资源,资源实例化后,成为对象。

  • 命名空间级别
    • 工作负载型资源
      • Pod
      • ReplicaSet
      • Deployment
      • StatefulSet
      • DaemonSet
      • Job
      • CronJob
    • 服务发现及负载均衡型资源
      • Service
      • Ingress
    • 配置与存储型资源
      • Volum(存储卷)
      • CSI(容器存储接口,可以扩展各种各样的第三方存储卷)
    • 特殊类型的存储卷
      • ConfigMap(当配置中心来使用的资源类型)
      • Secret(保存敏感数据)
      • DownwardAPI(把外部环境中的信息输出给容器)
  • 集群级别
    • NameSpace
    • Role
    • Node
    • ClusterRole
    • RoleBinding
    • ClusterRoleBinding
  • 元数据型
    • HPA(通过指标进行操作)
    • PodTemplate
    • LimitRange

常用字段

可以使用kubectl explain xxx命令查看对象详细字段信息及使用。

  • 必须存在的属性
    参数名 字段类型 说明
    version String 指kubernetes API的版本,目前基本上是v1,可以用kubectl api-versions 命令查询
    kind String 指yaml文件定义的资源类型和角色,例如:Pod
    metadata Object 元数据对象,固定值就写metadata
    metadata.name String 元数据对象的名称,例如:Pod的名称
    metadata.namespace String 元数据对象的命名空间,例如:kube-system
    Spec Object 详细定义对象,固定值
    spec.containers[] List Spec对象的容器列表定义
    spec.containers[].name String 容器的名称
    spec.containers[].image String 容器所使用的镜像的名称
  • 重要对象
    参数名 字段类型 说明
    spec.containers[].imagePullPolicy String 定义镜像的拉取策略,有 Always(默认)/Never/IfNotPresent 三个值可选, Always(每次都尝试重新拉取镜像), Never(仅适用本地镜像), IfNotPresent(如果本地有镜像就使用本地镜像,没有就拉取在线镜像。)
    spec.containers[].command[] List 指定容器启动命令,可以指定多个,不指定则使用镜像打包时使用的启动命令
    spec.containers[].args[] List 指定容器启动命令参数,可指定多个
    spec.containers[].workingDir String 指定容器的工作目录
    spec.containers[].volumeMounts[] List 指定容器内部的存储卷配置
    spec.containers[].volumeMounts[].name String 指定可以被容器挂载的存储卷的名称
    spec.containers[].volumeMounts[].mountPath String 指定可以被容器挂载的存储卷的路径
    spec.containers[].volumeMounts[].readOnly String 设置存储卷路径的读写模式,ture或false,默认为读写模式
    spec.containers[].ports[] List 指定容器需要用到的端口列表
    spec.containers[].ports[].name String 指定端口名称
    spec.containers[].ports[].containerPort String 指定容器需要监听的端口号
    spec.containers[].ports[].hostPort String 指定容器所在主机需要监听的端口号,默认跟上面containerPort相同。设置了hostPort的条件下,同一台主机无法启动该容器的相同副本,因为端口冲突。
    spec.containers[].ports[].protocol String 指定端口协议,支持TCP和UDP,默认值为TCP
    spec.containers[].env[] List 指定容器运行前需设置的环境变量列表
    spec.containers[].env[].name String 指定环境变量名称
    spec.containers[].env[].value String 指定环境变量值
    spec.containers[].resources Object 指定资源限制和资源请求的值
    spec.containers[].resources.limits Object 指定容器运行时资源的上限
    spec.containers[].resources.limits.cpu String 指定CPU的限制,单位为core数,将用于docker run --cpu-shares参数
    spec.containers[].resources.limits.memory String 指定MEM内存的限制,单位为MiB、GiB
    spec.containers[].resources.requests Object 指定容器启动和调度时的限制设置
    spec.containers[].resources.requests.cpu String CPU请求,单位为core数,容器启动的初始化可用量
    spec.containers[].resources.requests.memory String 内存请求,单位为MiB、GiB,容器启动的初始化可用量
  • 额外的参数项
    参数名 字段类型 说明
    spec.restartPolicy String 定义Pod的重启策略,可选值为Always(默认)/OnFailure/Never。 Always(Pod一旦终止运行,无论容器是如何终止的,kubelet服务都将重启它), OnFailure(只有Pod以非零退出码终止时,kubelet才会重启该容器,如果容器正常退出,即退出码为0,则kubelet不会重启它), Never(Pod终止后,kubelet将退出码报告给master,不会重启该容器)。
    spec.nodeSelector Object 定义Node的Label过滤标签,以key:value格式指定
    spec.imagePullSecrets Object 定义pull镜像时使用secret的名称,以name:secretkey格式指定
    spec.hostNetwork Boolean 定义是否使用主机网络模式,默认值为false。设置true表示使用宿主机网络,不使用网桥,同时设置了true将无法在同一台宿主机启动第二个副本。

服务

需要掌握svc原理及其构建方式

Service

  • apiServer → kube-proxy
  • Client → iptables(ipvs) → kube-proxy → Pod
  • 通过 labelSelector 命中后端的一个或多个具备指定标签的Pod。
  • 只提供4层负载均衡能力。
  • 后端访问机制: 轮询。
  • 类型:
    • ClusterIP: 默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP。
    • NodePort: 在ClusterIP基础上,为Service在每台机器上绑定一个端口,可以通过 {NodeIP}:{NodePort} 来访问服务。
    • LoadBalancer: 在NodePort基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到 {NodeIP}:{NodePort} 。
    • ExternalName: 把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建。

Headless Service

没有负载均衡及单独的Service IP。

可以通过指定.spec.clusterIP 为"None" 来创建Headless Service。

kube-proxy不会处理这类Service。

网络代理

kubernetes 集群中,每个Node运行一个 kube-proxy 进程。

kube-proxy 负责为 Service 实现了一种VIP(虚拟IP)的网络形式。

kubernetes 1.14 版本之后,默认使用ipvs进行网络代理。

代理模式

  • Linux
    • IPTABLES
    • IPVS
    • nftables
  • Windows
    • kernelspace

ClusterIP

clusterIP主要在每个node节点使用IPTABLES(IPVS), 将发向clusterIP对应端口的数据, 转发到kube-proxy中。

kube-proxy内部实现负载均衡。

kube-proxy可以查询到service下对应pod的地址和端口,将数据转发给对应的Pod的地址:端口。

三个主要组件:

  • apiserver: 用户通过 kubectl 命令向 apiserver 发送创建 service 的命令, apiserver 接收到请求后将数据存储到 etcd 中。

  • kube-proxy: kubernetes 的每个节点中都有一个叫做 kube-porxy 的进程,这个进程负责感知 service 、 pod 的变化, 并将变化的信息写入本地的 iptables 规则中。

  • iptables: 使用 NAT 等技术将 virtualIP 的流量转至 endpoint 中。

Ingress

提供从集群外部到集群内服务的 HTTP 和 HTTPS 路由。

Ingress 可为 Service 提供外部可访问的 URL、对其流量作负载均衡、 终止 SSL/TLS,以及基于名称的虚拟托管等能力。

Ingress 控制器 负责完成 Ingress 的工作,具体实现上通常会使用某个负载均衡器, 不过也可以配置边缘路由器或其他前端来帮助处理流量。

Ingress 不会随意公开端口或协议。

将 HTTP 和 HTTPS 以外的服务开放到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。

存储

掌握多种存储类型的特点

并且能够在不同环境中选择合适的存储方案(需要形成独立见解)

  • ConfigMap
    • 可用来存储单个属性,也可以存储整个配置文件或Json二进制对象。
    • 为容器提供注入配置信息的机制。
  • Secret
  • volume
  • Persistent volume

ConfigMap

  • 创建
    • 使用目录创建。--from-file
      kubectl create configmap game-ui-config --from-file=configMap/
      kubectl describe configmap game-ui-config
      kubectl get configmap game-ui-config -o yaml
      
    • 使用文件创建。只要指定为一个文件就可以从单个文件中创建ConfigMap。from-file
      kubectl create configmap game-config --from-file=configMap/game.properties
      
    • 使用字面值创建。利用-from-literal参数传递配置信息,该参数可以使用多次。
      kubectl create configmap test-config --from-literal=test.number=123456 --from-literal=test.name=cmTest
      
  • 可用于Pod环境变量。
  • 可用于设置命令行参数。
  • 数据卷插件也可使用。
  • 热更新。
    • kubectl edit configmap xxxxx
    • 更新后,并不会触发相关Pod的滚动更新,可以通过修改Pod Annotations强制触发滚动更新。
    • 更新后,使用该 ConfigMap 挂载的 Env 不会同步更新。
    • 更新后,使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。

Secret

解决了密码、token、密钥等敏感数据的配置问题。

不需要吧这些敏感数据暴露到镜像或者Pod Spec中。

Secret 可以以Volume 或者环境变量的方式使用。

三种类型:

  • Service Account
    • 用来访问 Kubernetes APl,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的/run/secrets/kubernetes.io/serviceaccount目录中。
  • Opaque
    • base64编码格式的 Secret,用来存储密码、密钥等。
    • 可用于volume挂载。
    • 可用于环境变量。
  • kubernetes.io/dockerconfigjson
    • 用来存储私有 docker registry 的认证信息。
    • kubectl create secret docker-registry myregistrykey --docker-server=xxxxx --docker-username=xxxxx --docker-password=xxxxx --docker-email=xxxxx

Volume

数据持久化保存。

数据共享。

  • emptyDir
    • 最初为空。
    • Pod中容器可以读取和写入。
    • 只要相应Pod在该节点上运行,该卷就会存在。
    • 容器崩溃不会导致数据丢失。
    • Pod删除则 emptyDir 中的数据永久删除。
    • 用法:
      • 暂存空间。例如用于基于磁盘的合并排序。
      • 用作长时间计算崩溃恢复时的检查点。
      • web服务器容器提供数据时,保存内容管理器容器提取的文件。
  • hostPath
    • 将主机节点的文件系统中的文件或目录挂载到集群中。

    • 用途:

      • 运行一个需要访问节点级系统组件的容器(例如负责收集日志的容器,可以以只读方式挂载 /var/log)。
      • 让存储在主机系统上的配置文件可以被静态Pod以只读方式访问(静态Pod无法访问ConfigMap)。
    • 类型:

      行为
      "" 空字符串(默认)用于向后兼容,这意味着在安hostPath 卷之前不会执行任何检查。
      DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
      Directory 在给定路径上必须存在的目录。
      FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
      File 在给定路径上必须存在的文件。
      Socket 在给定路径上必须存在的 UNIX 套接字。
      CharDevice (仅 Linux 节点) 在给定路径上必须存在的字符设备。
      BlockDevice (仅 Linux 节点) 在给定路径上必须存在的块设备。
    • 注意点:

      • 每个节点上的文件不同,具有相同配置的Pod可能在不同Node上上表现出不同效果。
      • 当kubernetes按照计划添加资源感知调度时,将无法考虑hostPash使用的资源。因为是Node节点自身的文件系统,并不是隶属于集群调度。
      • 在底层主机上出创建的文件或目录只能由Root写入。
  • PV
    • PV(PersistentVolume)
      • 是由管理员设置的存储,是集群的一部分。
      • 是独立的资源,具备独立的生命周期。
    • PVC(PersistentVolumeClaim)
      • 是用户存储的请求。
      • PVC消耗PV资源。
      • 可以请求指定大小和访问方式的存储资源。
    • 静态PV
      • 集群管理员创建的一些PV。
      • 带有可供集群用户使用的实际存储的细节。
      • 可用于消费。
    • 动态PV
      • 当静态PV不匹配PVC时,集群会尝试动态地为PVC创建卷(新PV资源)。
      • 此配置基于StorageClasses。
      • 要启用基于存储级别的动态存储配置,集群管理员需要启用API Server上的DefaultStorageClass[准入控制器]。
    • 绑定
      • master中的控制器监视新的PVC,寻找匹配的PV,并将他们绑定。
      • PVC和PV之间的绑定是一对一映射。
      • 如果新 PVC 触发动态调配 PV,Kubernetes 会为该 PVC 创建一个新的 PV,但不会为现有的 PVC 更换已经绑定的 PV。
    • 保护使用中的存储对象
      • 确保仍被 Pod 使用的 PVC 对象及其所绑定的 PV 对象在系统中不会被删除,因为这样做可能会引起数据丢失。
      • 如果用户删除被某 Pod 使用的 PVC 对象,该 PVC 申领不会被立即移除。 PVC 对象的移除会被推迟,直至其不再被任何 Pod 使用。 此外,如果管理员删除已绑定到某 PVC 申领的 PV 卷,该 PV 卷也不会被立即移除。 PV 对象的移除也要推迟到该 PV 不再绑定到 PVC。
    • 访问模式
      • ReadWriteOnce(RWO)
        • 可以被单个节点以 读/写 模式挂载
      • ReadOnlyMany(ROX)
        • 可以被多个节点以 只读 模式挂载
      • ReadWriteMany(RWX)
        • 可以被多个节点以 读/写 模式挂载
      • 一个卷一次只能使用一种访问模式挂载,即使它支持很多访问模式。
    • 回收策略
      • Retain(保留) 手动回收
      • Recycle(回收,已废弃) 基本擦除
      • Delete(删除) 关联的资产也将被删除
    • 状态
      • Available(可用) 一块空闲资源还没有被任何声明绑定。
      • Bound(已绑定) 已被绑定。
      • Released(已释放) PVC已被删除,但PV资源未被集群重新声明。
      • Failed(失败) 自动回收失败。
    • 删除Pod不会删除其pvc,手动删除pvc将自动释放pv。

集群调度

节点亲和性

pod.spec.nodeAffinity

  • preferredDuringSchedulingIgnoredDuringExecution 软策略
  • requiredDuringSchedulingIgnoredDuringExecution 硬策略
  • 如果二者结合使用,要先满足硬策略再满足软策略。
  • operator:
    • In label的值在某个列表中
    • NotIn label的值不在某个列表中
    • Gt label的值大于某值
    • Lt label的值小于某值
    • Exists 某个label存在
    • DoesNotExist 某个label不存在

Pod亲和性

pod.spec.affinity.podAffinity(亲和)/podAntiAffinity(反亲和)

  • preferredDuringSchedulingIgnoredDuringExecution 软策略
  • requiredDuringSchedulingIgnoredDuringExecution 硬策略
  • operator:
    • In
    • NotIn
    • Exists
    • DoesNotExist
  • topologyKey 拓扑

Taint(污点) 和 Toleration(容忍)

使节点能够排斥一类特定的Pod。

Taint和Toleration相互配合,可以避免Pod被分配到不适合的Node。

每个节点上都可以应用一个或多个Taint,表示对于那些不能容忍这些Taint的Pod,是不会被该节点接受的。

如果将Toleration应用于Pod,则这些Pod可以(但不一定)被调度到具有匹配Taint的节点上。

Taint(污点)

  • 组成
    • kubectl taint 可以给Node设置污点。
      • 设置污点: kubectl taint nodes node1 key1=value1:NoSchedule
      • 去除污点: kubectl taint nodes node1 key1:NoSchedule-
    • Node被设置上污点后,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。
    • 公式: key=value:effect
      • "key=value" → 标签,vaule可以为空。
      • "effect" → 描述作用。
        • NoSchedule :表示kubernetes将不会把Pod调度到具有该污点的Node上。
        • PreferNoSchedule :表示kubernetes将尽量避免把Pod调度到具有该污点的Node上。
        • NoExecute :表示kubernetes将不会把Pod调度到具有该污点的Node上,同时会将Node上已存在的Pod驱逐出去。

Toleration(容忍)

  • key、vaule、effect 要与对应的taint保持一致。
  • operator
    • 默认为Equal, 与vaule相等。
    • 值为Exists将会忽略value值。
    • 如果 key 为空,那么 operator 必须是 Exists,匹配所有 key 和 value。同时 effect 仍然需要匹配。
  • tolerationSeconds用于描述当Pod需要被驱逐时,可以在Pod上继续保留运行的时间。
  • 当不指定key时,表示容忍所有的污点key。
  • 当不指定effect值时,表示容忍所有的污点作用。
  • 有多个master时,为防止资源浪费,可以这样做:
    • kubectl taint nodes Node-name node-role.kubernetes.io/master=:PreferNoSchedule

指定节点调度

  • Pod.sec.nodeNAme将Pod直接调度到指定的节点上。
    • 会跳过Scheduler的调度策略。
    • 该匹配规则是强制匹配。
  • Pod.sec.nodeSelector
    • 通过kubernetes的label-selector机制选择节点,由调度器调度策略匹配label,而后调度Pod到目标节点。
    • 该匹配规则属于强制约束。

Scheduler

Scheduler

  • kubernetes 的调度器。将定义的Pod分配到集群的节点上。
  • 作为单独程序运行。
  • 会一直监听API Server,获取"spec.nodeName"为空的Pod,对每个Pod都会创建一个binding,表明该Pod应该放到哪个节点。
  • 目标:
    • 公平
      • 如何保证每个节点都能被分配资源。
    • 资源高效利用
      • 集群所有资源最大化被使用。
    • 效率
      • 调度的性能要好,能够尽快地对打匹配的Pod完成调度工作。
    • 灵活
      • 允许用户根据自己的需求控制调度的逻辑。

调度过程

  • 首先,过滤掉不满足条件的节点,这个过程称为"predicate"。
    • 如果过程中没有找到合适节点,pod会一直处于"pending"状态,不断重试调度,直到有节点满足条件。
    • predicate 支持如下算法:
      • PodFitsResources: 节点上剩余的资源是否大于 pod 请求的资源。
      • PodFitsHost: 如果 pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配。
      • PodFitsHostPorts: 节点上已经使用的 port 是否和 pod 申请的 port 冲突。
      • PodselectorMatches: 过滤掉和 pod 指定的 label 不匹配的节点。
      • NoDiskConflict: 已经 mount的 volume 和 pod 指定的 volume 不冲突,除非它们都是只读。
  • 其次,对通过的节点按照优先级排序,这个过程称为"priority"。
    • 优先级选项:
      • LeastRequestedPriority: 通过计算 CPU和 Memory 的使用率来决定权重,使用率越低权重越高。换句话
        说,这个优先级指标倾向于资源使用比例更低的节点。
      • BalancedResourceAllocation: 节点上 CPU和 Memory 使用率越接近,权重越高。这个应该和上面的一起使用,不应该单独使用。
      • ImagelocalityPriority: 倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高
  • 最后,从中选择优先级最高的节点。
  • 如果任一步骤出现错误,则直接返回错误。

安全

集群的认证

  • HTTP Token
    • 是用一个很长的特殊编码方式的并且难以被模仿的字符串来表达客户的一种方式。
    • 每一个Token对应一个用户名存储在API Server能访问的文件中。
    • 当客户端法器API调用请求时,需要在HTTP Header中放入Token。
  • HTTP Base
    • 通过 用户名+密码 的方式认证。
    • 用BASE64算法进行编码加密。
    • 编码后的字符串放在HTTP Request中的Heather Authorization域,发送给服务器。服务器收到后进行解码,获取用户名及密码。
  • HTTPS 证书认证
    • 基于CA根证书签名的客户端身份认证方式。

安全性说明:

  • Controller Manager、Scheduler、API Server 三者在同一台机器,所以直接使用API Server的非安全端口访问。
    • insecure-bind-address=127.0.0.1
  • kubectl、kubelet、kube-proxy访问API Server 都需要证书进行HTTPS双向认证。

证书颁发:

  • 手动签发, 通过k8s集群跟ca进行签发HTTPS证书。
  • 自动签发, kubelet首次访问API Server时,使用token做认证,通过后,Controller Manager会为kubelet生成一个证书,后续访问都用证书做认证。

kubeconfig

  • 包含集群参数(CA证书、API Server地址)、客户端参数(上面生成的证书和私钥)、集群context 信息(集群名称、用户名)。
  • Kubenetes 组件通过启动时指定不同的 kubeconfig文件可以切换到不同的集群。
  • .kube/config

ServiceAccount

  • 用于Pod中的容器访问API Server。
  • Pod的创建、销毁是动态的,要为它手动生成证书是不可行的。
  • Kubenetes使用了Service Account解决Pod 访问APl Server的认证问题。

Secret和SA

  • Kubernetes 设计了一种资源对象叫做Secret,分为两类:
    • 一种是用于ServiceAccount的service-account-token。
    • 另一种是用于保存用户自定义保密信息的 Opaque。
  • ServiceAccount 中用到包含三个部分:
    • Token
      • 使用 APIServer 私钥签名的JWT。用于访问APlServer时,Server端认证。
    • ca.crt
      • 用于Client端验证APIServer发送的证书。
    • namespace
      • 标识这个service-account-token的作用域名空间。
  • 默认情况下,每个 namespace 都会有一个 ServiceAccount,如果 Pod 在创建时没有指定 ServiceAccount ,就会使用 Pod 所属的namespace的ServiceAccount。默认挂载目录: /run/secrets/kubernetes.io/serviceaccount/

鉴权

认证 只是确认通信的双方都确认了对方是可信的,可以相互通信。

鉴权 则是确定请求方有哪些资源的权限。

APl Server 目前支持以下几种授权策略(通过 APl Server 的启动参数"-authorization-mode"设置)

  • AlwaysDeny: 表示拒绝所有的请求,一般用于测试。
  • AlwaysAllow: 允许接收所有请求,如果集群不需要授权流程,则可以采用该策略。
  • ABAC(Attribute-Based Access control): 基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。
  • Webbook: 通过调用外部 REST 服务对用户进行授权。
  • RBAC(Role-Based Access Control): 基于角色的访问控制,现行默认规则。

RBAC:

  • 对集群中的资源和非资源均拥有完整的覆盖。
  • 整个 RBAC 完全由几个 API 对象完成,同其它 API对象一样,可以用 kubectl 或 API 进行操作。
  • 可以在运行时进行调整,无需重启 API Server。
  • 4个资源对象:
    • Role
      • 表示一组规则权限,权限只会增加,不存在一个资源一开始就有很多权限而通过RBAC对其进行减少权限的操作。
      • Role可以定义在一个namespace中,如果想要跨namespace则可以创建ClusterRole。
    • RoleBinding
      • 可以将角色中定义的权限授予用户或用户组。
      • 包含一组权限列表(subjects),列表中包含有不同形式的待授予权限资源类型(users,groups,service account)。
      • 包含对被绑定的Role的引用。
      • 适用于某个命名空间内授权。
      • 可以引用ClusterRole来对当前namespace内用户、用户组或ServiceAccount进行授权。
    • ClusterRole
      • 具有与Role相同的权限角色控制能力。
      • 是集群级别的。
      • 可用于:
        • 集群级别的资源控制(例如node访问权限)。
        • 非资源型endpoints(例如/healthz访问)。
        • 所有命名空间资源控制(例如pods)。
    • ClusterRoleBinding
      • 适用于集群范围内的授权。

API Server会把客户端证书的cn 字段作为User,把 names.O 字段作为Group。

kubelet 使用 TLS Bootstaping 认证时,API Server 可以使用 Bootstrap Tokens 或者 Tokenauthentication file 验证 token,无论哪一种,Kubenetes 都会为 token 绑定一个默认的 User 和 Group。

Pod使用 ServiceAccount 认证时,service-account-token 中的JWT 会保存 User 信息,再创建一对角色/角色绑定(集群角色/集群角色绑定)资源对象,就可以完成权限绑定了。

准入控制

准入控制器是一段代码,它会在请求通过认证和鉴权之后、对象被持久化之前拦截到达 API 服务器的请求。

Kubernetes 的若干重要功能都要求启用一个准入控制器,以便正确地支持该特性。

因此,没有正确配置准入控制器的 Kubernetes API 服务器是不完整的,它无法支持你所期望的所有特性。

Helm

Linux yum

掌握helm原理

helm模板自定义

helm部署常用插件

高可用

高可用集群副本数最好是 >=3 的奇数个

集群证书

修改kubeadm 达到证书可用期限为10年

posted @   ヾ(o◕∀◕)ノヾ  阅读(14)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示