Pod
每个Pod中都包含一个或者多个容器,这些容器可以分为两类:① 用户程序所在的容器,数量可多可少。② Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个:
- 可以以它为依据,评估整个Pod的健康状况。
- 可以在根容器上设置IP地址,其它容器都共享此IP(Pod的IP),以实现Pod内部的网络通信
ReplicaSet
ReplicaSet的主要作用是保证一定数量的Pod能够正常运行,它会持续监听这些Pod的运行状态,一旦Pod发生故障,就会重启或重建。同时它还支持对Pod数量的扩缩容
ReplicaSet的资源清单文件:
1 |
apiVersion: apps/v1 # 版本号 kind: ReplicaSet # 类型 metadata: # 元数据 name: pc-replicaset # rs名称 namespace: dev # 命名类型 spec: # 详细描述 replicas: 3 # 副本数量 selector: # 选择器,通过它指定该控制器可以管理哪些Pod matchLabels: # Labels匹配规则 app: nginx-pod template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx # 容器名称 image: nginx:1.17.1 # 容器需要的镜像地址 ports: - containerPort: 80 # 容器所监听的端口 |
replicas:指定副本数量,其实就是当然rs创建出来的Pod的数量,默认为1
selector:选择器,它的作用是建立Pod控制器和Pod之间的关联关系,采用了Label Selector机制(在Pod模块上定义Label,在控制器上定义选择器,就可以表明当前控制器能管理哪些Pod了)。
template:模板,就是当前控制器创建Pod所使用的模板,里面其实就是前面学过的Pod的定义
创建rs
1 |
kubectl create -f pc-replicaset.yaml 查看 kubectl get rs pc-replicaset -n dev -o wide |
扩缩容 编辑rs的副本数量,修改spec:replicas:6即可
1 |
kubectl edit rs pc-replicaset -n dev |
删除
1 |
# 在kubernetes删除ReplicaSet前,会将ReplicaSet的replicas调整为0,等到所有的Pod被删除后,再执行ReplicaSet对象的删除 kubectl delete rs pc-replicaset -n dev 使用yaml直接删除 kubectl delete -f pc-replicaset.yaml |
Deployment
Deployment控制器并不直接管理Pod,而是通过管理ReplicaSet来间接管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment的功能比ReplicaSet强大
主要功能:
1 |
○ 支持ReplicaSet的所有功能。 ○ 支持发布的停止、继续。 ○ 支持版本滚动更新和版本回退 |
创建pc-deployment.yaml文件
1 |
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 |
创建Deployment
1 |
kubectl create -f pc-deployment.yaml 查看 kubectl get deploy pc-deployment -n dev 查看ReplicaSet kubectl get rs -n dev 使用scale命令实现扩缩容 kubectl scale deploy pc-deployment --replicas=5 -n dev 编辑Deployment的副本数量,修改spec:replicas:4即可 kubectl edit deployment pc-deployment -n dev |
Deployment支持两种镜像更新的策略:重建更新
和滚动更新(默认)
,可以通过strategy
选项进行配置
1 |
strategy: 指定新的Pod替代旧的Pod的策略,支持两个属性 type: 指定策略类型,支持两种策略 Recreate:在创建出新的Pod之前会先杀掉所有已经存在的Pod RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本的Pod rollingUpdate:当type为RollingUpdate的时候生效,用于为rollingUpdate设置参数,支持两个属性: maxUnavailable:用来指定在升级过程中不可用的Pod的最大数量,默认为25%。 maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。 |
编辑pc-deployment.yaml文件,在spec节点下添加更新策略
1 |
更新Deployment kubectl apply -f pc-deployment.yaml |
镜像升级
1 |
kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev |
版本回退
1 |
# 版本升级相关功能 kubetl rollout 参数 deploy xx # 支持下面的选择 # status 显示当前升级的状态 # history 显示升级历史记录 # pause 暂停版本升级过程 # resume 继续已经暂停的版本升级过程 # restart 重启版本升级过程 # undo 回滚到上一级版本 (可以使用--to-revision回滚到指定的版本) |
查看当前升级版本的状态
1 |
kubectl rollout status deployment pc-deployment -n dev 历史记录 kubectl rollout history deployment pc-deployment -n dev 版本回退 # 可以使用-to-revision=1回退到1版本,如果省略这个选项,就是回退到上个版本,即2版本 kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev |
删除Deployment,其下的ReplicaSet和Pod也会一起被删除:
1 |
kubectl delete -f pc-deployment.yaml |
Horizontal Pod Autoscaler(HPA)
-
动执行
kubectl scale
命令实现Pod的扩缩容,但是这显然不符合kubernetes的定位目标–自动化和智能化。kubernetes期望可以通过监测Pod的使用情况,实现Pod数量的自动调整,于是就产生了HPA这种控制器。
-
HPA可以获取每个Pod的利用率,然后和HPA中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现Pod的数量的调整。其实HPA和之前的Deployment一样,也属于一种kubernetes资源对象,它通过追踪分析目标Pod的负载变化情况,来确定是否需要针对性的调整目标Pod的副本数。
安装metrics-server
1 |
wget https://github.com/kubernetes-sigs/metrics-server/archive/v0.3.6.tar.gz 解压 tar -zxvf v0.3.6.tar.gz 进入metrics-server-0.3.6/deploy/1.8+/目录 cd metrics-server-0.3.6/deploy/1.8+/ 修改metrics-server-deployment.yaml文件 vim metrics-server-deployment.yaml 添加 hostNetwork: true image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6 args: - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP |
安装metrics-server(v0.3.6)
1 |
kubectl apply -f ./ 查看metrics-server生成的Pod kubectl get pod -n kube-system 查看资源使用情况 kubectl top node kubectl top pod -n kube-system |
安装metrics-server(v0.4.1)
1 |
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.4.1/components.yaml |
修改components.yaml
1 |
apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: selector: matchLabels: k8s-app: metrics-server strategy: rollingUpdate: maxUnavailable: 0 template: metadata: labels: k8s-app: metrics-server spec: containers: - args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port # 修改部分 - --kubelet-insecure-tls # 修改部分 image: registry.cn-shanghai.aliyuncs.com/xuweiwei-kubernetes/metrics-server:v0.4.1 |
安装metrics-server
1 |
kubectl apply -f components.yaml |
准备Deployment和Service
-
创建Deployment:创建nginx.yaml文件,内容如下
1 |
apiVersion: apps/v1 # 版本号 kind: Deployment # 类型 metadata: # 元数据 name: nginx # deployment的名称 namespace: dev # 命名类型 spec: # 详细描述 selector: # 选择器,通过它指定该控制器可以管理哪些Pod matchLabels: # Labels匹配规则 app: nginx-pod template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx # 容器名称 image: nginx:1.17.1 # 容器需要的镜像地址 ports: - containerPort: 80 # 容器所监听的端口 resources: # 资源限制 requests: cpu: "100m" # 100m表示100millicpu,即0.1个CPU |
创建Deployment
1 |
kubectl create -f nginx.yaml |
查看Deployment和Pod
1 |
kubectl get pod,deploy -n dev |
创建Service
1 |
kubectl expose deployment nginx --name=nginx --type=NodePort --port=80 --target-port=80 -n dev 查看 kubectl get svc -n dev |
部署HPA
创建pc-hpa.yaml文件,内容如下
1 |
apiVersion: autoscaling/v1 # 版本号 kind: HorizontalPodAutoscaler # 类型 metadata: # 元数据 name: pc-hpa # deployment的名称 namespace: dev # 命名类型 spec: minReplicas: 1 # 最小Pod数量 maxReplicas: 10 # 最大Pod数量 targetCPUUtilizationPercentage: 3 # CPU使用率指标 scaleTargetRef: # 指定要控制的Nginx的信息 apiVersion: apps/v1 kind: Deployment name: nginx |
创建hpa
1 |
kubectl create -f pc-hpa.yaml 查看 kubectl get hpa -n dev |
StatefulSet(有状态)
无状态应用:
认为Pod都是一样的,没有顺序要求,不用考虑在哪个Node节点上运行,随意进行伸缩和扩展
有状态应用:
有顺序的要求,认为每个Pod都是不一样的,需要考虑在哪个Node节点上运行,需要按照顺序进行伸缩和扩展,让每个Pod都是独立的,保持Pod启动顺序和唯一性。
StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器,部署需要HeadLinessService(无头服务)
在用Deployment时,每一个Pod名称是没有顺序的,是随机字符串,因此是Pod名称是无序的,但是在StatefulSet中要求必须是有序 ,每一个Pod不能被随意取代,Pod重建后pod名称还是一样的。
而Pod IP是变化的,所以是以Pod名称来识别。Pod名称是Pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称 。
创建pc-stateful.yaml文件
1 |
apiVersion: v1 kind: Service metadata: name: service-headliness namespace: dev spec: selector: app: nginx-pod clusterIP: None # 将clusterIP设置为None,即可创建headliness Service type: ClusterIP ports: - port: 80 # Service的端口 targetPort: 80 # Pod的端口 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: pc-statefulset namespace: dev spec: replicas: 3 serviceName: service-headliness selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1 ports: - containerPort: 80 |
创建StatefulSet
1 |
kubectl create -f pc-stateful.yaml 查看StatefulSet kubectl get statefulset pc-statefulset -n dev -o wide 查看Pod kubectl get pod -n dev -o wide 删除StatefulSet kubectl delete -f pc-stateful.yaml |
Deployment和StatefulSet的区别
Deployment和StatefulSet的区别:Deployment没有唯一标识而StatefulSet有唯一标识。
StatefulSet的唯一标识是根据主机名+一定规则生成的。
StatefulSet的唯一标识是
主机名.无头Service名称.命名空间.svc.cluster.local
。
StatefulSet支持两种更新策略:OnDelete和RollingUpdate(默认),其中OnDelete表示删除之后才更新,RollingUpdate表示滚动更新
1 |
updateStrategy: rollingUpdate: # 如果更新的策略是OnDelete,那么rollingUpdate就失效 partition: 2 # 表示从第2个分区开始更新,默认是0 type: RollingUpdate /OnDelete # 滚动更新 |
Pod的资源清单
1 |
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 |