1. k8s概述

Kubernetes 是Google开源的分布式的容器管理平台,方便我们在服务器集群中管理我们容器化应用。

目标是管理跨多个主机的容器,用于自动部署、扩展和管理容器化的应用程序

简单来说:

  • docker compose用于在一台电脑里管理多个容器
  • docker swarm用于在多台电脑管理多个容器
  • k8s就是docker swarm的一种实现方式

2. k8s常用概念介绍

  • 节点 (Master node and Worker node)

    节点通常指的就是服务器,在k8s中有两种节点:

    • 管理节点(Master Node):负责管理整个k8s集群,一般由3个管理节点组成HA的架构。
    • 工作节点(Worker Node):主要负责运行容器。
  • 命名空间 (Namespace)

    k8s命名空间主要用于隔离集群资源、隔离容器等,为集群提供了一种虚拟隔离的策略;

    默认存在3个名字空间,分别是

    • 默认命名空间 default
    • 系统命名空间 kube-system 和 kube-public。
  • Object

    k8s 对象(Object)是一种持久化存储并且用于表示集群状态的实体。k8s 对象其实就是k8s自己的配置协议,总之我们可以通过定义一个object让k8s根据object定义执行一些部署任务、监控任务等等。

  • POD

    Pod是 Kubernetes 部署应用或服务的最小的基本单位。一个Pod 封装多个应用容器(也可以只有一个容器)、存储资源、一个独立的网络 IP 以及管理控制容器运行方式的策略选项。

  • 副本集 (ReplicaSet,RS)

    是一种控制器,负责监控和维护集群中pod的副本(replicas)数,确保pod的副本数是我们期望的样子。

  • 部署 (Deployment)

    表示对k8s集群的一次更新操作,是k8s集群中最常用的Object,主要用于部署应用。支持滚动升级。

  • 服务 (service)

    是对应用的抽象,也是k8s中的基本操作单元,一个服务背后由多个pod支持,服务通过负载均衡策略将请求转发到容器中。

  • Ingress

    是一种网关服务,可以将k8s服务通过http协议暴露到外部。

  • 无状态应用 & 有状态应用

    • 无状态应用指的是应用在容器中运行时候不会在容器中持久化存储数据,应用容器可以随意创建、销毁;如果一个应用有多个容器实例,对于无状态应用,请求转发给任何一个容器实例都可以正确运行。例如:web应用
    • 有状态应用指的是应用在容器中运行时候需要稳定的持久化存储、稳定的网络标识、固定的pod启动和停止次序。例如:mysql数据库

集群、节点、kubelet

集群是一组节点,这些节点可以是物理服务器或者虚拟机,在他上面安装了Kubernetes环境。
k8s cluster

  • Master 负责管理集群, master 协调集群中的所有活动,例如调度应用程序、维护应用程序的所需状态、扩展应用程序和滚动更新。

  • 节点是 Kubernetes 集群中的工作机器,可以是物理机或虚拟机。

  • 每个工作节点都有一个 kubelet,Kubelet是管理节点并与 Kubernetes Master 节点进行通信的代理。节点上还应具有处理容器操作的容器运行时,例如 Dockerrkt

    kubernetes 是一个分布式的集群管理系统,在每个节点(node)上都要运行一个 worker 对容器进行生命周期的管理,这个 worker 程序就是 kubelet。

    简单地说,kubelet 的主要功能就是定时从某个地方获取节点上 pod/container 的期望状态(运行什么容器、运行的副本数量、网络或者存储如何配置等等),并调用对应的容器平台接口达到这个状态。

一个 Kubernetes 工作集群至少有三个节点。 Master 管理集群,而 节点 用于托管正在运行的应用程序。

当您在 Kubernetes 上部署应用程序时,您可以告诉 master 启动应用程序容器。Master 调度容器在集群的节点上运行。 节点使用 Master 公开的 Kubernetes API 与 Master 通信。用户也可以直接使用 Kubernetes 的 API 与集群交互。

Pod

Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace,是Kubernetes 调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。 k8s pod在 Kubernetes 中,所有对象都使用 manifest(yaml或json)来定义,比如一个简单的 nginx 服务可以定义为 nginx.yaml,它包含一个镜像为 nginx 的容器:

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

Label

Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key最长不能超过63字节,value 可以为空,也可以是不超过253字节的字符串)。 Label 不提供唯一性,并且实际上经常是很多对象(如Pods)都使用相同的 label 来标志具体的应用。 Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如Service 用 label 来选择一组 Pod)。Label Selector支持以下几种方式:

  • 等式,如app=nginx和env!=production
  • 集合,如env in (production, qa)
  • 多个label(它们之间是AND关系),如app=nginx,env=test

Namespace

Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services,deployments 等都是属于某一个 namespace 的(默认是default),而 Node, PersistentVolumes 等则不属于任何 namespace。

Deployment

是否手动创建 Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么,能否将Pods划到逻辑组里?

Deployment 确保任意时间都有指定数量的 Pod“副本”在运行。如果为某个 Pod 创建了Deployment 并且指定3个副本,它会创建3个 Pod,并且持续监控它们。如果某个 Pod 不响应,那么 Deployment 会替换它,保持总数为3.

如果之前不响应的 Pod 恢复了,现在就有4个 Pod 了,那么 Deployment 会将其中一个终止保持总数为3。如果在运行中将副本总数改为5,Deployment 会立刻启动2个新 Pod,保证总数为5。Deployment 还支持回滚和滚动升级。

当创建 Deployment 时,需要指定两个东西:

  • Pod模板:用来创建 Pod 副本的模板
  • Label标签:Deployment 需要监控的 Pod 的标签。

现在已经创建了 Pod 的一些副本,那么在这些副本上如何均衡负载呢?我们需要的是 Service。

Service

Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹配 labels 的Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些endpoints 上。

每个 Service 都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)和 DNS 名,其他容器可以通过该地址或 DNS 来访问服务,而不需要了解后端容器的运行。

3. k8s架构

img

通过上图可以看出k8s整体架构主要由左边的master节点和右边的worker组成,master节点负责对整个集群进行管理,右边的电脑表示worker节点负责运行我们部署的容器。

4. 基于k8s的常见web应用部署架构

img

从上往下看,ingress作为http请求入口接收客户端请求,ingress根据路由规则将请求转发给对应的服务,服务再根据负载均衡策略将请求转发给对应的容器实例,底层基础云服务由所有容器实例共享。