Pod详解
Pod是Kubernetes的最重要概念,每一个Pod都有一个特殊的被称为”根容器”的Pause容器。Pause容器对应的镜
像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。
每个Pod都是应用的一个实例,有专用的IP
一个Pod可以有多个容器,彼此间共享网络和存储资源,每个Pod 中有一个Pause容器保存所有的容器状态, 通过管理pause容器,达到管理pod中所有容器的效果
同一个Pod中的容器总会被调度到相同Node节点,不同节点间Pod的通信基于虚拟二层网络技术实现
普通的Pod和静态Pod
Pod的定义
下面是yaml文件定义的Pod的完整内容
Pod的基本用法
在kubernetes中对运行容器的要求为:容器的主程序需要一直在前台运行,而不是后台运行。应用需要改造成前
台运行的方式。如果我们创建的Docker镜像的启动命令是后台执行程序,则在kubelet创建包含这个容器的pod之
后运行完该命令,即认为Pod已经结束,将立刻销毁该Pod。如果为该Pod定义了RC,则创建、销毁会陷入一个无
限循环的过程中。
Pod可以由1个或多个容器组合而成。由一个容器组成的Pod示例
由两个为紧耦合的容器组成的Pod示例
创建
kubectl create -f xxx.yaml
查看
kubectl get pod/po <Pod_name>
kubectl get pod/po <Pod_name> -o wide
kubectl describe pod/po <Pod_name>
删除
kubectl delete -f pod pod_name.yaml
kubectl delete pod --all/[pod_name]
Pod的分类
Pod有两种类型
普通Pod一旦被创建,就会被放入到etcd中存储,随后会被Kubernetes Master调度到某个具体的Node上并进行绑定,随后该Pod对应的Node上的kubelet进程实例化成一组相关的Docker容器并启动起来。在默认情 况下,当Pod里某个容器停止时,Kubernetes会自动检测到这个问题并且重新启动这个Pod里某所有容器, 如果Pod所在的Node宕机,则会将这个Node上的所有Pod重新调度到其它节点上。
静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod,它们不能通过 API Server进行管理,无法与ReplicationController、Deployment或DaemonSet进行关联,并且kubelet也无法对它们进行健康检查。
Pod生命周期和重启策略
Pod的状态
Pod重启策略
Pod的重启策略包括Always、OnFailure和Never,默认值是Always
常见状态转换
包含两个容器 Running 容器被OOM 杀掉 Running Running Failure
Pod资源配置
每个Pod都可以对其能使用的服务器上的计算资源设置限额,Kubernetes中可以设置限额的计算资源有CPU与Memory两种,其中CPU的资源单位为CPU数量,是一个绝对值而非相对值。Memory配额也是一个绝对值,它的单
位是内存字节数。
Kubernetes里,一个计算资源进行配额限定需要设定以下两个参数:
Requests 该资源最小申请数量,系统必须满足要求
Limits 该资源最大允许使用的量,不能突破,当容器试图使用超过这个量的资源时,可能会被Kubernetes Kill并重启
上述代码表明MySQL容器申请最少0.25个CPU以及64MiB内存,在运行过程中容器所能使用的资源配额为0.5个 CPU以及128MiB内存。
Label详解
Label是Kubernetes系统中另一个核心概念。一个Label是一个key=value的键值对,其中key与value由用户自己指
定。Label可以附加到各种资源对象上,如Node、Pod、Service、RC,一个资源对象可以定义任意数量的Label,
同一个Label也可以被添加到任意数量的资源对象上,Label通常在资源对象定义时确定,也可以在对象创建后动态
添加或删除。
Label的最常见的用法是使用metadata.labels字段,来为对象添加Label,通过spec.selector来引用对象
Label附加到Kubernetes集群中的各种资源对象上,目的就是对这些资源对象进行分组管理,而分组管理的核心就 是Label Selector。Label与Label Selector都是不能单独定义,必须附加在一些资源对象的定义文件上,一般附加在RC和Service的资源定义文件中。
Replication Controller详解
Replication Controller(RC) 是Kubernetes系统中核心概念之一,当我们定义了一个RC并提交到Kubernetes集群中以后,Master节点上的Controller Manager组件就得到通知,定期检查系统中存活的Pod,并确保目标Pod实例的数量刚好等于RC的预期值,如果有过多或过少的Pod运行,系统就会停掉或创建一些Pod.此外我们也可以通过修改 RC的副本数量,来实现Pod的动态缩放功能。
kubectl scale rc nginx --replicas=5
由于Replication Controller与Kubernetes代码中的模块Replication Controller同名,所以在Kubernetes v1.2时, 它就升级成了另外一个新的概念Replica Sets,官方解释为下一代的RC,它与RC区别是:Replica Sets支援基于集合的Label selector,而RC只支持基于等式的Label Selector。我们很少单独使用Replica Set,它主要被Deployment这个 更高层面的资源对象所使用,从而形成一整套Pod创建、删除、更新的编排机制。最好不要越过RC直接创建Pod, 因为Replication Controller会通过RC管理Pod副本,实现自动创建、补足、替换、删除Pod副本,这样就能提高应用的容灾能力,减少由于节点崩溃等意外状况造成的损失。即使应用程序只有一个Pod副本,也强烈建议使用RC来 定义Pod
Replica Set详解
ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的selector(ReplicationController 仅支持等式)。Kubernetes官方强烈建议避免直接使用ReplicaSet,而应该通过Deployment来创建RS和Pod。由于ReplicaSet是ReplicationController的代替物,因此用法基本相同,唯一的区别在于ReplicaSet支持集合式的selector。
Deployment详解
Deployment是Kubenetes v1.2引入的新概念,引入的目的是为了更好的解决Pod的编排问题,Deployment内部使用了Replica Set来实现。Deployment的定义与Replica Set的定义很类似,除了API声明与Kind类型有所区别:
Horizontal Pod Autoscaler
Horizontal Pod Autoscal(Pod横向扩容 简称HPA) 与RC、Deployment一样,也属于一种Kubernetes资源对象。通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的 实现原理。
Kubernetes对Pod扩容与缩容提供了手动和自动两种模式,手动模式通过kubectl scale命令对一个Deployment/RC进行Pod副本数量的设置。自动模式则需要用户根据某个性能指标或者自定义业务指标,并指定Pod副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整。
手动扩容和缩容
kubectl scale deployment frontend --replicas 1
自动扩容和缩容
HPA控制器基本Master的kube-controller-manager服务启动参数 —horizontal-pod-autoscaler-sync-period 定义的时长(默认值为30s),周期性地监测Pod的CPU使用率,并在满足条件时对RC或Deployment中的Pod副 本数量进行调整,以符合用户定义的平均Pod CPU使用率。
Volume详解
Volume是Pod中能够被多个容器访问的共享目录。Kubernetes的Volume定义在Pod上,它被一个Pod中的多个容 器挂载到具体的文件目录下。Volume与Pod的生命周期相同,但与容器的生命周期不相关,当容器终止或重启 时,Volume中的数据也不会丢失。要使用volume,pod需要指定volume的类型和内容( spec.volumes
字段), 和映射到容器的位置(spec.containers.volumeMounts
字段)。 Kubernetes支持多种类型的Volume,包括:
emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、nfs、iscsi、flocker、glusterfs、rbd、cephfs、gitRepo、secret、persistentVolumeClaim、downwardAPI、azureFileVolume、azureDisk、vsphereVolume、Quobyte、PortworxVolume、ScaleIO。
emptyDir
EmptyDir类型的volume创建于pod被调度到某个宿主机上的时候,而同一个pod内的容器都能读写EmptyDir
中的同一个文件。一旦这个pod离开了这个宿主机,EmptyDir中的数据就会被永久删除。所以目前EmptyDir
类型的volume主要用作临时空间,比如Web服务器写日志或者tmp文件需要的临时目录。yaml示例如下
hostPath
HostPath属性的volume使得对应的容器能够访问当前宿主机上的指定目录。例如,需要运行一个访问Docker系统目录的容器,那么就使用/var/lib/docker目录作为一个HostDir类型的volume;或者要在一个容器内部运行CAdvisor,那么就使用/dev/cgroups目录作为一个HostDir类型的volume。一旦这个pod离开了这个宿主机,HostDir中的数据虽然不会被永久删除,但数据也不会随pod迁移到其他宿主机上。因此,需要 注意的是,由于各个宿主机上的文件系统结构和内容并不一定完全相同,所以相同pod的HostDir可能会在不 同的宿主机上表现出不同的行为。yaml示例如下:
nfs
NFS类型的volume。允许一块现有的网络硬盘在同一个pod内的容器间共享。yaml示例如下:
8. Namespace详解
Namespace在很多情况下用于实现多用户的资源隔离,通过将集群内部的资源对象分配到不同的Namespace中,
形成逻辑上的分组,便于不同的分组在共享使用整个集群的资源同时还能被分别管理。Kubernetes集群在启动
后,会创建一个名为”default”的Namespace,如果不特别指明Namespace,则用户创建的Pod,RC,Service都将
被系统 创建到这个默认的名为default的Namespace中。
Namespace创建
Namespace查看
kubectl get pods --namespace=development
Service 详解
Service是Kubernetes最核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地
址,并且将请求负载分发到后端的各个容器应用上。
Service的定义
yaml格式的Service定义文件
Service的基本用法
一般来说,对外提供服务的应用程序需要通过某种机制来实现,对于容器应用最简便的方式就是通过TCP/IP机制及
监听IP和端口号来实现。创建一个基本功能的Service
我们可以通过kubectl get pods -l app=mywebapp -o yaml | grep podIP来获取Pod的IP地址和端口号来访问Tomcat服务,但是直接通过Pod的IP地址和端口访问应用服务是不可靠的,因为当Pod所在的Node发生故障时, Pod将被kubernetes重新调度到另一台Node,Pod的地址会发生改变。我们可以通过配置文件来定义Service,再 通过kubectl create来创建,这样可以通过Service地址来访问后端的Pod.
多端口Service
有时一个容器应用也可能需要提供多个端口的服务,那么在Service的定义中也可以相应地设置为将多个端口对应
到多个应用服务。
外部服务Service
在某些特殊环境中,应用系统需要将一个外部数据库作为后端服务进行连接,或将另一个集群或Namespace中的 服务作为服务的后端,这时可以通过创建一个无Label Selector的Service来实现。