跳到主要内容

k8s基本概念

前言

使用docker compose可以轻松高效的管理容器,定义和运行多个容器,但是无法同时管理多台机器。

k8s可以管理大规模的集群,能够像控制一台答疑的机器一样控制整个集群。

k8s得益于docker的特性,服务的创建和销毁非常快速简单,使应用的发布、重启、扩缩容能够自动化。

k8s集群有两种角色,master和node

  • master是集群的控制节点,负责管理整个集群,像应用的调度、更新、扩缩容等

  • node就是具体干活的,上面运行着docker服务和kubelet服务(一个k8s组件),接收到master下发的任务后,用docker去运行指定的应用。

Deployment(应用管理)

有一个k8s集群后,通过k8s的Deployment配置文件去描述应用。比如应用名、镜像名、运行的实例数、cpu和内存资源配额等。然后使用kubectl命令,跟k8s的master通过api通信,最终完成应用管理

kubectl create -f app.yaml

创建好应用之后,由k8s来保证应用处于运行状态,当实例失败或者node宕机,k8s会自动发现并在新的node上调度一个新实例。

Pod(k8s最小调度单位)

创建一个Deployment后,Node上就会启动相应数量的Pod,作为k8s集群的最小调度单位。

Pod是一组容器的集合(当然可以只有一个),同一个pod里的容器可以:

  • 通过volume共享存储

  • 有相同的网络空间,即有一样的ip和网络设置

  • 容器间互相了解,知道其他容器的镜像、端口等等

Service Discovery

Deployment创建了,Pod也运行了,如何访问应用。

最简单就是podid+port可以访问,如果实例比较多,拿到所有pod的ip和port,配置到负载均衡。但是pod在失败、node宕机、更新服务时,都会重建pod,每个pod都有自己的ip,所以pod的ip不稳定,会经常变化。

这里k8s有个新的service概念,Servcie是一个Pods的逻辑集合,不管Deployment的Pod有多少和如何变化,service总能发现并维护好他的Pod列表。

k8s通过给Pod打标签,一个Service可以只负责一个Deployment的Pod,也可以负责多个Deployment的Pod,而不用把Deployment和Service做一一对应。

Service 主要由三种常用类型

  • 仅用与集群内部通信的 ClusterIP 类型

  • 接入集群外部请求的 NodePort 类型,它工作于每个节点的主机 IP 之上(外部的负载均衡可以配置node的部分或者全部节点,来转发请求到Service)

  • LoadBalacer 类型,它可以把外部请求负载均衡至多个 Node 的主机IP的 NodePort 之上

三种类型中,每一种都以前一种为基础才能实现,而且第三种类型中的 LoadBalacer 需要协同集群外部的组件才能实现,并且此外部组建并不接受 Kubernetes 的管理

service提供多种入口:

  • ClusterIP:通过集群内部IP地址暴露服务,此地址仅在集群内部可达,而无法被集群外部的客户端访问,Service在集群内的唯一ip,是一种虚拟ip,通过这个ip在集群内能均衡访问到所有的后端Pod,避免pod实例的变化对外部的影响。

  • NodePort:Service会在集群每个Node上启动一个端口,可以通过任意Node的这个端口访问到Pod

  • LoadBalancer:外部的负载均衡器把请求转发给NodeIP:NodePort

  • ExternalName:此类型并非定义由Kubernetes集群提供的服务,而是把集群外部的某服务以DNS CNAME记录的方式映射到集群内,从而让集群内的Pod资源能够访问外部的Service的一种实现方式(通过spec.externalName设置),因此,这种类型的Service没有ClusterIP和NodePort,也没有标签选择器用于选择Pod资源,因此也不会有Enpoints存在

RollingUpdate(滚动升级)

k8s里典型的服务升级方案,主要思路是一遍增加新版本应用的实例,一遍减少旧版本应用的实例,直到全部替换为新版本,在整个升级过程中,服务一直处于可用状态,并且可以在任意时刻回滚到旧版本。

部署方式

官方提供3中部署方式