k8s是什么?
k8s是一个全新的基于容器技术的分布式架构领先方案。是负责自动化运维管理多个Docker程序的集群。传统的后端部署办法:把jar包(war包、可执行二进制文件、配置文件等)放到服务器上,接着运行启动脚本把程序跑起来,同时启动守护脚本定期检查程序运行状态、必要的话重新拉起程序。其中最大的一个问题在于:**如果服务的请求量上来,已部署的服务响应不过来怎么办?**传统的做法往往是,如果请求量、内存、CPU超过阈值做了告警,运维马上再加几台服务器,部署好服务之后,接入负载均衡来分担已有服务的压力。
问题出现了:从监控告警到部署服务,中间需要人力介入,那么,有没有办法自动完成服务的部署、更新、卸载和扩容、缩容呢?这,就是K8S要做的事情:自动化运维管理Docker(容器化)程序。
下面这张图是Kubernetes的架构图。
Kubernetes节点
部署 Kubernetes 时,将获得一个集群。一个 Kubernetes 集群由一组工作机器组成,称为节点,运行容器化应用程序。每个集群至少有一个工作节点。
在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。
Kubernetes节点有运行应用容器必备的服务,而这些都是受Master的控制。
每次个节点上当然都要运行Docker。Docker来负责所有具体的映像下载和容器运行。
Kubernetes主要由以下几个核心组件组成:
- etcd保存了整个集群的状态;
- apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
- controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
- kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
- Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
- kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
除了核心组件,还有一些推荐的Add-ons:
- kube-dns负责为整个集群提供DNS服务
- Ingress Controller为服务提供外网入口
- Heapster提供资源监控
- Dashboard提供GUI
- Federation提供跨可用区的集群
- Fluentd-elasticsearch提供集群日志采集、存储与查询
k8s基本概念和术语
1、Master
Master是kubernetes集群的"大脑",是集群控制节点,负责整个集群的管理和控制。基本上接收Kubernetes的所有控制命令,master负责具体的执行过程。Master节点通常占据一个服务器(高可用部署建议用3台服务器)。一旦master宕机或者不可用,那么对集群内容器应用的管理都将失效。
运行在master上的组件:
- etcd: 高可用k-v存储,用于持久化资源对象(node、service、pod、rc、namespace等)
- Kubernetes API Server(kube-apiserver):Kubernetes API,集群的统一入口,各组件协调者,以HTTP API提供接口服务,Kubernetes里所有资源的增删改查和监听操作都交给APIServer处理后再提交给Etcd存储。
- Kubernetes Controller Manager(kube-controller-manager):Kubernetes里所有资源对象的自动化控制中心,可以理解为资源对象的大总管。
- kube-scheduler:负责资源调度(Pod调度)的进程。
2、Node
具体"干活"的,工作负载节点,在Kubernetes集群中除了master节点外的机器被称为Node。每个Node都会被Master分配一些工作负载(Docker容器),当某个Node宕机时,其上的工作负载会被Master自动转移到其他Node节点上。
运行在Node上的组件:
- kubelet:kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,负责Pod对应容器的创建、启停等任务。同时与Master密切协作,实现集群管理的基本功能,获取Node节点上Pod的运行状态等
- kube-proxy:在Node节点上实现Pod网络代理,实现Kubernetes Service的通信和负载均衡机制的重要组件。
- docker:Docker引擎,负责本机的容器的创建和管理工作
3、Pod
- Pod是K8s中最小的单元
- 一组容器的集合
- 共享网络【一个Pod中的所有容器共享同一网络】
- 生命周期是短暂的(服务器重启后,就找不到了)
4、Label
标签,一个Label是一个key=value的键值对。Label可以被附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label。
5、Controller
- 确保预期的pod副本数量【ReplicaSet】
- 无状态应用部署【Deployment】
- 无状态就是指,不需要依赖于网络或者ip
- 有状态应用部署【StatefulSet】
- 有状态需要特定的条件
- 确保所有的node运行同一个pod 【DaemonSet】
- 一次性任务和定时任务【Job和CronJob】
6、Replica Set
ReplicaSet 实现了 Pod 的多副本管理。使用 Deployment 时会自动创建 ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod 的多个副本,所以我们通常不需要直接使用 ReplicaSet。RS是新一代RC。
7、部署(Deployment)
- 定义一组Pod副本数目,版本等
- 通过控制器【Controller】维持Pod数目【自动回复失败的Pod】
- 通过控制器以指定的策略控制版本【滚动升级、回滚等】
8、服务(Service)
- 定义一组pod的访问规则
- Pod的负载均衡,提供一个或多个Pod的稳定访问地址
- 支持多种方式【ClusterIP、NodePort、LoadBalancer】
可以用来组合pod,同时对外提供服务
9、存储卷(Volume)
K8s集群中的存储卷跟Docker的存储卷有些类似,只不过Docker的存储卷作用范围为一个容器,而K8s的存储卷的生命周期和作用范围是一个Pod。每个Pod中声明的存储卷由Pod中的所有容器共享。
- 声明在Pod容器中可访问的文件目录
- 可以被挂载到Pod中一个或多个容器指定路径下
- 支持多种后端存储抽象【本地存储、分布式存储、云存储】
10、Container 容器
本文中提到的镜像Image、容器Container,都指代了Pod下的一个container。关于K8S中的容器,在2.1Pod章节都已经交代了,这里无非再啰嗦一句:一个Pod内可以有多个容器container。
在Pod中,容器也有分类,对这个感兴趣的同学欢迎自行阅读更多资料:
- 标准容器 Application Container。
- 初始化容器 Init Container。
- 边车容器 Sidecar Container。
- 临时容器 Ephemeral Container。
一般来说,我们部署的大多是标准容器( Application Container)。
11、命名空间(Namespace)
命名空间,逻辑隔离
- 一个集群内部的逻辑隔离机制【鉴权、资源】
- 每个资源都属于一个namespace
- 同一个namespace所有资源不能重复
- 不同namespace可以资源名重复
API
我们通过Kubernetes的API来操作整个集群
同时我们可以通过 kubectl 、ui、curl 最终发送 http + json/yaml 方式的请求给API Server,然后控制整个K8S集群,K8S中所有的资源对象都可以采用 yaml 或 json 格式的文件定义或描述
如下:使用yaml部署一个nginx的pod
完整流程
- 通过Kubectl提交一个创建RC(Replication Controller)的请求,该请求通过APlserver写入etcd
- 此时Controller Manager通过API Server的监听资源变化的接口监听到此RC事件
- 分析之后,发现当前集群中还没有它所对应的Pod实例
- 于是根据RC里的Pod模板定义一个生成Pod对象,通过APIServer写入etcd
- 此事件被Scheduler发现,它立即执行执行一个复杂的调度流程,为这个新的Pod选定一个落户的Node,然后通过API Server讲这一结果写入etcd中
- 目标Node上运行的Kubelet进程通过APiserver监测到这个"新生的Pod.并按照它的定义,启动该Pod并任劳任怨地负责它的下半生,直到Pod的生命结束
- 随后,我们通过Kubectl提交一个新的映射到该Pod的Service的创建请求
- ControllerManager通过Label标签查询到关联的Pod实例,然后生成Service的Endpoints信息,并通过APIServer写入到etod中,
- 接下来,所有Node上运行的Proxy进程通过APIServer查询并监听Service对象与其对应的Endponts信息,建立一个软件方式的负载均衡器来实现Service访问到后端Pod的流量转发功能