Kubernetes的整体架构
Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项。
- Master Node:作为控制节点,对集群进行调度管理;Master Node由API Server、Scheduler、Cluster State Store和Controller-Manger Server所组成;
- Worker Node:作为真正的工作节点,运行业务应用的容器;Worker Node包含kubelet、kube proxy和Container Runtime;
- kubectl:用于通过命令行与API Server进行交互,而对Kubernetes进行操作,实现在集群中进行各种资源的增删改查等操作;
- Add-on:是对Kubernetes核心功能的扩展,例如增加网络和网络策略等能力。
- repliceation 用于伸缩副本数量
- endpoint 用于管理网络请求
- scheduler 调度器
1、准备好一个包含应用程序的Deployment的yml文件,然后通过kubectl客户端工具发送给ApiServer。
2、ApiServer接收到客户端的请求并将资源内容存储到数据库(etcd)中。
3、Controller组件(包括scheduler、replication、endpoint)监控资源变化并作出反应。
4、ReplicaSet检查数据库变化,创建期望数量的pod实例。
5、Scheduler再次检查数据库变化,发现尚未被分配到具体执行节点(node)的Pod,然后根据一组相关规则将pod分配到可以运行它们的节点上,并更新数据库,记录pod分配情况。
6、Kubelete监控数据库变化,管理后续pod的生命周期,发现被分配到它所在的节点上运行的那些pod。如果找到新pod,则会在该节点上运行这个新pod。
7、kuberproxy运行在集群各个主机上,管理网络通信,如服务发现、负载均衡。例如当有数据发送到主机时,将其路由到正确的pod或容器。对于从主机上发出的数据,它可以基于请求地址发现远程服务器,并将数据正确路由,在某些情况下会使用轮训调度算法(Round-robin)将请求发送到集群中的多个实例。
创建Pod的整个流程,时序图如下:
1. 用户提交创建Pod的请求,可以通过API Server的REST API ,也可用Kubectl命令行工具,支持Json和Yaml两种格式;
2. API Server 处理用户请求,存储Pod数据到Etcd;
3. Schedule通过和 API Server的watch机制,查看到新的pod,尝试为Pod绑定Node;
4. 过滤主机:调度器用一组规则过滤掉不符合要求的主机,比如Pod指定了所需要的资源,那么就要过滤掉资源不够的主机;
5. 主机打分:对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等;
6. 选择主机:选择打分最高的主机,进行binding操作,结果存储到Etcd中;
7. kubelet根据调度结果执行Pod创建操作: 绑定成功后,会启动container, docker run, scheduler会调用API Server的API在etcd中创建一个bound pod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步bound pod信息,一旦发现应该在该工作节点上运行的bound pod对象没有更新,则调用Docker API创建并启动pod内的容器。
k8s使用kubeadm搭建环境
前提:禁用swap
swapoff -a
添加hosts
vi /etc/hosts
192.168.31.61 k8s-master 192.168.31.62 k8s-node1 192.168.31.63 k8s-node2
1、创建一个Master节点
kubeadm init
2、讲一个Node节点加入到当前集群中
kubeadm join <Master节点到IP和端口>
3、
k8s标签含义
名称 | 含义 |
apiVersion | API版本 |
kind | 资源类型 |
metadata | 资源元数据 |
spec | 资源规格 |
selector | 标签选择器,于下面template.metadata.labels保持一直 |
template | Pod模板 |
metadata | Pod元数据 |
spec | Pod规格 |
containers | 容器配置 |
pod与deployment的关系
Pod是单一亦或一组容器的合集
Pod是k8s的最小调度单位,一个Pod中可以有多个containers,彼此共享网络等,这是k8s的核心概念。
deployment是pod版本管理的工具 用来区分不同版本的pod
从开发者角度看,deployment顾明思意,既部署,对于完整的应用部署流程,除了运行代码(既pod)之外,需要考虑更新策略,副本数量,回滚,重启等步骤,
deployment,StatefulSet是Controller,保证Pod一直运行在你需要的状态。
有一次性的也就是job,有定时执行的也就是crontabjob,有排号的也就是sts
问题:
1.创建Pod的时候一定会创建 deployment么 ?
2.创建deployment的时候一定会创建Pod么?
Pod是可以单独创建并进行生命周期管理的。
单独创建Pod的时候就不会有deployment出现,但是创建deployment的时候一定会创建Pod,因为Pod是一个基础的单位。
任何的控制器单位的具体实现必须落到Pod去实现。
k8s基本核心概念
Pod: k8s最小部署单元,一组容器的集合。
Deployment: 最常见的控制器,用于更高级别部署和管理Pod。
Service: 为一组Pod提供负责均衡,对外提供统一访问入口。
Label: 标签,附加到某个资源上,用于关联对象,查询,筛选。
kubernetes的集群架构和组件
Deployment控制器(管理应用)
Deployment介绍
Deployment是最常用的k8s工作负载控制器(workload controllers),是k8s的抽象概念,用于更高层次对象,部署和管理pod。
Deployment主要功能:
- 管理Pod,即应用程序。
- 具有上线部署,副本设定,滚动升级,回滚等功能。
应用场景:
网站,API,微服务。
应用发布
kubectl create 的时候加上--record参数,用于记录创建/升级服务时记录执行的命令。
应用升级
kubectl set image deployment 容器名称=镜像名称 -n demospace kubectl set image deployment demoservice=lib/demoservicelib:1.1.0 --namespace=demospace 或者 kubectl edit deployment demoservice -n demospace
应用发布失败回滚
查看deployments版本
kubectl rollout history deployments demoservice -n demospace
查看deployments指定版本信息
kubectl rollout history deployments demoservice -n demospace --revision=2
回滚
kubectl rollout undo deployment demoservice -n demospace 回滚到指定版本: kubectl rollout undo deployment demoservice --to-revision=2 --n demospace
应用水平扩容和缩容
- 修改yaml里面的replicas。
- kubectl scale deployment demoservice --replicas=2 -n demospace。
应用下线
- 删除对应的控制器(kubectl delete deployment 容器名称)。
- 删除对应的service(kubectl delete svc 容器名称)。
- 使用yaml文件删除。
Pod对象
Pod介绍
Pod是一个逻辑抽象概念,k8s创建和管理的最小单元,一个Pod中可以有一个或多个容器。
Pod的特点
- 一个Pod可以理解为一个应用实例,提供服务。
- Pod中容器始终部署在一个Node上。
- Pod中容器共享网络,存储资源。
Pod存在的意义
Pod的实现机制
Pod 要解决的问题
Pod 这样一个东西,本身是一个逻辑概念。那在机器上,它究竟是怎么实现的呢?这就是我们要解释的第二个问题。
既然说 Pod 要解决这个问题,核心就在于如何让一个 Pod 里的多个容器之间最高效的共享某些资源和数据。
因为容器之间原本是被 Linux Namespace 和 cgroups 隔开的,所以现在实际要解决的是怎么去打破这个隔离,然后共享某些事情和某些信息。这就是 Pod 的设计要解决的核心问题所在。
所以说具体的解法分为两个部分:网络和存储。
1.共享网络
第一个问题是 Pod 里的多个容器怎么去共享网络?下面是个例子:
比如说现在有一个 Pod,其中包含了一个容器 A 和一个容器 B,它们两个就要共享 Network Namespace。在 Kubernetes 里的解法是这样的:它会在每个 Pod 里,额外起一个 Infra container 小容器来共享整个 Pod 的 Network Namespace。
Infra container 是一个非常小的镜像,大概 100~200KB 左右,是一个汇编语言写的、永远处于“暂停”状态的容器。由于有了这样一个 Infra container 之后,其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。
所以说一个 Pod 里面的所有容器,它们看到的网络视图是完全一样的。即:它们看到的网络设备、IP地址、Mac地址等等,跟网络相关的信息,其实全是一份,这一份都来自于 Pod 第一次创建的这个 Infra container。这就是 Pod 解决网络共享的一个解法。
在 Pod 里面,一定有一个 IP 地址,是这个 Pod 的 Network Namespace 对应的地址,也是这个 Infra container 的 IP 地址。所以大家看到的都是一份,而其他所有网络资源,都是一个 Pod 一份,并且被 Pod 中的所有容器共享。这就是 Pod 的网络实现方式。
由于需要有一个相当于说中间的容器存在,所以整个 Pod 里面,必然是 Infra container 第一个启动。并且整个 Pod 的生命周期是等同于 Infra container 的生命周期的,与容器 A 和 B 是无关的。这也是为什么在 Kubernetes 里面,它是允许去单独更新 Pod 里的某一个镜像的,即:做这个操作,整个 Pod 不会重建,也不会重启,这是非常重要的一个设计。
2.共享存储
第二问题:Pod 怎么去共享存储?Pod 共享存储就相对比较简单。
比如说现在有两个容器,一个是 Nginx,另外一个是非常普通的容器,在 Nginx 里放一些文件,让我能通过 Nginx 访问到。所以它需要去 share 这个目录。我 share 文件或者是 share 目录在 Pod 里面是非常简单的,实际上就是把 volume 变成了 Pod level。然后所有容器,就是所有同属于一个 Pod 的容器,他们共享所有的 volume。
比如说上图的例子,这个 volume 叫做 shared-data,它是属于 Pod level 的,所以在每一个容器里可以直接声明:要挂载 shared-data 这个 volume,只要你声明了你挂载这个 volume,你在容器里去看这个目录,实际上大家看到的就是同一份。这个就是 Kubernetes 通过 Pod 来给容器共享存储的一个做法。
所以在之前的例子中,应用容器 App 写了日志,只要这个日志是写在一个 volume 中,只要声明挂载了同样的 volume,这个 volume 就可以立刻被另外一个 LogCollector 容器给看到。以上就是 Pod 实现存储的方式。
Service控制器
Service存在的意义
Service引入是解决Pod的动态变化,提供统一访问入口:
- 防止Pod失联,准备找到提供同一个服务Pod,通过一组标签关联Pod(服务发现)。
- 定义一组Pod的访问策略(负载均衡)。
Service的定义与创建
Service ClusterIP类型
集群内部使用
Service NodePort类型
对外暴漏应用
Service Loadblancer类型
对外暴漏应用,适用于公有云
Ingress对象
Ingress为弥补NodePort的不足而生
NodePort的不足
- 一个端口只能一个服务使用,端口需要提前规划。
- 只支持4层负载均衡。
Ingress:
Ingress公开了从集群外部到集群内部服务到HTTP和HTTPS路由到规则集合,而具体实现流量路由则是
有Ingress Controller负债。
Ingress是什么?
Ingress规则配置