认识Kubernetes

文章目录

  • Kubernetes起源
  • 7个概念入门k8s
    • 第1个概念:pod
    • 第2个概念:namespace
    • 第3个概念:node
    • 第4个概念:service
    • 第5个概念:volume
    • 第6个概念:PV和PVC
    • 第7个概念:controller
      • deployment
      • StatefuleSet
      • DaemonSet
      • Job和CronJob
  • k8s的本质

Kubernetes起源

Kubernetes,我们一般简称为K8s。之所以叫K8s,是因为首字母k和尾字母s之间有8个字母,为的是方便拼写。其实是硅谷里有些人的坏习惯,在那里的有些人总喜欢把长单词用首字母+跳过的字母数的方式来进行缩写,就是为了让爷爷奶奶们读不懂,比如亚马逊的Algorithms就被写成A9。

k8s是Google在2014年发布的一个开源项目,据说 Google 的数据中心里运行着超过 20 亿个容器,而且 Google 十年前就开始使用容器技术。最初,Google 开发了一个叫 Borg 的系统(现在命令为 Omega)来调度如此庞大数量的容器和工作负载。在积累了这么多年的经验后,Google 决定重写这个容器管理系统,并将其贡献到开源社区,让全世界都能受益。
这个项目就是 Kubernetes。
从 2014 年第一个版本发布以来,Kubernetes 迅速获得开源社区的追捧,包括 Red Hat、VMware、Canonical 在内的很多有影响力的公司加入到开发和推广的阵营。目前 Kubernetes 已经成为发展最快、市场占有率最高的容器编排引擎产品。 Kubernetes 一直在快速地开发和迭代。

7个概念入门k8s

第1个概念:pod

pod是一组紧密关联的容器集合,其内部的多个容器共享网络和文件系统,可以通过进程间通信和文件共享完成服务。因此pod是k8s调度的基本单位,也是最小的工作单元,并且每个pod都有一个唯一的IP。

pod具有如下特征:

  • 包含多个共享IPC、Network和UTC namespace的容器,可直接通过localhost通信
  • 所有Pod内容器都可以访问共享的Volume,可以访问共享数据
  • 优雅终止:pod删除的时候先给其内的进程发送SIGTERM,等待一段时间(grace period)后才强制停止依然还在运行的进程
  • 特权容器(通过SecurityContext配置)具有改变系统配置的权限(在网络插件中大量应用)
  • 支持三种重启策略(restartPolicy),分别是:Always、OnFailure、Never
  • 支持三种镜像拉取策略(imagePullPolicy),分别是:Always、Never、IfNotPresent
  • 资源限制,Kubernetes通过CGroup限制容器的CPU以及内存等资源,可以设置request以及limit值
  • 健康检查,提供两种健康检查探针,分别是livenessProbe和redinessProbe,前者用于探测容器是否存活,如果探测失败,则根据重启策略进行重启操作,后者用于检查容器状态是否正常,如果检查容器状态不正常,则请求不会到达该Pod
  • Init container在所有容器运行之前执行,常用来初始化配置
  • 容器生命周期钩子函数,用于监听容器生命周期的特定事件,并在事件发生时执行已注册的回调函数,支持两种钩子函数:postStart和preStop,前者是在容器启动后执行,后者是在容器停止前执行

第2个概念:namespace

docker的底层就是基于Linux系统的namespace技术。namespace,命名空间,就是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组,pod、service、deployment等都属于某个namespace。

常用的namespace操作

查询所有namespace
	kubectl get namespace
	NAME              STATUS   AGE
	default           Active   3h39m
	kube-node-lease   Active   3h39m
	kube-public       Active   3h39m
	kube-system       Active   3h39m
创建namespace
	kubectl create namespace test
删除namespace
	kubectl delete namespace test

删除namespace时一定要注意:

  • 删除namespace时会自动删除所有属于该namespace的资源
  • default和kube-system不可删除
  • PV不属于任何namespace,但PVC是属于某个namespace的

第3个概念:node

node节点是pod真正运行的宿主机,可以是物理机也可以是虚拟机,k8s本质上是在管理node上的资源,而node要管理其上的pod,这就需要node安装docker、kubelet和kube-proxy。

常用的node操作

查询所有node
	kubectl get node
	NAME     STATUS   ROLES    AGE     VERSION
	master   Ready    master   3h49m   v1.14.2
	node1    Ready    <none>   3h47m   v1.14.2
	node2    Ready    <none>   3h47m   v1.14.2
将node标志为不可调度
	kubectl cordon node1
	此时查询node状态
		kubectl get node
		NAME     STATUS                     ROLES    AGE     VERSION
		master   Ready                      master   3h50m   v1.14.2
		node1    Ready,SchedulingDisabled   <none>   3h48m   v1.14.2
		node2    Ready                      <none>   3h48m   v1.14.2
将node标志为可调度
	kubectl uncordon node1

第4个概念:service

service是对一组提供相同功能的pods进行抽象,并未它们提供一个统一的入口,借助service可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。

service有四种类型:

  • ClusterIP: 默认类型,自动分配一个仅集群内部可以访问的虚拟IP
  • NodePort: 在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过 NodeIP:NodePort 来访问该服务
  • LoadBalancer: 在NodePort的基础上,借助cloud provider创建一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort
  • ExternalName: 将服务通过DNS CNAME记录方式转发到指定的域名

第5个概念:volume

容器的数据默认是非持久化的,容器晓辉以后数据也会跟着丢失,docker为了解决此问题提供了volume机制,而k8s则有更强大的volume机制和插件。

在k8s中,volume的生命周期与pod绑定。pod中的容器销毁时,volume中的数据不会丢失,只有当pod被删除时,volume才会进行清理,至于其中的数据是否丢失还要看具体的volume类型。

  • emptyDir:emptyDir volume就是宿主机上的一个空目录。容器挂掉不会引起emptyDir目录下的数据丢失,但是pod被删除或者迁移时,emptyDir也会被删除
  • hostPath:hostPath Volume的作用是将宿主机文件系统中已经存在的目录挂载给pod中的容器。大部分应用都不会使用hostPath Volume,因为这实际上增加了pod与节点的耦合,限制了pod的使用。不过那些需要访问k8s或docker内部数据(配置文件和二进制库)的应用则需要使用hostPath。
  • NFS:网络文件系统,k8s中通过简单地配置就可以挂载NFS到pod中,而NFS中的数据是可以永久保存的,同时NFS支持同时写操作。
  • glusterfs:同NFS一样是一种网络文件系统,k8s可以将glusterfs挂载到pod中,并进行永久保存
  • cephfs:一种分布式网络文件系统,可以挂载到pod中,并进行永久保存
  • subpath:pod的多个容器使用同一个volume时,会经常用到
  • secret:密钥管理,可以将敏感信息进行加密之后保存并挂载到pod中

第6个概念:PV和PVC

PV是PersistentVolume的简写,意思是持久化存储卷,和node一样,PV也是集群的资源;而PVC是PersistentVolumeClaim的简写,用于将PV挂载到pod中

PV的访问模式有三种:

  • ReadWriteOnce(RWO):最基本的方式,可读可写,但只支持被单个pod挂载
  • ReadOnlyMany(ROX):只读,但可以被多个pod挂载
  • ReadWriteMany(RWX):可读可写,还支持被多个pod挂载

PV的回收策略也有三种:

  • Retain,不清理保留volume(需要手动清理)
  • Recycle,删除数据,即 rm -rf /thevolume/* (只有NFS和HostPath支持)
  • Delete,删除存储资源

第7个概念:controller

k8s通常不会直接创建pod,而是通过controller来管理pod。controller中定义了pod的部署特性,比如有几个副本、在哪个node上运行等。为了满足不同的业务场景,k8s提供了多种controller,包括deployment、ReplicaSet、StatefuleSet、DaemonSet和Job 等。

deployment

前面说到针对不同的业务场景,k8s提供了不同的controller,而针对无状态类型的应用,k8s使用deployment。其典型的应用场景有:

  • 定义deployment来创建pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续deployment

常用的deployment操作

查询deployment
	kubectl get deployment --all-namespaces
	NAMESPACE     NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
	kube-system   coredns                2/2     2            2           4h50m
	kube-system   kubernetes-dashboard   1/1     1            1           4h20m
查看某个deployment的详细信息
	kubectl describe deployment kubernetes-dashboard -n kube-system
创建一个deployment
	kubectl create deployment nginx --image=nginx 
编辑deployment
	kubectl edit deployment kubernetes-dashboard -n kube-system
删除deployment
	kubectl delete deployment nginx
扩缩容,及修改deployment下的pod实例个数
	kubectl scale deployment nginx --replicas=2

StatefuleSet

deployment和ReplicaSet视为无状态应用设计的,而StatefulSet则视为有状态应用设计,其应用场景包括:

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行操作(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
  • 有序收缩,有序删除(即从N-1到0)

其支持两种更新策略

  • OnDelete:当.spec.template更新时,并不立即删除旧的pod,而是等待用户手动删除这些旧pod后自动创建新pod,这是默认的更新策略
  • RollingUpdate:当.spec.template更新时,自动删除旧的pod并创建新pod替换,在更新时这些pod是按逆序的方式进行,依次删除、创建并等待pod变成Ready状态才进行下一个pod的更新

DaemonSet

DaemonSet就是守护进程集,保证在特定或所有node节点上都运行一个pod实例,常用来部署一些集群的日志采集、监控或者其他系统管理应用,典型的应用有:

  • 日志收集
  • 系统监控
  • 系统程序

DaemonSet可以指定pod运行的node,这种指定忽视node的SchedulingDisabled状态,关于指定有两种方法:

  • nodeSelector:只调度到匹配指定label的node上
  • nodeAffinity:功能更丰富的Node选择器,比如支持集合操作,可以调度到满足条件的pod所在的node上

并且支持两种策略

  • OnDelete:默认策略,更新模板后,只有手动删除了旧的pod后才会创建新的pod
  • RollingUpdate:更新DaemonSet模版后,自动删除旧的pod并创建新的pod

Job和CronJob

Job负责批量处理短暂的一次性任务 (short lived>CronJob即定时任务,就类似于Linux系统的crontab,在指定的时间周期运行指定的任务

k8s的本质

我们在这里看了这么久以期入门k8s,那么k8s究竟是什么,它又为何如此受欢迎?
要说k8s的受欢迎,就要提到docker,回到容器上来。

当docker项目成功后不久,它就开始对容器的编排越走越深,因为对云服务提供商来说,只需要能够将用户提交的docker镜像以容器的形式运行起来,就会成为一个节点来承载一定的价值,在这个过程中,云服务提供商有许多可以增值服务的地方,这些都是盈利点。
对于大多数用户来说,有了一个应用服务的容器镜像,现在就需要有一个集群来把这个应用跑起来,最好顺便再有一些比如路由、监控、备份、高可用等附加的功能。在这时候,k8s应运而生。

那么k8s能在这样的大环境下做到什么,想明白这点,就要来看看k8s的架构。
整个k8s集群由master和node节点组成。在master上工作着三个紧密协作的独立组件,分别是负责API服务的kube-apiserver、负责调度的kube-scheduler和负责容器编排的kube-controller-manager,而整个容器的持久化数据,则保存在etcd中;而在node上最核心的部分就是kubelet,它通过一个叫做CRI(Container Runtime Interface) 的远程调用接口来定义容器运行时的各项核心参数。
以上就是k8s的基本架构,它说明k8s根本不会管在其中有什么样的容器在运行,使用了什么样的技术,只要有能够运行的容器镜像,就可以接入到k8s中。在k8s中,docker不是整个架构的核心,而仅仅是一个最底层的容器运行的实现。

综上,k8s要做到什么就很清楚了,在大规模集群中的各种任务之间存在着各种关系,能处理这种关系,就是k8s在云计算时代异军突起的胜算。

在传统虚拟化技术中,对这些关系的处理都非常粗线条。比如经常有很多功能基本无关的应用,只因为它们之间偶尔会互相发起几个HTTP请求,就全都被部署在同一台虚拟机中;再比如经常有一个应用被部署在虚拟机之后,还需要运维手动维护许多跟它协作的,类似日志搜集、灾难恢复等等的守护进程。
但是当容器技术出现以后,再也没有人这么粗线条地处理功能划分了,因为容器本身就只是一个进程。原来那些不得不挤在同一个虚拟机之中的应用、组件、守护进程,现在全部可以单独做成镜像,单独作为一个容器运行,拥有自己的资源,彼此互不干涉,甚至不知道对方存在于哪台node上。大家应该都听过微服务这个说法,微服务之所以从想象变为现实,这就是其中一个前提条件。

接下来我们来看看k8s究竟怎样处理这些关系。
从容器出发,首先要解决容器间紧密合作的问题,于是扩展出了pod的概念;有了pod之后,我们需要能够一次启动多个应用的实例,就有了deployment这个pod的多实例管理器;有了这样一组相同的pod后,我们就需要让它们负载均衡,就需要有一个固定的IP和端口可以负载均衡地访问到它们,就有了service。

终于我们得到了k8s的本质,它的本质就是为用户提供一个具有普遍意义的容器编排工具,就像一个操作系统。

你可能感兴趣的:(Kubernetes,k8s)