< Back

k8s

Pod

通常每个pod会放一个容器(应用),虽然也可以放多个容器,但是那一般都是有一个主容器,其他一些helper容器或者辅助服务的情况的时候。

每个pod会有他自己的ip地址,不是容器,而是pod。pod之间就通过这个ip地址来交流。但是pod还有一个重要的概念就是ephemeral,就是说他们会很容易挂掉。而当一个pod挂掉后会被重新启动一个新的,并且会被分配一个新的ip。这样的话就很不方便,你是通过ip来通信的,那一旦当pod被重启一个新的后,你就得去做相应调整。所以就有了service。

每个pod都有一个service,service有永久的ip地址,pod的生命周期不会影响到service,pod挂掉后,service和ip都不会变,所以各个pod间通过service来通信就好了。

同时service还有load balance的功能,会把收到的请求给到最空闲的pod,也就是一个副本。

img

同时,这个副本也不需要手动去创建,而是定义一个blueprint,指定多少个副本pod,这个blueprint或者组件叫做Deployment。实际工作中,你不会去创建pod,而是创建Deployment。

有多个副本的话,那么数据库这种需要持久化的就有要面对一个问题,单个数据库容器通过volume能解决,如果如果的话要怎么办。然后就有了StatefulSet这个组件,专门用来做这个事。当有想mysql,mongodb等有状态应用需要创建的时候就要StatefulSet来创建而不是Deployment。但是部署StatefulSet不是个容易的事情,所以这就是为什么通常都是把数据库这种放到k8s里面来做。k8s里面专门做无状态应用的管理就好了。

pod分成两类:自主式pod和控制器管理的pod(被控制的和不被控制的pod)。这并不是官方的说法,是别人的总结。不被控制器管理的pod在死亡后不会被重新创建。

定义一个pod的时候,有一个叫做pause的容器一定会被启动,在同一个pod里的容器可以直接通过localhost访问到,因为容器共享pause的网络栈,所以,同一个pod里的容器端口不能冲突

如果pause挂载了一个存储卷,那么pod里其他容器也可以访问到,也即是说pod里的容器既共享网络栈也共享存储卷

pod控制器类型

ReplicationController:用来确保容器应用的副本数始终保持在用户定义的副本数。即如果有容器异常退出,会自动创建新的pod,而如果多出来的pod也会自动被回收掉。新版的k8s建议使用ReplicaSet取代RC。

ReplicaSet:跟RC没有本质不同,只是名字不一样,并且RS支持集合式的selector,就是说比如给pod打各种标签比如版本号,然后你可以定义说当版本号到多少时要做什么操作,RC不支持这种方式。

虽然RS可以独立使用,但是一般还是建议使用Deployment来自动管理RS,这样就无需担心跟其他机制不兼容的问题,比如RS不支持rolling update,但是Deployment支持。

Deployment在创建出来后会去创建一个RS,然后再去创建pod。如果有一天让Deployment更新版本,他会先去创建一个新的RS,然后在这个RS下创建新版本的pod,创建好一个就从先前的RS中删除一个旧的,达到滚动更新的目的。

img

Horizontal Pod Autoscaling(HPA):平滑扩展。仅适用于Deployment和RS。比如基于RS定义一个HPA,设定一些参数,可以自动的加减RS下的pod数量。

StatefulSet:为了解决有状态服务的问题

DaemonSet:确保全部(或者一些)Node上运行一个Pod副本。为什么说“一些”?因为如果给一些Node打上污点,那么这些Node是不被调度的,这些Node就被创建Pod,但是正常情况下是全部的。

Job:负责批处理任务,即仅执行一次的任务,他保证批处理任务的一个或者多个Pod成功结束。比方说有一个备份数据的任务,这部分代码放在一个Pod里,Job负责来执行这些代码,这个事情本来也可以直接在Linux中运行,备份程序有可能异常退出,而Job可以检测到是异常退出然后重新执行一遍,直到成功为止,或者可以设置说要连续成功退出两遍才算成功。

Cron Job:管理基于时间的Job。

K8s Architecture

Node

node是实际工作的地方,所以也叫做worker。一个node可以有多个pod。每个node都有三个必须要安装的进程:

  • 容器运行时(docker 或者其他技术)
  • Kubelet。能和容器以及node两者进行交互,
  • Kubeproxy。负责转发service过来的请求给pod

MasterNode

和普通的node不一样,master有四个必须要安装的。

  • Api server。大概就是和cluster交互的一个接口吧。
  • Scheduler。比如当api server接到请求要添加一个pod的时候,它会负责把这个pod添加到和合适的node里,通过查看每个node所用的资源的多少。但是实际来做这个事的是node上的Kubelet。
  • Controller manager。检测集群的状态,比如有pod挂掉的时候,他会通知Scheduler,然后到Kubelet,然后重启pod。
  • etcd。集群的键值存储,集群的一些状态的变化都会被写入到这里。是集群的大脑,之所以这么说,是因为Scheduler和Controller manager都是因为这些数据才能工作的。Scheduler如何知道有多少资源可用,Controller manager如何知道集群的状态。api server如何知道集群是否健康。

编辑Deployment的配置文件后,所有的东西都会被自动更新。

YAML Configuration File

主要分为三个部分:metadata,specification,以及status。

比较特殊的就是status,因为这个是k8s自己生成的,他会不断的比较期望的状态和目前实际的状态。比如status显示只有一个副本,但是spec里面写的是两个,那么k8s就知道出了点问题,需要修复。k8s如何获取当前的状态呢?etcd。

Ingress

k8s有pod,有service,当你要从浏览器来访问时,可以通过一个external service,但是这只适用于测试阶段,你想要快速的验证一个什么东西的时候。然后就有了ingress,你可以不用暴露你整个服务的ip,当有请求过来的时候,首先是到ingress,然后再转到internal service,然后到pod。

ingress可以配置一个Default backend,用于在收到的请求没有匹配到服务的时候。比如返回一个错误页面。

Helm

k8s的包管理工具,类似apt,yum这样的。很多集群的搭建工作都是差不太多的,所以有人会发布他自己的yaml文件,然后你就能重用这个文件。