K8S是一个便携的,可扩展的,开源平台,利用声明式的配置和自动化操作来管理容器化的服务。
K8S主要功能就是做容器编排, 编排是什么? 就是原本就已经存在了某些东西,你利用这些东西进行排列组合之类的操作,来发挥某些价值。上面提到了Docker可以对应用进行打包,但是当容器越来越多的时候,管理难度也会随之增加,而K8S就是一种容器管理工具,方便我们来管理Docker。
K8S历史
下图是部署方案的升级:
传统部署,将应用直接部署在物理机上。缺点:多个应用部署在一台机器,可能由于某个应用导致机器资源耗尽,所有应用都无法用。如果每个应用运行在单独的物理机上,成本太高
虚拟化部署:可以在同一台机器上对应用进行隔离,更好的利用机器资源。但是缺点是,每一个虚拟机都要有操作系统,虚拟化的硬件,一定程度上浪费资源。但是比传统部署方案好
容器化部署:相比于虚拟化部署更加轻量级,同时更加便携,更好的利用系统的资源。
K8S是方便容器管理的,那么K8S有哪些好处呢?
自动发布和回滚,在K8S中描述自己想要的状态,然后K8S就会改变容器到期望的状态。
服务发现和负载均衡,K8S可以通过DNS名字来发现容器,如果网络传输量高的时候,K8S可以负载均衡分发网络请求。
自动恢复,当容器故障的时候,会自动重启,自动替换故障的容器。
... 优点很多,不然就不会这么火了
我自己的感觉是K8S在运维和发布上相比于传统的方式简化了很多:
不用再手动的重启设备,发布版本等,只需要在K8S中配置期望的状态,降低开发运维成本
K8S自带管理集群功能,传统方式要自己去管理多台机器,现在用K8S就可以搞定
...
K8S架构
K8S的集群主要有Master节点和Worker节点两种类型,左侧为Master节点,右侧为多个Worker节点。Master节点主要用于暴露API,调度部署,和节点的管理。Worker节点时真正工作的节点,Docker就运行在工作节点上,同时运行一个K8S的代理用于同主节点通信。
kube-controller-manager 是用户与K8S交互的工具,kubectl,
kube-apiServer提供了资源操作的唯一入口,对资源进行增删改查,并提供认证、授权、访问控制、API注册和发现等机制;
etcd保存了整个集群的状态; K8S中的资源,pod都是以yml文件来描述的
Scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
kubelet 相当于worker节点的代理,用于与主节点通信,同时负责pod对应容器的创建,启停任务。
K8S本地安装
集群版本如果只是做实验会比较麻烦,我们可以使用官方提供的minikube安装简化版本的K8S即可。
Minikube本地安装, 记得Minikube放在C盘,还要安装VirtualBox
Play with Kubernetes,浏览器端交互式教程
在minikube配置好本地K8S集群之后,我们就可以利用本地环境来探索K8S的用法了。
K8S概念
Pod
K8S调度的最小单位,在一个pod里面可以有一个或者多个容器。下图为pod,node,与Container的关系:
pod在创建之后会存储在ectd中。然后被Master节点调度到某个具体的Node上并进行绑定,pod被Node上的kubelet进程实例化为Docker容器被启动起来
当Pod里某个容器停止时,k8s会检测到并重启这个pod(重启pod里面所有的容器),如果pod所在node宕机,则这个node上的所有pod被调度到其他的node上。
一个pod中的多容器共享文件与资源
通过ymal文件创建pod
参考: Hands-on: Kubernetes Pods. My first container
Replication Controller
其实听名字我们大致可以猜到这个概念在K8S中就是控制复制相关的东西,实际上它就是在配置文件中定义了一个期望的场景,即声明某种pod的副本数量在任意时刻都符合某个预期值,然后K8S会根据期望值进行调度Pod。所以RC的定义包含如下部分:
Pod的预期副本数
用于筛选目标Pod的Label Selector
当Pod的副本数量小于预期数量时,用于创建pod的pod template
如下为一个RC定义的例子:
apiVersion: v1 kind: ReplicationController metadata: name: nginx spec: replicas: 3 #定义副本数 selector: app: nginx #定义选择的pod label template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
如果我们想要让pod的数量变为2个的话:
删除RC:
Deployment
Deployment相当于对RC的一次升级,它也是描述自己期望的状态,然后K8S会尽力实现我们想要的状态。Deployment的典型使用场景有以下几个:
更新Deployment以创建新的Pod,比如镜像升级。 相当于我们发布了新的产品版本
如果当前的Deployment不稳定,则回滚到早先的一个Depoyment版本
扩展Deployment以应对高负载
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.12.2 ports: - containerPort: 80
使用命令创建Deplyment:
.\kubectl create -f .\labs\deployment\deployment_nginx.yml
更新与回滚容器的镜像:
ReplicationSet
ReplicaSet(RS)是Replication Controller(RC)的升级版本。ReplicaSet 和 Replication Controller之间的唯一区别是对选择器的支持。
RS支持更丰富的选择器,匹配集合,表达式等
RC仅支持equality-based(全匹配,理解为等于号)的选择器要求。
大多数kubectl支持Replication Controller 命令的也支持ReplicaSets。
一般使用Deployment来管理ReplicaSets,很少会单独使用ReplicaSets
Service
在K8S集群中,每个pod都有自己的独立IP地址。
不同的pod相互之间是可以通信的,不管有没有在同一台Node上。
不同的Node也可以与pod进行通信,不管pod是否在当前的Node上
当我们使用RS或者RC的时候,如果对pod做scale的话,可能会杀死一些pod。当使用Deployment进行滚动更新的时候,旧的pod也会被终止,然后创建新的pod,但是这个时候Pod IP地址就会变化了。
但是一般提供给外界的都是一个稳定的IP和端口,来提供服务,那么pod提供的服务如何才能被发现或者及时更新呢?这就是K8S的Service做的事。
Service有三种类型:
ClusterIP:集群中可以访问的,集群里任何地方都可以访问,但是外部无法访问。K8S会分配一个集群IP给Service。
NodePort:绑定到Node上面了,这个时候外界是可以访问的。
外部LoadBalancer:一般需要云服务商提供。
首先看下节点的IP
ClusterIP
通过kubectl expose命令创建的服务默认是ClusterIP,其地址如上图,只有K8S集群内部可以访问。
NodePort
在使用Kubectrl创建服务的时候指定service的类型:
kubectl expose deployment nginx-deployment --type=NodePort
从外部访问:
关于LoadBalancer需要外部依赖,这里就不做演示
小结
K8S现在基本上成为互联网公司的标准配备,哪怕没有在线上使用,也会再开发环境做一些研究,作为技术人员很有必要学习一下K8S,希望这篇文章能帮助到大家。
参考
注:
本文独家发布自金蝶云社区