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 一直在快速地开发和迭代。
pod是一组紧密关联的容器集合,其内部的多个容器共享网络和文件系统,可以通过进程间通信和文件共享完成服务。因此pod是k8s调度的基本单位,也是最小的工作单元,并且每个pod都有一个唯一的IP。
pod具有如下特征:
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时一定要注意:
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
service是对一组提供相同功能的pods进行抽象,并未它们提供一个统一的入口,借助service可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。
service有四种类型:
容器的数据默认是非持久化的,容器晓辉以后数据也会跟着丢失,docker为了解决此问题提供了volume机制,而k8s则有更强大的volume机制和插件。
在k8s中,volume的生命周期与pod绑定。pod中的容器销毁时,volume中的数据不会丢失,只有当pod被删除时,volume才会进行清理,至于其中的数据是否丢失还要看具体的volume类型。
PV是PersistentVolume的简写,意思是持久化存储卷,和node一样,PV也是集群的资源;而PVC是PersistentVolumeClaim的简写,用于将PV挂载到pod中
PV的访问模式有三种:
PV的回收策略也有三种:
k8s通常不会直接创建pod,而是通过controller来管理pod。controller中定义了pod的部署特性,比如有几个副本、在哪个node上运行等。为了满足不同的业务场景,k8s提供了多种controller,包括deployment、ReplicaSet、StatefuleSet、DaemonSet和Job 等。
前面说到针对不同的业务场景,k8s提供了不同的controller,而针对无状态类型的应用,k8s使用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
deployment和ReplicaSet视为无状态应用设计的,而StatefulSet则视为有状态应用设计,其应用场景包括:
其支持两种更新策略
DaemonSet就是守护进程集,保证在特定或所有node节点上都运行一个pod实例,常用来部署一些集群的日志采集、监控或者其他系统管理应用,典型的应用有:
DaemonSet可以指定pod运行的node,这种指定忽视node的SchedulingDisabled状态,关于指定有两种方法:
并且支持两种策略
Job负责批量处理短暂的一次性任务 (short lived>CronJob即定时任务,就类似于Linux系统的crontab,在指定的时间周期运行指定的任务
我们在这里看了这么久以期入门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的本质,它的本质就是为用户提供一个具有普遍意义的容器编排工具,就像一个操作系统。