【Kubernetes系列】第2篇 基础概念介绍


1 Pod - 实例

Pod是一组紧密关联的容器集合,支持多个容器在一个Pod中共享网络和文件系统,能够经过进程间通讯和文件共享这种简单高效的方式完成服务,是Kubernetes调度的基本单位。Pod的设计理念是 每一个Pod都有一个惟一的IPphp


Pod具备以下特征:node

  • 包含多个共享IPC、Network和UTC namespace的容器,可直接经过localhost通讯 nginx

  • 全部Pod内容器均可以访问共享的Volume,能够访问共享数据 docker

  • 优雅终止:Pod删除的时候先给其内的进程发送SIGTERM,等待一段时间(grace period)后才强制中止依然还在运行的进程 apache

  • 特权容器(经过SecurityContext配置)具备改变系统配置的权限(在网络插件中大量应用)json

  • 支持三种重启策略(restartPolicy),分别是:Always、OnFailure、Never后端

  • 支持三种镜像拉取策略(imagePullPolicy),分别是:Always、Never、IfNotPresentbash

  • 资源限制,Kubernetes经过CGroup限制容器的CPU以及内存等资源,能够设置request以及limit值网络

  • 健康检查,提供两种健康检查探针,分别是livenessProbe和redinessProbe,前者用于探测容器是否存活,若是探测失败,则根据重启策略进行重启操做,后者用于检查容器状态是否正常,若是检查容器状态不正常,则请求不会到达该Pod负载均衡

  • Init container在全部容器运行以前执行,经常使用来初始化配置

  • 容器生命周期钩子函数,用于监听容器生命周期的特定事件,并在事件发生时执行已注册的回调函数,支持两种钩子函数:postStart和preStop,前者是在容器启动后执行,后者是在容器中止前执行


2 Namespace - 命名空间

Namespace(命名空间)是对一组资源和对象的抽象集合,好比能够用来将系统内部的对象划分为不一样的项目组或者用户组。常见的pod、service、replicaSet和deployment等都是属于某一个namespace的(默认是default),而node, persistentVolumes等则不属于任何namespace。

经常使用namespace操做:

# 查询全部namespaces 
kubectl get namespace
# 建立namespace
kubectl create namespace ns-name 
# 删除namespace
kubectl delete namespace ns-name复制代码

删除命名空间时,需注意如下几点:

  1. 删除一个namespace会自动删除全部属于该namespace的资源。

  2. default 和 kube-system 命名空间不可删除。

  3. PersistentVolumes是不属于任何namespace的,但PersistentVolumeClaim是属于某个特定namespace的。

  4. Events是否属于namespace取决于产生events的对象。

3 Node 节点

Node是Pod真正运行的主机,能够是物理机也能够是虚拟机。Node本质上不是Kubernetes来建立的, Kubernetes只是管理Node上的资源。为了管理Pod,每一个Node节点上至少须要运行container runtime(Docker)、kubelet和kube-proxy服务。


经常使用node操做:

# 查询全部node
kubectl get nodes
# 将node标志为不可调度
kubectl cordon $nodename
# 将node标志为可调度
kubectl uncordon $nodename复制代码

taint(污点)

使用kubectl taint命令能够给某个Node节点设置污点,Node被设置上污点以后就和Pod之间存在了一种相斥的关系,可让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。每一个污点的组成:`key=value:effect`,当前taint effect支持以下三个选项:

  • NoSchedule:表示k8s将不会将Pod调度到具备该污点的Node上

  • PreferNoSchedule:表示k8s将尽可能避免将Pod调度到具备该污点的Node上

  • NoExecute:表示k8s将不会将Pod调度到具备该污点的Node上,同时会将Node上已经存在的Pod驱逐出去


经常使用命令以下:

# 为节点node0设置不可调度污点
kubectl taint node node0 key1=value1:NoShedule
# 将node0上key值为key1的污点移除
kubectl taint node node0 key-
# 为kube-master节点设置不可调度污点
kubectl taint node node1 node-role.kubernetes.io/master=:NoSchedule
# 为kube-master节点设置尽可能不可调度污点
kubectl taint node node1 node-role.kubernetes.io/master=PreferNoSchedule复制代码

容忍(Tolerations)

设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在必定程度上不会被调度到Node上。 但咱们能够在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将能够容忍污点的存在,能够被调度到存在污点的Node上。


4 Service 服务

Service是对一组提供相同功能的Pods的抽象,并为他们提供一个统一的入口,借助 Service 应用能够方便的实现服务发现与负载均衡,并实现应用的零宕机升级。 Service经过标签(label)来选取后端Pod,通常配合ReplicaSet或者Deployment来保证后端容器的正常运行。


service 有以下四种类型,默认是ClusterIP:

  • ClusterIP: 默认类型,自动分配一个仅集群内部能够访问的虚拟IP

  • NodePort: 在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就能够经过 `NodeIP:NodePort` 来访问该服务

  • LoadBalancer: 在NodePort的基础上,借助cloud provider建立一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort

  • ExternalName: 将服务经过DNS CNAME记录方式转发到指定的域名


另外,也能够将已有的服务以Service的形式加入到Kubernetes集群中来,只须要在建立 Service 的时候不指定Label selector,而是在Service建立好后手动为其添加endpoint。


5 Volume 存储卷

默认状况下容器的数据是非持久化的,容器消亡之后数据也会跟着丢失,因此Docker提供了Volume机制以便将数据持久化存储。Kubernetes提供了更强大的Volume机制和插件,解决了容器数据持久化以及容器间共享数据的问题。


Kubernetes存储卷的生命周期与Pod绑定

  • 容器挂掉后Kubelet再次重启容器时,Volume的数据依然还在

  • Pod删除时,Volume才会清理。数据是否丢失取决于具体的Volume类型,好比emptyDir的数据会丢失,而PV的数据则不会丢


目前Kubernetes主要支持如下Volume类型:

  • emptyDir:Pod存在,emptyDir就会存在,容器挂掉不会引发emptyDir目录下的数据丢失,可是pod被删除或者迁移,emptyDir也会被删除

  • hostPath:hostPath容许挂载Node上的文件系统到Pod里面去

  • NFS(Network File System):网络文件系统,Kubernetes中经过简单地配置就能够挂载NFS到Pod中,而NFS中的数据是能够永久保存的,同时NFS支持同时写操做。

  • glusterfs:同NFS同样是一种网络文件系统,Kubernetes能够将glusterfs挂载到Pod中,并进行永久保存

  • cephfs:一种分布式网络文件系统,能够挂载到Pod中,并进行永久保存

  • subpath:Pod的多个容器使用同一个Volume时,会常常用到

  • secret:密钥管理,能够将敏感信息进行加密以后保存并挂载到Pod中

  • persistentVolumeClaim:用于将持久化存储(PersistentVolume)挂载到Pod中

  • ...


6 PersistentVolume(PV) 持久化存储卷

PersistentVolume(PV)是集群之中的一块网络存储。跟 Node 同样,也是集群的资源。PersistentVolume (PV)和PersistentVolumeClaim (PVC)提供了方便的持久化卷: PV提供网络存储资源,而PVC请求存储资源并将其挂载到Pod中。


PV的访问模式(accessModes)有三种:

  • ReadWriteOnce(RWO):是最基本的方式,可读可写,但只支持被单个Pod挂载。

  • ReadOnlyMany(ROX):能够以只读的方式被多个Pod挂载。

  • ReadWriteMany(RWX):这种存储能够以读写的方式被多个Pod共享。


不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较经常使用的是 NFS。在PVC绑定PV时一般根据两个条件来绑定,一个是存储的大小,另外一个就是 访问模式。


PV的回收策略(persistentVolumeReclaimPolicy)也有三种

  • Retain,不清理保留Volume(须要手动清理)

  • Recycle,删除数据,即 rm -rf /thevolume/* (只有NFS和HostPath支持)

  • Delete,删除存储资源


7 Deployment 无状态应用

通常状况下咱们不须要手动建立Pod实例,而是采用更高一层的抽象或定义来管理Pod,针对无状态类型的应用,Kubernetes使用Deloyment的Controller对象与之对应。其典型的应用场景包括:

  • 定义Deployment来建立Pod和ReplicaSet

  • 滚动升级和回滚应用

  • 扩容和缩容

  • 暂停和继续Deployment


经常使用的操做命令以下:

# 生成一个Deployment对象
kubectl run www --image=10.0.0.183:5000/hanker/www:0.0.1 --port=8080
# 查找Deployment
kubectl get deployment --all-namespaces
# 查看某个Deployment
kubectl describe deployment www
# 编辑Deployment定义
kubectl edit deployment www
# 删除某Deployment
kubectl delete deployment www
# 扩缩容操做,即修改Deployment下的Pod实例个数
kubectl scale deployment/www --replicas=2
# 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
# 回滚操做
kubectl rollout undo deployment/nginx-deployment
# 查看回滚进度
kubectl rollout status deployment/nginx-deployment
# 启用水平伸缩(HPA - horizontal pod autoscaling),设置最小、最大实例数量以及目标cpu使用率
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
# 暂停更新Deployment
kubectl rollout pause deployment/nginx-deployment
# 恢复更新Deployment
kubectl rollout resume deploy nginx复制代码

更新策略

`.spec.strategy` 指新的Pod替换旧的Pod的策略,有如下两种类型

  • `RollingUpdate` 滚动升级,能够保证应用在升级期间,对外正常提供服务。

  • `Recreate` 重建策略,在建立出新的Pod以前会先杀掉全部已存在的Pod。


Deployment和ReplicaSet二者之间的关系

  • 使用Deployment来建立ReplicaSet。ReplicaSet在后台建立pod,检查启动状态,看它是成功仍是失败。

  • 当执行更新操做时,会建立一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移 动到新的ReplicaSet中


8 StatefulSet 有状态应用

Deployments和ReplicaSets是为无状态服务设计的,那么StatefulSet则是为了有状态服务而设计,其应用场景包括:

  • 稳定的持久化存储,即Pod从新调度后仍是能访问到相同的持久化数据,基于PVC来实现

  • 稳定的网络标志,即Pod从新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现

  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行操做(即从0到N-1,在下一个Pod运行以前全部以前的Pod必须都是Running和Ready状态),基于init containers来实现

  • 有序收缩,有序删除(即从N-1到0)


支持两种更新策略:

  • OnDelete:当`.spec.template`更新时,并不当即删除旧的Pod,而是等待用户手动删除这些旧Pod后自动建立新Pod。这是默认的更新策略,兼容v1.6版本的行为

  • RollingUpdate:当 `.spec.template` 更新时,自动删除旧的Pod并建立新Pod替换。在更新时这些Pod是按逆序的方式进行,依次删除、建立并等待Pod变成Ready状态才进行下一个Pod的更新。


9 DaemonSet 守护进程集

DaemonSet保证在特定或全部Node节点上都运行一个Pod实例,经常使用来部署一些集群的日志采集、监控或者其余系统管理应用。典型的应用包括:

  • 日志收集,好比fluentd,logstash等

  • 系统监控,好比Prometheus Node Exporter,collectd等

  • 系统程序,好比kube-proxy, kube-dns, glusterd, ceph,ingress-controller等


指定Node节点

DaemonSet会忽略Node的unschedulable状态,有两种方式来指定Pod只运行在指定的Node节点上:

  • nodeSelector:只调度到匹配指定label的Node上

  • nodeAffinity:功能更丰富的Node选择器,好比支持集合操做

  • podAffinity:调度到知足条件的Pod所在的Node上


目前支持两种策略

  • OnDelete: 默认策略,更新模板后,只有手动删除了旧的Pod后才会建立新的Pod

  • RollingUpdate: 更新DaemonSet模版后,自动删除旧的Pod并建立新的Pod


10 Ingress 负载均衡

Kubernetes中的负载均衡咱们主要用到了如下两种机制:

  • Service:使用Service提供集群内部的负载均衡,Kube-proxy负责将service请求负载均衡到后端的Pod中

  • Ingress Controller:使用Ingress提供集群外部的负载均衡


Service和Pod的IP仅可在集群内部访问。集群外部的请求须要经过负载均衡转发到service所在节点暴露的端口上,而后再由kube-proxy经过边缘路由器将其转发到相关的Pod,Ingress能够给service提供集群外部访问的URL、负载均衡、HTTP路由等,为了配置这些Ingress规则,集群管理员须要部署一个Ingress Controller,它监听Ingress和service的变化,并根据规则配置负载均衡并提供访问入口。


经常使用的ingress controller:

  • nginx

  • traefik

  • Kong

  • Openresty


11 Job & CronJob 任务和定时任务

Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。


CronJob即定时任务,就相似于Linux系统的crontab,在指定的时间周期运行指定的任务。


12 HPA(Horizontal Pod Autoscaling) 水平伸缩

Horizontal Pod Autoscaling能够根据CPU、内存使用率或应用自定义metrics自动扩展Pod数量 (支持replication controller、deployment和replica set)。


  • 控制管理器默认每隔30s查询metrics的资源使用状况(能够经过 --horizontal-pod-autoscaler-sync-period 修改)

  • 支持三种metrics类型

    • 预约义metrics(好比Pod的CPU)以利用率的方式计算

    • 自定义的Pod metrics,以原始值(raw value)的方式计算

    • 自定义的object metrics

  • 支持两种metrics查询方式:Heapster和自定义的REST API

  • 支持多metrics


能够经过以下命令建立HPA:

kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10复制代码


13 Service Account

Service account是为了方便Pod里面的进程调用Kubernetes API或其余外部服务而设计的


受权

Service Account为服务提供了一种方便的认证机制,但它不关心受权的问题。能够配合RBAC(Role Based Access Control)来为Service Account鉴权,经过定义Role、RoleBinding、ClusterRole、ClusterRoleBinding来对sa进行受权。


14 Secret 密钥

Sercert-密钥解决了密码、token、密钥等敏感数据的配置问题,而不须要把这些敏感数据暴露到镜像或者Pod Spec中。Secret能够以Volume或者环境变量的方式使用。有以下三种类型:

  • Service Account:用来访问Kubernetes API,由Kubernetes自动建立,而且会自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中;

  • Opaque:base64编码格式的Secret,用来存储密码、密钥等;

  • kubernetes.io/dockerconfigjson: 用来存储私有docker registry的认证信息。


15 ConfigMap 配置中心

ConfigMap用于保存配置数据的键值对,能够用来保存单个属性,也能够用来保存配置文件。ConfigMap跟secret很相似,但它能够更方便地处理不包含敏感信息的字符串。ConfigMap能够经过三种方式在Pod中使用,三种分别方式为:设置环境变量、设置容器命令行参数以及在Volume中直接挂载文件或目录。

可使用 kubectl create configmap从文件、目录或者key-value字符串建立等建立 ConfigMap。也能够经过 kubectl create -f value.yaml 建立。


16 Resource Quotas 资源配额

资源配额(Resource Quotas)是用来限制用户资源用量的一种机制。

资源配额有以下类型:

  • 计算资源,包括cpu和memory

    • cpu, limits.cpu, requests.cpu

    • memory, limits.memory, requests.memory

  • 存储资源,包括存储资源的总量以及指定storage class的总量

    • requests.storage:存储资源总量,如500Gi

    • persistentvolumeclaims:pvc的个数

    • .storageclass.storage.k8s.io/requests.storage

    • .storageclass.storage.k8s.io/persistentvolumeclaims

  • 对象数,便可建立的对象的个数

    • pods, replicationcontrollers, configmaps, secrets

    • resourcequotas, persistentvolumeclaims

    • services, services.loadbalancers, services.nodeports


它的工做原理为:

  • 资源配额应用在Namespace上,而且每一个Namespace最多只能有一个 ResourceQuota 对象

  • 开启计算资源配额后,建立容器时必须配置计算资源请求或限制(也能够 用LimitRange设置默认值)

  • 用户超额后禁止建立新的资源

相关文章
相关标签/搜索