Pod

pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图:

在对pod的用法进行说明之前,有必要先对docker容器进行说明

在使用docker时,可以使用docker run命令创建一个容器,而在kubernetes集群中对长时间运行容器的要求是:

  • 主程序需要一直在前台执行

如果我们创建的docker镜像的启动命令是后台执行程序,例如Linux脚本:

nohup ./start.sh &

那么kubelet在创建这个Pod执行完这个命令后,会认为这个Pod执行完毕,从而进行销毁pod,如果pod定义了ReplicationController,那么销毁了还会在创建,继续执行上述的命令然后又销毁,然后又重建,这样就会陷入恶性循环,这也是为什么执行的命令要运行在前台的原因,这一点一定要注意

Pod生命周期和重启策略

Pod的重启策略(RestartPolicy):

  • Always:当容器失败时,由kubelet自动重启该容器
  • OnFailure:当容器终止运行且退出代码不为0的时候,由kubelet自动重启
  • Never:不论容器运行状态如何,kubelet永远都不会重启该容器

Pod的重启策略和控制器息息相关,每种控制器对Pod的重启策略如下:

  • RC和DaemonSet:必须设置为Always,需要保证该容器持续运行
  • Job:OnFailure和Never,确保容器执行完毕后不在重启
  • kubelet:在Pod失效时自动重启它,不论将RestartPolicy设置成什么值,也不会对Pod进行健康检查

我们简单介绍完kubernetes的逻辑结构之后我们来看一下k8s控制器资源,k8s控制器资源分很多种,有replication controller,deployment,Horizontal pod autoscaler,statefulSet,daemonSet,job等...,接下来我们来详细分析一下下面资源的使用场景和区别

replication Controller控制器

replication controller简称RC,是kubernetes系统中的核心概念之一,简单来说,它其实定义了一个期望的场景,即声明某种pod的副本数量在任意时刻都复合某个预期值,所以RC的定义包含以下部分:

  • pod期待的副本数量
  • 用于筛选目标pod的Label Selector
  • 当pod的副本数量小于期望值时,用于创建新的pod的pod模板(template)

下面是一个完整的RC定义的例子,即确保拥有app=mynginx标签的这个pod在整个kubernetes集群中始终只有一个副本,红色字体一定要一直,因为我们的控制器就是根据标签筛选出来的(因为pod的ip和pod名字都会变化):

[root@master ~]# vim nginx.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
namespace: default
spec:
replicas:
selector:
app: mynginx
template:
metadata:
labels:
app: mynginx
spec:
containers:
- name: mycontainer
image: lizhaoqwe/nginx:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort:

在我们定义了一个RC并将其提交到kubernetes集群中后,master上的controller Manager组件就得到了通知,定期巡检系统中当前存货的目标pod,并确保目标pod实力数量刚好等于此RC的期望值,如果多余期望值,则停掉一些,如果少于期望值会再创建一些。

以下面3个Node节点的集群为例,说明kubernetes是如何通过RC来实现pod副本数量自动控制的机制,我们创建2个pod运行redis-slave,系统可能会再两个节点上创建pod,如下图

假设Node2上的pod意外终止,则根据RC定义的replicas数量1,kubernetes将会自动创建并启动两个新的pod,以保证在整个集群中始终有两个redis-slave Pod运行,如下图所示,系统可能选择Node3或者Node1来创建新的pod

此外,我们还可以通过修改RC的副本数量,来实现Pod的动态扩容和缩容

[root@master ~]# kubectl scale --replicas= rc myweb
replicationcontroller/myweb scaled

结果如下

这里需要注意的是,删除RC并不会影响通过该RC已创建好的pod,为了删除所有pod,可以设置replicas的值为0,然后更新该RC,另外,kubectl提供了stop和delete命令来一次性删除RC和RC控制的全部Pod

ReplicaSet

上一阶段讲过了ReplicationController控制器之后,相信大家对其已经了解了,ReplicaSet控制器其实就是ReplicationController的升级版,官网解释为下一代的“RC”,ReplicationController和ReplicaSet的唯一区别是ReplicaSet支持基于集合的Label selector,而RC只支持基于等式的Label Selector,这使得ReplicaSet的功能更强,下面等价于之前的RC例子的ReokucaSet的定义

[root@master ~]# vim replicaSet.yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: myweb
namespace: default
spec:
replicas:
selector:
matchLabels:
app: mynginx
matchExpressions:
- {key: app, operator: In, values: [mynginx]}
template:
metadata:
labels:
app: mynginx
spec:
containers:
- name: mycontainer
image: lizhaoqwe/nginx:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort:

kubectl命令行工具适用于RC的绝大部分命令同样适用于ReplicaSet,此外,我们当前很少单独适用ReplicaSet,它主要被Deployment这个更高层的资源对象所使用,从而形成一整套Pod创建,删除,更新的编排机制,我们在使用Deployment时无需关心它是如何维护和创建ReplicaSet的,这一切都是自动发生的

最后,总结一下RC(ReplicaSet)的一些特性和作用:

  • 在绝大多数情况下,我们通过定义一个RC实现Pod的创建及副本数量的自动控制
  • 在RC里包括完整的Pod定义模板
  • RC通过Label Selector机制实现对Pod副本的自动控制
  • 通过改变RC里的Pod副本数量,可以实现Pod的扩容和缩容
  • 通过改变RC里Pod模板中的镜像版本,可以实现滚动升级

Deployment

Deployment是kubernetes在1.2版本中引入的新概念,用于更好的解决Pod的编排问题,为此,Deployment在内部使用了ReplicaSet来实现目的,我们可以把Deployment理解为ReplicaSet的一次升级,两者的相似度超过90%

Deployment的使用场景有以下几个:

  • 创建一个Deployment对象来生成对应的ReplicaSet并完成Pod副本的创建
  • 检查Deployment的状态来看部署动作是否完成(Pod副本数量是否达到了预期的值)
  • 更新Deployment以创建新的Pod(比如镜像升级)
  • 如果当前Deployment不稳定,可以回滚到一个早先的Deployment版本
  • 暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后在恢复Deployment,进行新的发布
  • 扩展Deployment以应对高负载
  • 查看Deployment的状态,以此作为发布是否成功的纸币哦
  • 清理不在需要的旧版本ReplicaSet

除了API生命与Kind类型有区别,Deployment的定义与Replica Set的定义很类似,我们这里还是以上面为例子

apiVersion: extensions/v1beta1          apiVersion: apps/v1
kind: ReplicaSet kind: Deployment

执行文件

[root@master ~]# kubectl apply -f deploy.yaml
deployment.apps/myweb created

查看结果

[root@master ~]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
myweb / 5m5s

解释一下上面的显示

NAME:你的deployment控制器的名字

READY:已经准备好的Pod个数/所期望的Pod个数

UP-TO-DATE:最新版本的Pod数量,用于在执行滚动升级时,有多少个Pod副本已经成功升级

AVAILABLE:当前集群中可用的Pod数量,也就是集群中存活的Pod数量

StatefulSet

在kubernetes系统中,Pod的管理对象RC,Deployment,DaemonSet和Job都面向无状态的服务,但现实中有很多服务时有状态的,比如一些集群服务,例如mysql集群,集群一般都会有这四个特点:

  1. 每个节点都是有固定的身份ID,集群中的成员可以相互发现并通信
  2. 集群的规模是比较固定的,集群规模不能随意变动
  3. 集群中的每个节点都是有状态的,通常会持久化数据到永久存储中
  4. 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损

如果你通过RC或Deployment控制Pod副本数量来实现上述有状态的集群,就会发现第一点是无法满足的,因为Pod名称和ip是随机产生的,并且各Pod中的共享存储中的数据不能都动,因此StatefulSet在这种情况下就派上用场了,那么StatefulSet具有以下特性:

  • StatefulSet里的每个Pod都有稳定,唯一的网络标识,可以用来发现集群内的其它成员,假设,StatefulSet的名称为fengzi,那么第1个Pod叫fengzi-0,第2个叫fengzi-1,以此类推
  • StatefulSet控制的Pod副本的启停顺序是受控的,操作第N个Pod时,前N-1个Pod已经是运行且准备状态
  • StatefulSet里的Pod采用稳定的持久化存储卷,通过PV或PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了保证数据的安全)

StatefulSet除了要与PV卷捆绑使用以存储Pod的状态数据,还要与Headless,Service配合使用,每个StatefulSet定义中都要生命它属于哪个Handless Service,Handless Service与普通Service的关键区别在于,它没有Cluster IP

一、创建pv

[root@master ~]# cat createpv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
spec:
nfs:
path: /share_v1
server: 192.168.254.14
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02
spec:
nfs:
path: /share_v2
server: 192.168.254.14
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv03
spec:
nfs:
path: /share_v3
server: 192.168.254.14
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv04
spec:
nfs:
path: /share_v4
server: 192.168.254.14
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv05
spec:
nfs:
path: /share_v5
server: 192.168.254.11
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 2Gi

二、创建pvc和statfulset控制器管理的pod

[root@master ~]# cat state.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
namespace: default
labels:
app: myapp
spec:
ports:
- name: http
port:
clusterIP: None
selector:
app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: myapp-svc
replicas:
selector:
matchLabels:
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: liwang7314/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort:
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: myappdata
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

三、创建完毕后观察

[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp- / Running 8s
myapp- / Running 5s
myapp- / Running 3s

DemonSet

在每一个node节点上只调度一个Pod,因此无需指定replicas的个数,比如:

  • 在每个node上都运行一个日志采集程序,负责收集node节点本身和node节点之上的各个Pod所产生的日志
  • 在每个node上都运行一个性能监控程序,采集该node的运行性能数据
[root@localhost ~]# cat daemon.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-cloud-logging
namespace: kube-system
labels:
k8s-app: fluentd-cloud-logging
spec:
selector:
matchLabels:
k8s-app: fluentd-cloud-logging
template:
metadata:
namespace: kube-system
labels:
k8s-app: fluentd-cloud-logging
spec:
containers:
- name: fluentd-cloud-logging
image: kayrus/fluentd-elasticsearch:1.20
resources:
limits:
cpu: 100m
memory: 200Mi
env:
- name: FLUENTD_ARGS
value: -q
volumeMounts:
- name: varlog
mountPath: /var/log
readOnly: false
- name: containers
mountPath: /var/lib/docker/containers
readOnly: false
volumes:
- name: containers
hostPath:
path: /usr
- name: varlog
hostPath:
path: /usr/sbin

查看pod所在的节点

[root@localhost ~]# kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-bccdc95cf-8sqzn / Running 2d7h 10.244.0.6 master <none> <none>
coredns-bccdc95cf-vt8nz / Running 2d7h 10.244.0.7 master <none> <none>
etcd-master / Running 2d7h 192.168.254.13 master <none> <none>
fluentd-cloud-logging-6xx4l / Running 4h24m 10.244.2.7 node2 <none> <none>
fluentd-cloud-logging-qrgg6 / Rruning 4h24m 10.244.1.7 node1 <none> <none>
kube-apiserver-master / Running 2d7h 192.168.254.13 master <none> <none>
kube-controller-manager-master / Running 2d7h 192.168.254.13 master <none> <none>
kube-flannel-ds-amd64-c97wh / Running 2d7h 192.168.254.12 node1 <none> <none>
kube-flannel-ds-amd64-gl6wg / Running 2d7h 192.168.254.13 master <none> <none>
kube-flannel-ds-amd64-npsqf / Running 2d7h 192.168.254.10 node2 <none> <none>
kube-proxy-gwmx8 / Running 2d7h 192.168.254.13 master <none> <none>
kube-proxy-phqk2 / Running 2d7h 192.168.254.12 node1 <none> <none>
kube-proxy-qtt4b / Running 2d7h 192.168.254.10 node2 <none> <none>
kube-scheduler-master / Running 2d7h 192.168.254.13 master <none> <none>

k8s控制器资源(五)的更多相关文章

  1. k8s控制器资源

    k8s控制器资源   Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前 ...

  2. Kubernetes K8S之资源控制器StatefulSets详解

    Kubernetes的资源控制器StatefulSet详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...

  3. Kubernetes K8S之资源控制器Daemonset详解

    Kubernetes的资源控制器Daemonset详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C/ ...

  4. Kubernetes K8S之资源控制器Job和CronJob详解

    Kubernetes的资源控制器Job和CronJob详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...

  5. k8s核心资源之Pod概念&入门使用讲解(三)

    目录 1. k8s核心资源之Pod 1.1 什么是Pod? 1.2 Pod如何管理多个容器? 1.3 Pod网络 1.4 Pod存储 1.5 Pod工作方式 1.5.1 自主式Pod 1.5.2 控制 ...

  6. K8s容器资源限制

    在K8s中定义Pod中运行容器有两个维度的限制: 1. 资源需求:即运行Pod的节点必须满足运行Pod的最基本需求才能运行Pod. 如: Pod运行至少需要2G内存,1核CPU    2. 资源限额: ...

  7. k8s之资源限制以及探针检查

    k8s之资源限制以及探针检查 一.资源限制 1. 资源限制的使用 当定义Pod时可以选择性地为每个容器设定所需要的资源数量.最常见的可设定资源是CPU和内存大小,以及其他类型的资源. 2. reuqe ...

  8. K8s控制器

    K8s控制器 POD分类 #自主式pod:退出后,不会被创建 #控制器管理的pod:在控制器的生命周期内,始终位置pod的副本数 控制器类型 ReplicationController和Replica ...

  9. 8.深入k8s:资源控制Qos和eviction及其源码分析

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com,源码版本是1.19 又是一个周末,可以愉快的坐下来静静的品味一段源码,这一篇涉及到资源的 ...

随机推荐

  1. zz深度学习论文合集大全

        Pull requestsIssues Marketplace Explore             Learn Git and GitHub without any code! Using ...

  2. MySQL单表查询 条件查询,分组

    目录 1 where 条件查询 between like not in 2 group by 分组 聚合函数:max min sum avg count 3 having 过滤 4 distinct ...

  3. calc()在less中编译报错

    calc()对大家来说,或许很陌生,不太会相信calc()是css中的部分.因为看其外表像个函数,既然是函数为何又出现在CSS中呢? calc() 函数用于动态计算长度值. 需要注意的是,运算符前后都 ...

  4. 项目:git+gitlab+jenkins+ansible上线网站

    项目需求 1. 在gitlab中创建一个项目 nginxinstall2. 编写playbook,实现一键部署nginx.部署一个静态测试页.测试部署结果要求: 部署nginx 端口:83 运行身份: ...

  5. Visual Studio 调试系列5 检查变量(使用自动窗口和局部变量窗口)

    系列目录     [已更新最新开发文章,点击查看详细] 在调试时,“自动变量”和“局部变量”窗口会显示变量值. 仅在调试会话期间,这两个窗口才可用. “自动变量”窗口显示当前断点周围使用的变量. “局 ...

  6. kubernetes实战(九):k8s集群动态存储管理GlusterFS及使用Heketi扩容GlusterFS集群

    1.准备工作 所有节点安装GFS客户端 yum install glusterfs glusterfs-fuse -y 如果不是所有节点要部署GFS管理服务,就在需要部署的节点上打上标签 [root@ ...

  7. [数据结构 - 第8章] 查找之哈希表(C语言实现)

    首先是需要定义一个哈希表的结构以及一些相关的常数.其中 HashTable 就是哈希表结构.结构当中的 elem 为一个动态数组. #define HASHSIZE 12 // 定义哈希表长为数组的长 ...

  8. PyQt5笔记之布局管理

    代码:界面与逻辑分离 这是使用Designer做出的GUI,然后通过转换得到的Py代码.(界面文件) # -*- coding: utf-8 -*- # Form implementation gen ...

  9. 【linux】CentOS 查看系统时间,修改时区

    ===============CentOS 7.6================ 1.查看系统时间 date 查看当前系统时间以及时区结果是: Mon Jul 8 09:23:31 UTC 2019 ...

  10. Java反射获取泛型类型

    本文链接:https://blog.csdn.net/hongxingxiaonan/article/details/49202613 在Java反射技术的应用中,取得一个类的成员.方法和构造函数相对 ...