一、k8s组成
一个 kubernetes 集群主要由控制节点(master)、工作节点(node)构成,每个节点上都会安装不同的组件。
- 控制节点(master):集群的控制平面,负责集群的决策。
- API Server:集群操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制。
- Scheduler:负责集群资源调度,按照预定的调度策略将 Pod 调度到相应的 node 节点上。
- ControllerManager:负责维护集群的状态,比如程序部署安排、故障检测、自动扩展和滚动更新等。
- Etcd:负责存储集群中各种资源对象的信息。
- 工作节点(node):集群的数据平面,负责为容器提供运行环境。
- Kubelet:负责维护容器的生命周期,即通过控制 Docker ,来创建、更新、销毁容器。
- KubeProxy:负责提供集群内部的服务发现和负载均衡。
- Docker:负责节点上容器的各种操作。
其他概念
- Pod:Kubernetes 的最小控制单元,容器都是运行在 Pod 中的,一个 Pod 中可以有一个或多个容器。
- Controller:控制器,通过它来实现对 Pod 的管理,比如启动 Pod 、停止 Pod 、伸缩 Pod 的数量等等。
- Service:Pod 对外服务的统一入口,其下面可以维护同一类的多个 Pod 。
- Label:标签,用于对 Pod 进行分类,同一类 Pod 会拥有相同的标签。
- NameSpace:命名空间,用来隔离 Pod 的运行环境。
二、资源管理管理方式
命令式对象管理
语法格式:kubectl [command] [type] [name] [flags]
- command:指定要对资源执行的操作,比如create、get、delete。通过kubectl --help可以查看
- type:指定资源的类型,比如deployment、pod、service。通过kubectl api-resources查看
- name:指定资源的名称,名称大小写敏感。
- flags:指定额外的可选参数。
示例:查看所有的pod:kubectl get pods
命令式对象配置
通过命令配置和配置文件去操作kubernetes的资源,例如kubectl create -f nginxpod.yaml
声明式对象配置
通过apply命令和配置文件去操作kubernetes的资源,apply相当于create和patch,如果资源不存在,就创建,相当于kubectl create;如果资源存在,就更新,相当于kubectl patch。
kubectl apply -f nginxpod.yaml
使用推荐
- 创建和更新资源使用声明式对象配置:kubectl apply -f xxx.yaml。
- 删除资源使用命令式对象配置:kubectl delete -f xxx.yaml。
- 查询资源使用命令式对象管理:kubectl get(describe) 资源名称。
三、k8s资源类型
3.1 namespace
Namespace是kubernetes系统中一种非常重要的资源,它的主要作用是用来实现
多套系统的资源隔离
或者多租户的资源隔离
。通过Namespace可以Pod之间的互相访问。kubernetes在集群启动,会默认创建几个ns
kubectl get namespace
- default:所有未指定的Namespace的对象都会被分配在default命名空间。
- kube-node-lease:集群节点之间的心跳维护,v1.13开始引入。
- kube-public:此命名空间的资源可以被所有人访问(包括未认证用户)。
- kube-system:所有由kubernetes系统创建的资源都处于这个命名空间
通过命令操作namespace
- 查询:kubectl get namespace\ns [name]
查看命名空间的详情:kubectl describe namespace default
创建:kubectl create ns dev
删除:kubectl delete ns dev
通过命令式对象配置进行创建和删除
- 创建:kubectl create -f xxx.yaml
- 删除:kubectl delete -f xxx.yaml
3.2 Pod
- Pod是kubernetes集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于Pod中。
- Pod可以认为是容器的封装,一个Pod中可以存在一个或多个容器
命令操作Pod
- 创建Pod:kubectl run (Pod的名称) [参数]
- # --image 指定Pod的镜像
# --port 指定端口
# --namespace 指定namespace查询所有Pod的基本信息:kubectl get pods [-n 命名空间的名称]
查看Pod的详细信息:kubectl describe pod pod的名称 [-n 命名空间名称]
删除Pod:kubectl delete pod pod的名称 [-n 命名空间]
配置文件操作Pod
- 创建pod:kubectl create -f xxx.yaml
- 删除pod:kubectl delete -f xxx.yaml
3.3 Label
Label作用是在资源添加标识,用它来区分和选择,使得在不同的namespace下的pod也能相互访问。
命令操作标签
为资源打标签:kubectl label pod xxx key=value [-n 命名空间]
更新标签:kubectl label pod xxx key=value [-n 命名空间] --overwrite
查看标签:kubectl get pod xxx [-n 命名空间] --show-labels
涮选标签:kubectl get pod -l key=value [-n 命名空间] --show-labels
删除标签:kubectl label pod xxx key- [-n 命名空间]
3.4 deployment
Pod控制器用于Pod的管理,确保Pod资源符合预期的状态,当Pod的资源出现故障的时候,会尝试进行重启或重建Pod。
命令操作deployment
- 查看deployment:kubectl get deployment/deploy
- 创建deployment:kubectl create deployment 名称 --image=镜像名称
查看deployment的详细信息:kubectl describe deployment xxx [-n 命名空间]
删除deployment:kubectl delete deployment xxx [-n 命名空间]
配置文件操作deployment
- 创建deployment:kubectl create -f xxx.yaml
- 删除deployment:kubectl delete -f xxx.yaml
3.5 service
Service可以看做是一组同类的Pod对外的访问接口,借助Service,应用可以方便的实现服务发现和负载均衡。
命令操作service
- 暴露service:kubectl expose deployment xxx --name=服务名 --type=ClusterIP --port=暴露的端口 --target-port=指向集群中的Pod的端口 [-n 命名空间]
- ClusterIP:只能在集群内部访问
- NodePort:可以在集群外部访问
- 查看service:kubectl get service [-n 命名空间] [-o wide]
- 删除service:kubectl delete service xxx [-n 命名空间]
配置文件操作service
- 创建service:kubectl create -f xxx.yaml
- 删除service:kubectl delete -f xxx.yaml
四、Pod详解
4.1 Pod结构与定义
每个Pod中都包含一个或者多个容器
每个Pod都会有的一个根容器,作用:①评估整个Pod的健康状况②可以在根容器上设置IP地址,其它容器都共享此IP(Pod的IP),以实现Pod内部的网络通信
Pod资源清单
- 查询某种资源清单的一级属性:kubectl explain 资源类型
- 查看某种资源可以配置的子属性:kubectl explain 资源类型.属性
4.2 Pod基本配置
Pod资源清单如下
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,资源类型,例如 Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #Pod所属的命名空间,默认为"default"
labels: #自定义标签列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口的名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略
nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
4.3 Pod之镜像拉取策略
imagePullPolicy:用于设置镜像拉取的策略,kubernetes支持配置三种拉取策略:
- Always:总是从远程仓库拉取镜像(一直远程下载)。
- IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像。
- Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错。
默认值说明:
- 如果镜像tag为具体的版本号,默认策略是IfNotPresent。
- 如果镜像tag为latest(最终版本),默认策略是Always。
4.4 Pod之启动命令
command:用于在Pod中的容器初始化完毕之后执行一个命令
- 如果command和args均没有写,那么用Dockerfile的配置。
- 如果command写了,但是args没有写,那么Dockerfile默认的配置会被忽略,执行注入的command。
- 如果command没有写,但是args写了,那么Dockerfile中配置的ENTRYPOINT命令会被执行,使用当前args的参数。
- 如果command和args都写了,那么Dockerfile中的配置会被忽略,执行command并追加上args参数。
4.5 Pod之生命周期
Pod的生命周期
- Pod创建过程。
- 运行初始化容器(init container)过程。
- 运行主容器(main container):
- 容器启动后钩子(post start)、容器终止前钩子(pre stop)。
- 容器的存活性探测(liveness probe)、就绪性探测(readiness probe)。
- Pod终止过程。
- 在整个生命周期中,Pod会出现5种状态(相位),分别如下:
- 挂起(Pending):API Server已经创建了Pod资源对象,但它尚未被调度完成或者仍处于下载镜像的过程中。
- 运行中(Running):Pod已经被调度到某节点,并且所有容器都已经被kubelet创建完成。
- 成功(Succeeded):Pod中的所有容器都已经成功终止并且不会被重启。
- 失败(Failed):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态。
- 未知(Unknown):API Server无法正常获取到Pod对象的状态信息,通常由于网络通信失败所导致。
Pod的创建过程
- ① 用户通过kubectl或其他的api客户端提交需要创建的Pod信息给API Server。
- ② API Server开始生成Pod对象的信息,并将信息存入etcd,然后返回确认信息至客户端。
- ③ API Server开始反映etcd中的Pod对象的变化,其它组件使用watch机制来跟踪检查API Server上的变动。
- ④ Scheduler发现有新的Pod对象要创建,开始为Pod分配主机并将结果信息更新至API Server。
- ⑤ Node节点上的kubelet发现有Pod调度过来,尝试调度Docker启动容器,并将结果回送至API Server。
- ⑥ API Server将接收到的Pod状态信息存入到etcd中。
Pod的终止过程
- ① 用户向API Server发送删除Pod对象的命令。
- ② API Server中的Pod对象信息会随着时间的推移而更新,在宽限期内(默认30s),Pod被视为dead。
- ③ 将Pod标记为terminating状态。
- ④ kubelete在监控到Pod对象转为terminating状态的同时启动Pod关闭过程。
- ⑤ 端点控制器监控到Pod对象的关闭行为时将其从所有匹配到此端点的service资源的端点列表中移除。
- ⑥ 如果当前Pod对象定义了preStop钩子处理器,则在其标记为terminating后会以同步的方式启动执行。
- ⑦ Pod对象中的容器进程收到停止信号。
- ⑧ 宽限期结束后,如果Pod中还存在运行的进程,那么Pod对象会收到立即终止的信号。
- ⑨ kubectl请求API Server将此Pod资源的宽限期设置为0从而完成删除操作,此时Pod对于用户已经不可用了。
4.6 Pod之初始化容器
初始化容器是在Pod的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,它具有两大特征:
- ① 初始化容器必须运行完成直至结束,如果某个初始化容器运行失败,那么kubernetes需要重启它直至成功完成。
- ② 初始化容器必须按照定义的顺序执行,当且仅当前一个成功之后,后面的一个才能运行。
初始化容器有很多的应用场景,下面列出的是最常见的几个:
- 提供主容器镜像中不具备的工具程序或自定义代码。
- 初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足。
初始化容器配置使用关键字initContainers,在yaml层级和containers一致,配置也基本一致
4.7 钩子函数
kubernetes在主容器启动之后和停止之前提供了两个钩子函数:
- post start:容器创建之后执行,如果失败会重启容器。
- pre stop:容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作。
钩子处理器支持使用下面的三种方式定义动作
exec命令:在容器内执行一次命令
tcpSocket:在当前容器尝试访问指定的socket
httpGet:在当前容器中向某url发起HTTP请求
4.8 容器探测
- liveness probes:存活性探测,用于检测应用实例当前是否处于正常运行状态,如果不是,k8s会重启容器。
- readiness probes:就绪性探测,用于检测应用实例是否可以接受请求,如果不能,k8s不会转发流量。
探针支持的三种探测方式
① exec命令:在容器内执行一次命令,如果命令执行的退出码为0,则认为程序正常,否则不正常。
②tcpSocket:将会尝试访问一个用户容器的端口,如果能够建立这条连接,则认为程序正常,否则不正常。
- ③ httpGet:调用容器内web应用的URL,如果返回的状态码在200和399之前,则认为程序正常,否则不正常。
4.9 重启策略
在容器探测中,一旦容器探测出现了问题,kubernetes就会对容器所在的Pod进行重启,其实这是由Pod的重启策略决定的,Pod的重启策略有3种,分别如下:
- Always:容器失效时,自动重启该容器,默认值。
- OnFailure:容器终止运行且退出码不为0时重启。
- Never:不论状态如何,都不重启该容器。
重启策略适用于Pod对象中的所有容器,首次需要重启的容器,将在其需要的时候立即进行重启,随后再次重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作的延迟时长以此为10s、20s、40s、80s、160s和300s,300s是最大的延迟时长。
spec: containers: # 容器配置 - name: nginx image: nginx:1.17.1 imagePullPolicy: IfNotPresent ports: - name: nginx-port containerPort: 80 protocol: TCP livenessProbe: # 存活性探测 httpGet: port: 80 path: /hello host: 127.0.0.1 scheme: HTTP restartPolicy: Never # 重启策略
4.10 Pod调度
kubernetes提供了四大类调度方式。
- 自动调度:运行在哪个Node节点上完全由Scheduler经过一系列的算法计算得出。
- 定向调度:NodeName、NodeSelector。
- 亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity。
- 污点(容忍)调度:Taints、Toleration。
4.10.1 定向调度
定向调度,指的是利用在Pod上声明的nodeName或nodeSelector,以此将Pod调度到期望的Node节点上。这种方式是强制调度的。
apiVersion: v1 kind: Pod metadata: name: pod-nodename namespace: dev labels: user: xudaxian spec: containers: # 容器配置 - name: nginx image: nginx:1.17.1 imagePullPolicy: IfNotPresent ports: - name: nginx-port containerPort: 80 protocol: TCP nodeName: k8s-node1 # 指定调度到k8s-node1节点上
nodeSelector用于将Pod调度到添加了指定标签的Node节点上,它是通过kubernetes的label-selector机制实现的,换言之,在Pod创建之前,会由Scheduler使MatchNodeSelector调度策略进行label匹配,找出目标node,然后将Pod调度到目标节点,该匹配规则是强制约束。
apiVersion: v1 kind: Pod metadata: name: pod-nodeselector namespace: dev spec: containers: # 容器配置 - name: nginx image: nginx:1.17.1 imagePullPolicy: IfNotPresent ports: - name: nginx-port containerPort: 80 protocol: TCP nodeSelector: nodeenv: pro # 指定调度到具有nodeenv=pro的Node节点上
4.10.2 亲和性调度
kubernetes提供了一种亲和性调度(Affinity)。它在nodeSelector的基础之上进行了扩展,可以通过配置的形式,实现优先选择满足条件的Node进行调度,如果没有,也可以调度到不满足条件的节点上,使得调度更加灵活。
Affinity主要分为三类:
- nodeAffinity(node亲和性):以Node为目标,解决Pod可以调度到那些Node的问题。
- podAffinity(pod亲和性):以Pod为目标,解决Pod可以和那些已存在的Pod部署在同一个拓扑域中的问题。
- podAntiAffinity(pod反亲和性):以Pod为目标,解决Pod不能和那些已经存在的Pod部署在同一拓扑域中的问题。
node亲和性
pod.spec.affinity.nodeAffinity requiredDuringSchedulingIgnoredDuringExecution Node节点必须满足指定的所有规则才可以,相当于硬限制 nodeSelectorTerms 节点选择列表 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持Exists, DoesNotExist, In, NotIn, Gt, Lt preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node,相当于软限制 (倾向) preference 一个节点选择器项,与相应的权重相关联 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt weight 倾向权重,在范围1-100。
nodeAffinity的注意事项:
- 如果同时定义了nodeSelector和nodeAffinity,那么必须两个条件都满足,Pod才能运行在指定的Node上。
- 如果nodeAffinity指定了多个nodeSelectorTerms,那么只需要其中一个能够匹配成功即可。
- 如果一个nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有的才能匹配成功。
- 如果一个Pod所在的Node在Pod运行期间其标签发生了改变,不再符合该Pod的nodeAffinity的要求,则系统将忽略此变化。
podAffinity亲和性
podAffinity主要实现以运行的Pod为参照,实现让新创建的Pod和参照的Pod在一个区域的功能。
pod.spec.affinity.podAffinity requiredDuringSchedulingIgnoredDuringExecution 硬限制 namespaces 指定参照pod的namespace topologyKey 指定调度作用域 labelSelector 标签选择器 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist. matchLabels 指多个matchExpressions映射的内容 preferredDuringSchedulingIgnoredDuringExecution 软限制 podAffinityTerm 选项 namespaces topologyKey labelSelector matchExpressions key 键 values 值 operator matchLabels weight 倾向权重,在范围1-1
topologyKey用于指定调度的作用域,例如:
- 如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围。
- 如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分。
podAntiAffinity反亲和性
podAntiAffinity主要实现以运行的Pod为参照,让新创建的Pod和参照的Pod不在一个区域的功能。其配置方式和podAffinity一样
4.10.3 污点和容忍
污点就是站在Node的角度上,通过在Node上添加
污点属性
,来决定是否运行Pod调度过来。
- 污点的格式为:
key=value:effect
,key和value是污点的标签,effect描述污点的作用,支持如下三个选项:
- PreferNoSchedule:kubernetes将尽量避免把Pod调度到具有该污点的Node上,除非没有其他节点可以调度。
- NoSchedule:kubernetes将不会把Pod调度到具有该污点的Node上,但是不会影响当前Node上已经存在的Pod。
- NoExecute:kubernetes将不会把Pod调度到具有该污点的Node上,同时也会将Node上已经存在的Pod驱逐。
设置污点
kubectl taint node xxx key=value:effect
去除污点
kubectl taint node xxx key:effect-
去除所有污点
kubectl taint node xxx key-
使用kubeadm搭建的集群,默认就会给Master节点添加一个污点标记,所以Pod就不会调度到Master节点上。
容忍就是忽略,Node通过污点拒绝Pod调度上去,Pod通过容忍忽略拒绝。
kubectl explain pod.spec.tolerations ...... FIELDS: key # 对应着要容忍的污点的键,空意味着匹配所有的键 value # 对应着要容忍的污点的值 operator # key-value的运算符,支持Equal和Exists(默认) effect # 对应污点的effect,空意味着匹配所有影响 tolerationSeconds # 容忍时间, 当effect为NoExecute时生效,表示pod在Node上的停留时间
五、Pod控制器
Pod控制器用来管理Pod的,保证Pod数量的正常运行
- ReplicationController:比较原始的Pod控制器,已经被废弃,由ReplicaSet替代。
- ReplicaSet:保证指定数量的Pod运行,并支持Pod数量变更,镜像版本变更。
- Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、版本回退。
- Horizontal Pod Autoscaler:可以根据集群负载自动调整Pod的数量,实现削峰填谷。
- DaemonSet:在集群中的指定Node上都运行一个副本,一般用于守护进程类的任务。
- Job:它创建出来的Pod只要完成任务就立即退出,用于执行一次性任务。
- CronJob:它创建的Pod会周期性的执行,用于执行周期性的任务。
- StatefulSet:管理有状态的应用。
5.1 ReplicaSet
ReplicaSet的主要作用是保证一定数量的Pod能够正常运行,它会持续监听这些Pod的运行状态,一旦Pod发生故障,就会重启或重建。同时它还支持对Pod数量的扩缩容和版本镜像的升级。
apiVersion: apps/v1 # 版本号 kind: ReplicaSet # 类型 metadata: # 元数据 name: # rs名称 namespace: # 所属命名空间 labels: #标签 controller: rs spec: # 详情描述 replicas: 3 # 副本数量 selector: # 选择器,通过它指定该控制器管理哪些po matchLabels: # Labels匹配规则 app: nginx-pod matchExpressions: # Expressions匹配规则 - {key: app, operator: In, values: [nginx-pod]} template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1 ports: - containerPort: 80
扩缩容
- kubectl edit rs pc-replicaset -n dev
- kubectl scale rs pc-replicaset --replicas=2 -n dev
镜像升级
- kubectl edit rs pc-replicaset -n dev
- kubectl set image rs rs名称 容器名称=镜像版本 -n 命名空间
删除ReplicaSe
- kubectl delete rs pc-replicaset -n dev
- kubectl delete rs pc-replicaset -n dev --cascade=false 这种方式会保留Pod
- kubectl delete -f pc-replicaset.yaml
5.2 Deployment
Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment的功能比ReplicaSet强大。Deployment的主要功能如下:
- 支持ReplicaSet的所有功能。
- 支持发布的停止、继续。
- 支持版本滚动更新和版本回退。
apiVersion: apps/v1 # 版本号 kind: Deployment # 类型 metadata: # 元数据 name: # rs名称 namespace: # 所属命名空间 labels: #标签 controller: deploy spec: # 详情描述 replicas: 3 # 副本数量 revisionHistoryLimit: 3 # 保留历史版本,默认为10 paused: false # 暂停部署,默认是false progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600 strategy: # 策略 type: RollingUpdate # 滚动更新策略 rollingUpdate: # 滚动更新 maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数 maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数 selector: # 选择器,通过它指定该控制器管理哪些pod matchLabels: # Labels匹配规则 app: nginx-pod matchExpressions: # Expressions匹配规则 - {key: app, operator: In, values: [nginx-pod]} template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1 ports: - containerPort: 80
扩缩容
- kubectl scale deploy pc-deployment --replicas=5 -n dev
- kubectl edit deployment pc-deployment -n dev
镜像更新
Deployment支持两种镜像更新的策略:重建更新和滚动更新(默认),可以通过strategy选项进行配置。
strategy: 指定新的Pod替代旧的Pod的策略,支持两个属性 type: 指定策略类型,支持两种策略 Recreate:在创建出新的Pod之前会先杀掉所有已经存在的Pod RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本的Pod rollingUpdate:当type为RollingUpdate的时候生效,用于为rollingUpdate设置参数,支持两个属性: maxUnavailable:用来指定在升级过程中不可用的Pod的最大数量,默认为25%。 maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。
版本回退
# 版本升级相关功能
kubetl rollout 参数 deploy xx # 参数支持下面的选择
- status 显示当前升级的状态
- history 显示升级历史记录
- pause 暂停版本升级过程
- resume 继续已经暂停的版本升级过程
- restart 重启版本升级过程
- undo 回滚到上一级版本 (可以使用--to-revision回滚到指定的版本)
5.3 其他控制器
- Horizontal Pod Autoscaler(HPA)可以通过监测Pod的使用情况,实现Pod数量的自动调整
DaemonSet类型的控制器可以保证集群中的每一台(或指定)节点上都运行一个副本,一般适用于日志收集、节点监控等场景。也就是说,如果一个Pod提供的功能是节点级别的(每个节点都需要且只需要一个),那么这类Pod就适合使用DaemonSet类型的控制器创建,特点如下
- 每向集群中添加一个节点的时候,指定的Pod副本也将添加到该节点上。
- 当节点从集群中移除的时候,Pod也会被垃圾回收。
- Job主要用于负责批量处理短暂的一次性任务。Job的特点:
- 当Job创建的Pod执行成功结束时,Job将记录成功结束的Pod数量。
- 当成功结束的Pod达到指定的数量时,Job将完成执行。
CronJob控制器可以以类似Linux操作系统的周期性任务作业计划的方式控制器运行时间点及重复运行的方式
六、 Service详解
Service会对提供同一个服务的多个Pod进行聚合,并且提供一个统一的入口地址,通过访问Service的入口地址就能访问到后面的Pod服务。
资源清单
apiVersion: v1 # 版本 kind: Service # 类型 metadata: # 元数据 name: # 资源名称 namespace: # 命名空间 spec: selector: # 标签选择器,用于确定当前Service代理那些Pod app: nginx type: NodePort # Service的类型,指定Service的访问方式 clusterIP: # 虚拟服务的IP地址 sessionAffinity: # session亲和性,支持ClientIP、None两个选项,默认值为None ports: # 端口信息 - port: 8080 # Service端口 protocol: TCP # 协议 targetPort : # Pod端口 nodePort: # 主机端口
spec.type的说明:
- ClusterIP:默认值,它是kubernetes系统自动分配的虚拟IP,只能在集群内部访问。
- NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务。
- LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境的支持。
- ExternalName:把集群外部的服务引入集群内部,直接使用。
负载均衡策略
- 对Service的访问被分发到了后端的Pod上去,目前kubernetes提供了两种负载分发策略:
- 如果不定义,默认使用kube-proxy的策略,比如随机、轮询等。
- 基于客户端地址的会话保持模式,即来自同一个客户端发起的所有请求都会转发到固定的一个Pod上,这对于传统基于Session的认证项目来说很友好,此模式可以在spec中添加
sessionAffinity: ClusterIP
选项。Service的类型
- ClusterIP类型的Service只能在集群内部访问
- HeadLiness类型的Service,不会分配Cluster IP,如果想要访问Service,只能通过Service的域名进行查询,设置clusterIP:None
七、Ingress介绍
Ingress相当于一个七层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解为Ingress里面建立了诸多映射规则,Ingress Controller通过监听这些配置规则并转化为Nginx的反向代理配置,然后对外提供服务。
- Ingress:kubernetes中的一个对象,作用是定义请求如何转发到Service的规则。
- Ingress Controller:具体实现反向代理及负载均衡的程序,对Ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现的方式有很多,比如Nginx,Contour,Haproxy等。
八、数据存储
在前面已经提到,容器的生命周期可能很短,会被频繁的创建和销毁。那么容器在销毁的时候,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器中的数据,kubernetes引入了Volume的概念。
Volume是Pod中能够被多个容器访问的共享目录,它被定义在Pod上,然后被一个Pod里面的多个容器挂载到具体的文件目录下,kubernetes通过Volume实现同一个Pod中不同容器之间的数据共享以及数据的持久化存储。Volume的生命周期不和Pod中的单个容器的生命周期有关,当容器终止或者重启的时候,Volume中的数据也不会丢失。
kubernetes的Volume支持多种类型,比较常见的有下面的几个:
- 简单存储:EmptyDir、HostPath、NFS。
- 高级存储:PV、PVC。
- 配置存储:ConfigMap、Secret。
8.1 EmptyDir
EmptyDir是最基础的Volume类型,一个EmptyDir就是Host上的一个空目录。
EmptyDir是在Pod被分配到Node时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为kubernetes会自动分配一个目录,当Pod销毁时,EmptyDir中的数据也会被永久删除。
EmptyDir的用途如下:
- 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留。
- 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)。
8.2 HostPath
HostPath就是将Node主机中的一个实际目录挂载到Pod中,以供容器使用,这样的设计就可以保证Pod销毁了,但是数据依旧可以保存在Node主机上。
....
volumes: # 声明volume,name为logs-volume,类型为hostPath
- name: logs-volume
hostPath:
path: /root/logs
type: DirectoryOrCreate # 目录存在就使用,不存在就先创建再使用type的值的说明:
- DirectoryOrCreate:目录存在就使用,不存在就先创建后使用。
- Directory:目录必须存在。
- FileOrCreate:文件存在就使用,不存在就先创建后使用。
- File:文件必须存在。
- Socket:unix套接字必须存在。
- CharDevice:字符设备必须存在。
- BlockDevice:块设备必须存在。
8.3 NFS
NFS是一个网络文件存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上,这样,无论Pod在节点上怎么转移,只要Node和NFS的对接没有问题,数据就可以成功访问。
8.4 PV
PV是存储资源的抽象,下面是PV的资源清单文件:
apiVersion: v1 kind: PersistentVolume metadata: name: pv2 spec: nfs: # 存储类型,和底层正则的存储对应 path: server: capacity: # 存储能力,目前只支持存储空间的设置 storage: 2Gi accessModes: # 访问模式 - storageClassName: # 存储类别 persistentVolumeReclaimPolicy: # 回收策略
pv的关键配置参数说明:
- 存储类型:底层实际存储的类型,kubernetes支持多种存储类型,每种存储类型的配置有所不同。
- 存储能力(capacity):目前只支持存储空间的设置(storage=1Gi),不过未来可能会加入IOPS、吞吐量等指标的配置。
- 访问模式(accessModes):用来描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
- ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载。
- ReadOnlyMany(ROX):只读权限,可以被多个节点挂载。
- ReadWriteMany(RWX):读写权限,可以被多个节点挂载。
需要注意的是,底层不同的存储类型可能支持的访问模式不同。
- 回收策略( persistentVolumeReclaimPolicy):当PV不再被使用之后,对其的处理方式,目前支持三种策略:
- Retain(保留):保留数据,需要管理员手动清理数据。
- Recycle(回收):清除PV中的数据,效果相当于
rm -rf /volume/*
。- Delete(删除):和PV相连的后端存储完成volume的删除操作,常见于云服务器厂商的存储服务。
需要注意的是,底层不同的存储类型可能支持的回收策略不同。
- 存储类别(storageClassName):PV可以通过storageClassName参数指定一个存储类别。
- 具有特定类型的PV只能和请求了该类别的PVC进行绑定。
- 未设定类别的PV只能和不请求任何类别的PVC进行绑定。
- 状态(status):一个PV的生命周期,可能会处于4种不同的阶段。
- Available(可用):表示可用状态,还未被任何PVC绑定。
- Bound(已绑定):表示PV已经被PVC绑定。
- Released(已释放):表示PVC被删除,但是资源还没有被集群重新释放。
- Failed(失败):表示该PV的自动回收失败。
PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息,下面是PVC的资源清单文件
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc namespace: dev spec: accessModes: # 访客模式 - selector: # 采用标签对PV选择 storageClassName: # 存储类别 resources: # 请求空间 requests: storage: 5Gi
PVC的关键配置参数说明:
- 访客模式(accessModes):用于描述用户应用对存储资源的访问权限。
- 用于描述用户应用对存储资源的访问权限:
- 选择条件(selector):通过Label Selector的设置,可使PVC对于系统中已存在的PV进行筛选。
- 存储类别(storageClassName):PVC在定义时可以设定需要的后端存储的类别,只有设置了该class的pv才能被系统选出。
- 资源请求(resources):描述对存储资源的请求。
8.5 ConfigMap
ConfigMap是一个比较特殊的存储卷,它的主要作用是用来存储配置信息的。
apiVersion: v1 kind: ConfigMap metadata: name: configMap namespace: dev data: # <map[string]string> xxx
挂载到容器
apiVersion: v1 kind: Pod metadata: name: pod-configmap namespace: dev spec: containers: - name: nginx image: nginx:1.17.1 volumeMounts: - mountPath: /configmap/config name: config volumes: - name: config configMap: name: configmap
8.7 Secret
在kubernetes中,还存在一种和ConfigMap非常类似的对象,称为Secret对象,它主要用来存储敏感信息,例如密码、密钥、证书等等。