kubernetes 入门与实践
1. kubernetes/K8S 是什么?
Kubernetes 是一个可移植、可扩展的、开源的容器管理平台,可以对容器进行自动化部署、自动化扩缩容、跨主机管理等,简称 K8S。K8S 提供了应用程序的升级和回滚的能力,可以对代码进行灰度发布、金丝雀发布、蓝绿发布、滚动更新等。提供了一套完整的监控系统和日志收集平台,具有故障自恢复的能力。利用 service 可以实现服务注册、发现和四层负载均衡,利用 ingress 可以实现七层负载均衡,通过coredns 可实现域名解析等。K8S 支持在多种平台部署,可在私有云,公有云,混合云,openstack、openshift、VMware vSphere,VMware workstation,物理机、云主机等环境部署。
docker 官方 logo:
kubernetes 官方 logo:
它是一个舵,舵是轮船的方向盘,船在大海里航行就要靠舵来掌控方向,Docker 是集装箱,可以把杂乱的货物整理归类,那 kubernetes 就是运送集装箱的船的方向盘,所以叫做舵。
2. kubernetes 起源和发展前景
Kubernetes 单词起源于希腊语, 是“舵手”或者“领航员、飞行员”的意思。
来源于 Google 的 Borg 项目:
Borg 是谷歌内部的一个容器编排工具,谷歌业务 90%以上都在 Borg 上运行,Borg 在谷歌内部已经使用了大概 15 年。 K8S 是在 Borg 的基础上开发出来的轻量级容器编排工具。K8S 的根基非常牢固,得益于 Borg 过去十数年间积累的经验和教训,是站在巨人的肩膀上发展起来的项目。开源之后,迅速称霸容器编排技术领域。
Kubernetes 的发展状况:
京东:
2016 年底,京东业务开始从 OpenStack 切换到 Kubernetes,第一阶段迁移 20%的业务到kubernetes,集群规模是 500+物理节点,2w+Pod 容器。
2020 年,京东实现 90%的业务切换到 kubernetes,集群规模达到上万个节点,百万 Pod 容器阿里巴巴:管理几十个 K8S 集群,其中最大的集群约 1 万个节点,每个集群会运行几十万个应用,api 的 QPS 达到1000 万+。
kubernetes 发展历史:
- 2014.6
谷歌云计算专家埃里克·布鲁尔(Eric Brewer)在旧金山的发布会宣布开源 kubernetes,它由 Joe Beda、 Brendan Burns 以及 Craig McLuckie 带头创建,之后华为、微软、redhat 等公司纷纷引入 kubernetes。 - 2014.9
Kubernetes 开始内测,发布第一个测试版本 0.2. - 2015.7
Kubernetes 开始正式对外使用,发布第一个正式版本 1.0。 4. 2016.12
发布 1.5 版本。 - 2017.10
Docker 官方宣布支持 Kubernetes。这标志着 kubernetes 将成为容器编排领域的大佬。 - 2018 年
2018.3 发布 1.10 版本,CNCF 宣布 Kubernetes 正式毕业 - 2019 年
2019.3 发布 1.14 版本 - 2020 年
2020.8 发布 1.19 版本
2020.12 发布 1.20 版本,宣布不在支持 docker,由于 Docker 镜像遵循开放容器倡议(OCI)镜像规范,所以 Docker 产生的镜像能在所有 CRI (容器运行时接口标准)兼容运行时的集群中正常使用。也就是说 docker+k8s 这套还可以继续用,不需要过度担心。
目前大约是每 100 天更新一次版本,更新速度相当快。常见的容器编排工具: - docker-compose:单机环境下管理 docker
- Docker Swarm:
docker 自己的容器编排工具,可以管理 docker 集群 - Apache Mesos and Marathon:
Mesos 是一个数据中心的资源统一管控的工具,本身没有编排容器的功能,需要和 Marathon 结合使用。后来 Apache Mesos 自己说不但支持 Marathon 也支持 Kubernetes,且当时 docker 也说不但原生支持 docker swarm 也支持 k8s,k8s 的地位已经显而易见了。
3. kubernetes 特性
自我修复弹性伸缩
自动部署和回滚
服务发现和负载均衡机密和配置管理
存储编排批处理
4. kubernetes 架构
先看下 Borg 项目的架构:
k8s 的物理架构是 master/node 模式:
K8S 集群至少需要一个主节点(Master)和多个工作节点(Worker)单 master 节点架构图如下:
Master 节点是集群的控制节点,负责整个集群的管理和控制,主节点主要用于暴露 API,调度部署和节点的管理。工作节点主要是运行容器的。
5. kubernetes 架构详细拆分-组件介绍
kubectl:管理 k8s 的命令行工具,可以操作 k8s 中的资源对象。
etcd: 是一个高可用的键值数据库,存储 k8s 的资源状态信息和网络信息的,etcd 中的数据变更是通过
api server 进行的。
apiserver: 提供 k8s api,是整个系统的对外接口,提供资源操作的唯一入口,供客户端和其它组件调用,提供了 k8s 各类资源对象(pod,deployment,Service 等)的增删改查,是整个系统的数据总线和数据中心,并提供认证、授权、访问控制、API 注册和发现等机制,并将操作对象持久化到 etcd 中。相当于“营业厅”。
scheduler:负责 k8s 集群中 pod 的调度的 , scheduler 通过与 apiserver 交互监听到创建 Pod 副本的信息后,它会检索所有符合该 Pod 要求的工作节点列表,开始执行 Pod 调度逻辑。调度成功后将 Pod绑定到目标节点上,相当于“调度室”。
controller-manager:与 apiserver 交互,实时监控和维护 k8s 集群的控制器的健康情况,对有故障的进行处理和恢复,相当于“大总管”。
kubelet: 每个 Node 节点上的 kubelet 定期就会调用 API Server 的 REST 接口报告自身状态,API
Server 接收这些信息后,将节点状态信息更新到 etcd 中。kubelet 也通过API Server 监听 Pod 信息,从而对 Node 机器上的 POD 进行管理,如创建、删除、更新 Pod
kube-proxy:提供网络代理和负载均衡,是实现 service 的通信与负载均衡机制的重要组件,kube-
proxy 负责为 Pod 创建代理服务,从 apiserver 获取所有 service 信息,并根据 service 信息创建代理服务,实现 service 到 Pod 的请求路由和转发,从而实现 K8s 层级的虚拟转发网络,将到 service 的请求转发到后端的 pod 上。
多 master 节点高可用架构图如下:
6. kubernets 中的资源对象
6.1 Pod
1.1 Pod是什么?
官方文档:https://kubernetes.io/docs/concepts/workloads/pods/
Pod是Kubernetes中的最小调度单元,k8s是通过定义一个Pod的资源,然后在Pod里面运行容器,容器需要指定一个镜像,这样就可以用来运行具体的服务。一个Pod封装一个容器(也可以封装多个容器),Pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。
Pod是需要调度到k8s集群的工作节点来运行的,具体调度到哪个节点,是根据scheduler调度器实现的。
白话解释:
可以把pod看成是一个“豌豆荚”,里面有很多“豆子”(容器)。一个豌豆荚里的豆子,它们吸收着共同的营养成分、肥料、水分等,Pod和容器的关系也是一样,Pod里面的容器共享pod的网络、存储等。
pod相当于一个逻辑主机--比方说我们想要部署一个tomcat应用,如果不用容器,我们可能会部署到物理机、虚拟机或者云主机上,那么出现k8s之后,我们就可以定义一个pod资源,在pod里定义一个把tomcat容器,所以pod充当的是一个逻辑主机的角色。
1.1.1 Pod如何管理多个容器?
Pod中可以同时运行多个容器。同一个Pod中的容器会自动的分配到同一个 node 上。同一个Pod中的容器共享资源、网络环境,它们总是被同时调度,在一个Pod中同时运行多个容器是一种比较高级的用法,只有当你的容器需要紧密配合协作的时候才考虑用这种模式。例如,你有一个容器作为web服务器运行,需要用到共享的volume,有另一个“sidecar”容器来从远端获取资源更新这些文件。
一些Pod有init容器和应用容器。 在应用程序容器启动之前,运行初始化容器。
1.1.2 Pod网络
Pod是有IP地址的,每个pod都被分配唯一的IP地址(IP地址是靠网络插件calico、flannel、weave等分配的),POD中的容器共享网络名称空间,包括IP地址和网络端口。 Pod内部的容器可以使用localhost相互通信。 Pod中的容器也可以通过网络插件calico与其他节点的Pod通信。
1.1.3 Pod存储
创建Pod的时候可以指定挂载的存储卷。 POD中的所有容器都可以访问共享卷,允许这些容器共享数据。 Pod只要挂载持久化数据卷,Pod重启之后数据还是会存在的。
1.2 Pod工作方式
在K8s中,所有的资源都可以使用一个yaml文件来创建,创建Pod也可以使用yaml配置文件。或者使用kubectl run在命令行创建Pod(不常用)。
1.2.1 自主式Pod
所谓的自主式Pod,就是直接定义一个Pod资源,如下:
[root@xianchaomaster1 ~]# vim pod-tomcat.yaml
apiVersion: v1
kind: Pod
metadata:
name: tomcat-test
namespace: default
labels:
app: tomcat
spec:
containers:
- name: tomcat-java
ports:
- containerPort: 8080
image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
Pause 容器
每个 pod 中都存在一个 pause 容器。Pod 中除了 Pause 之外的其他容器可以称之为业务容器。
pause 容器主要为每个业务容器提供以下功能:
PID 命名空间:Pod 中的不同应用程序可以看到其他应用程序的进程 ID。网络命名空间:Pod 中的多个容器能够访问同一个 IP 和端口范围。
IPC 命名空间:Pod 中的多个容器能够使用 SystemV IPC 或 POSIX 消息队列进行通信。
UTS 命名空间:Pod 中的多个容器共享一个主机名和 Volumes(共享存储卷)。
6.2 label
label 是标签的意思,k8s 中的资源对象大都可以打上标签,如 Node、Pod、Service 等,一个资源可以绑定任意多个 label,k8s 通过 Label 可实现多维度的资源分组管理,后续可通过 Label Selector 查询和筛选拥有某些 Label 的资源对象,例如创建一个 Pod,给定一个 Label 是 app=tomcat,那么service 可以通过 label selector 选择拥有 app=tomcat 的 pod,和其相关联,也可通过 app=tomcat删除拥有该标签的 Pod 资源。
6.3 Replicaset
Kubernetes 中的副本控制器,管理Pod,使 pod 副本的数量始终维持在预设的个数。
6.4 Deployment
管理Replicaset 和Pod 的副本控制器,Deployment 可以管理多个Replicaset,是比 Replicaset更高级的控制器,也即是说在创建 Deployment 的时候,会自动创建 Replicaset,由 Replicaset再创建 Pod,Deployment 能对Pod 扩容、缩容、滚动更新和回滚、维持 Pod 数量。
6.5 Service
在 kubernetes 中,Pod 是有生命周期的,如果 Pod 重启 IP 很有可能会发生变化。如果我们的服务都是将 Pod 的 IP 地址写死,Pod 的挂掉或者重启,和刚才重启的 pod 相关联的其他服务将会找不到它所关联的 Pod,为了解决这个问题,在 kubernetes 中定义了 service 资源对象,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service 是一组 Pod 的逻辑集合,这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector 实现的。
可以看下面的图:
6.6 Coredns
在 k8s 中,coredns 会监听 3 类 k8s 资源,分别是 Service、StatefulSet 和 Pod,并会为这三类资源自动创建(更新/删除)相应的域名记录,k8s 中各服务间可以直接通过服务域名的方式进行通信。
6.7 kube-proxy
部署在每个 Node 节点上,它是实现 Kubernetes Service 的通信与负载均衡机制的重要组件, kube- proxy 负责为 Pod 创建代理服务,从 apiserver 获取所有 server 信息,并根据 service 信息创建代理服务,实现 server 到 Pod 的请求路由和转发,从而实现 K8s 层级的虚拟转发网络。