Kubernetes是Google基于其内部使用的Borg系统开源出来的容器编排调度引擎,Google 将其作为初始和核心项目贡献给CNCF(云原生计算基金会),近年来逐渐发展出了云原生生态。
Kubernetes的目标不仅仅是一个编排系统,而是提供一个规范用以描述集群的架构,定义服务的最终状态,使系统自动地达到和维持该状态。Kubernetes作为云原生应用的基石,相当于一个云操作系统,其重要性不言而喻。
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。——CNCF(云原生计算基金会)。
容器的设计模式
类别 | 名称 |
---|---|
资源对象 | Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaler |
配置对象 | Node、Namespace、Service、Secret、ConfigMap、Ingress、Label、CustomResourceDefinition、 ServiceAccount |
存储对象 | Volume、Persistent Volume |
策略对象 | SecurityContext、ResourceQuota、LimitRange |
在 Kubernetes 系统中,Kubernetes 对象 是持久化的条目。Kubernetes 使用这些条目去表示整个集群的状态。特别地,它们描述了如下信息:
- 什么容器化应用在运行(以及在哪个 Node 上)
- 可以被应用使用的资源
- 关于应用如何表现的策略,比如重启策略、升级策略,以及容错策略
资源限制与配额
- Pod级别,最小的资源调度单位
- Namespace级别,限制资源配额和每个Pod的资源使用区间
集群详情
- Kubernetes 1.6.0
- Docker 1.12.5(使用yum安装)
- Etcd 3.1.5
- Flanneld 0.7 vxlan 网络
- TLS 认证通信 (所有组件,如 etcd、kubernetes master 和 node)
- RBAC 授权
- kubelet TLS BootStrapping
- kubedns、dashboard、heapster(influxdb、grafana)、EFK(elasticsearch、fluentd、kibana) 集群插件
- 私有Docker镜像仓库Harbor(请自行部署,Harbor提供离线安装包,直接使用docker-compose启动即可)
步骤介绍
- 创建 TLS 证书和秘钥
- 创建kubeconfig文件
- 创建高可用etcd集群
- 安装kubectl命令行工具
- 部署master节点
- 安装flannel网络插件
- 部署node节点
- 安装kubedns插件
- 安装dashboard插件
- 安装heapster插件
- 安装EFK插件
Kubernetes中的负载均衡
- Service:直接用Service提供cluster内部的负载均衡,并借助cloud provider提供的LB提供外部访问
- Ingress:还是用Service提供cluster内部的负载均衡,但是通过自定义LB提供外部访问
- Service Load Balancer:把load balancer直接跑在容器中,实现Bare Metal的Service Load Balancer
- Custom Load Balancer:自定义负载均衡,并替代kube-proxy,一般在物理部署Kubernetes时使用,方便接入公司已有的外部服务
应用构建和发布流程说明:
- 用户向Gitlab提交代码,代码中必须包含
Dockerfile
- 将代码提交到远程仓库
- 用户在发布应用时需要填写git仓库地址和分支、服务类型、服务名称、资源数量、实例个数,确定后触发Jenkins自动构建
- Jenkins的CI流水线自动编译代码并打包成Docker镜像推送到Harbor镜像仓库
- Jenkins的CI流水线中包括了自定义脚本,根据我们已准备好的Kubernetes的YAML模板,将其中的变量替换成用户输入的选项
- 生成应用的Kubernetes YAML配置文件
- 更新Ingress的配置,根据新部署的应用的名称,在Ingress的配置文件中增加一条路由信息
- 更新PowerDNS,向其中插入一条DNS记录,IP地址是边缘节点的IP地址。关于边缘节点,请查看边缘节点配置
- Jenkins调用Kubernetes的API,部署应用
安全性与权限管理
Kubernetes是一个多租户的云平台,因此必须对用户的权限加以限制,对用户空间进行隔离。Kubernetes中的隔离主要包括这几种:
- 网络隔离:需要使用网络插件,比如flannel, calico。
- 资源隔离:kubernetes原生支持资源隔离,pod就是资源隔离和调度的最小单位,同时使用namespace限制用户空间和资源限额。
- 身份隔离:使用RBAC-基于角色的访问控制,多租户的身份认证和权限控制。
云原生应用开发示例
将按照如下步骤来开发部署一个Kubernetes原生应用并将它部署到Kubernetes集群上开放给集群外访问:
- 服务API的定义
- 使用Go语言开发Kubernetes原生应用
- 一个持续构建与发布工具与环境
- 使用traefik和VIP做边缘节点提供外部访问路由
服务注册&服务发现
在Kubernetes中则可以使用DNS、Service和Ingress来实现,不需要修改应用代码,直接从网络层面来实现。
Service Mesh
Kubernetes中的应用将作为微服务运行,但是Kubernetes本身并没有给出微服务治理的解决方案,比如服务的限流、熔断、良好的灰度发布支持等。
Service Mesh可以用来做什么
- Traffic Management:API网关
- Observability:服务调用和性能分析
- Policy Enforcment:控制服务访问策略
- Service Identity and Security:安全保护
Service Mesh的特点
- 专用的基础设施层
- 轻量级高性能网络代理
- 提供安全的、快速的、可靠地服务间通讯
- 扩展kubernetes的应用负载均衡机制,实现灰度发布
- 完全解耦于应用,应用可以无感知,加速应用的微服务和云原生转型
Kubernetes 运行在节点 (node) 上,节点是集群中的单个机器。如果你有自己的硬件,节点可能对应于物理机器,但更可能对应于在云中运行的虚拟机。节点是部署你的应用或服务的地方,是 Kubernetes 工作的地方。有 2 种类型的节点 ——master 节点和 worker 节点,所以说 Kubernetes 是主从结构的。
主节点是一个控制其他所有节点的特殊节点。一方面,它和集群中的任何其他节点一样,这意味着它只是另一台机器或虚拟机。另一方面,它运行着控制集群其他部分的软件。它向集群中的所有其他节点发送消息,将工作分配给它们,工作节点向主节点上的 API Server 汇报。
Master 节点本身也包含一个名为 API Server 的组件。这个 API 是节点与控制平面通信的唯一端点。API Server 至关重要,因为这是 worker 节点和 master 节点就 pod、deployment 和所有其他 Kubernetes API 对象的状态进行通信的点。
Woker 节点是 Kubernetes 中真正干活的节点。当你在应用中部署容器或 pod(稍后定义)时,其实是在将它们部署到 worker 节点上运行。Worker 节点托管和运行一个或多个容器的资源。
Kubernetes 中的逻辑而非物理的工作单位称为 pod。一个 pod 类似于 Docker 中的容器。记得我们在前面讲到,容器可以让你创建独立、隔离的工作单元,可以独立运行。但是要创建复杂的应用程序,比如 Web 服务器,你经常需要结合多个容器,然后在一个 pod 中一起运行和管理。这就是 pod 的设计目的 —— 一个 pod 允许你把多个容器,并指定它们如何组合在一起来创建应用程序。而这也进一步明确了 Docker 和 Kubernetes 之间的关系 —— 一个 Kubernetes pod 通常包含一个或多个 Docker 容器,所有的容器都作为一个单元来管理。
Kubernetes 中的 service 是一组逻辑上的 pod。把一个 service 看成是一个 pod 的逻辑分组,它提供了一个单一的 IP 地址和 DNS 名称,你可以通过它访问服务内的所有 pod。有了服务,就可以非常容易地设置和管理负载均衡,当你需要扩展 Kubernetes pod 时,这对你有很大的帮助,我们很快就会看到。
什么是 Kubectl?
kubectl 是一个命令行工具,用于与 Kubernetes 集群和其中的 pod 通信。使用它你可以查看集群的状态,列出集群中的所有 pod,进入 pod 中执行命令等。你还可以使用 YAML 文件定义资源对象,然后使用 kubectl 将其应用到集群中。
Kubernetes 中的自动扩展
我们使用 Kubernetes 而不是直接使用 Docker 的原因之一,是因为 Kubernetes 能够自动扩展应用实例的数量以满足工作负载的需求。
自动缩放是通过集群设置来实现的,当服务需求增加时,增加节点数量,当需求减少时,则减少节点数量。节点是 “物理” 结构 —— 我们把 “物理” 放在引号里,因为要记住,很多时候,它们实际上是虚拟机。
无论如何,节点是物理机器的事实意味着我们的云平台必须允许 Kubernetes 引擎创建新机器。各种云提供商对 Kubernetes 支持基本都满足这一点。
什么是 kubernetes Ingress 和 Egress?
外部用户或应用程序与 Kubernetes pod 交互,就像 pod 是一个真正的服务器一样。我们需要设置安全规则允许哪些流量可以进入和离开 “服务器”,就像我们为托管应用程序的服务器定义安全规则一样。
进入 Kubernetes pod 的流量称为 Ingress,而从 pod 到集群外的出站流量称为 egress。我们创建入口策略和出口策略的目的是限制不需要的流量进入和流出服务。而这些策略也是定义 pod 使用的端口来接受传入和传输传出数据 / 流量的地方。
什么是 Ingress Controller?
但是在定义入口和出口策略之前,你必须首先启动被称为 Ingress Controller(入口控制器)的组件;这个在集群中默认不启动。有不同类型的入口控制器,Kubernetes 项目默认只支持 Google Cloud 和开箱即用的 Nginx 入口控制器。通常云供应商都会提供自己的入口控制器。
什么是 Replica 和 ReplicaSet?
为了保证应用程序的弹性,需要在不同节点上创建多个 pod 的副本。这些被称为 Replica。假设你所需的状态策略是 “让名为 webserver-1 的 pod 始终维持在 3 个副本”,这意味着 ReplicationController 或 ReplicaSet 将监控活动副本的数量,如果其中有任何一个 replica 因任何原因不可用(例如节点的故障),那么 Deployment Controller 将自动创建一个新的系统(定义如下)。
所需状态是在 deployment 中定义的。 Master 节点的中有一个子系统叫做 Deployment Controller,负责实际执行并使当前状态不断趋向于所需状态。
因此,举例来说,如果你目前有 2 个 pod 的副本,而你所希望的状态应该有 3 个,那么 Replication Controller 或 ReplicaSet 会自动检测到这个要求,并指示 Deployment Controller 根据预定义的设置部署一个新的 pod。
什么是服务网格?
服务网格 (Service Mesh)用于管理服务之间的网络流量,是云原生的网络基础设施层,也是Kubernetes 次世代的云原生应用的重要组成部分。
服务网格利用容器之间的网络设置来控制或改变应用程序中不同组件之间的交互。下面,我们用一个例子来说明。假设你想测试 Nginx 的新版本,检查它是否与你的 Web 应用兼容。你用新的 Nginx 版本创建了一个新的容器 (Container2),并从当前容器 (Container1) 中复制了当前的 Nginx webserver 配置。但你不想影响组成 web 应用的其他微服务(假设每个容器对应一个单独的微服务)—— 就是 MySQL 数据库、Node.js 前端、负载均衡器等。
所以使用服务网格,你可以立即只把 webserver 微服务改成 Container2(新 Nginx 版本的那个)进行测试。如果确定它不能工作,比如因为它导致网站出现一些兼容性问题,那么你就调用服务网格来快速切换回原来的 Container1。而这一切都不需要对其他容器进行任何配置变更 —— 这些变更对其他容器是完全透明的。
如果没有服务网格,对容器来说这项工作将十分繁琐,因为这涉及到逐一更改所有其他容器上的配置,将它们所包含的服务从 Container1 指向 Container2,然后在测试失败后,将它们全部改回来。
在前面这部分 Kubernetes 指南中,我们介绍了一些与 Kubernetes 网络相关的概念。Kubernetes 中的网络可能很棘手,很难理解,如果你刚刚开始,你可能需要一些实践来理解这里。关于服务网格的更多内容请参考Istio Handbook——Istio 服务网格进阶实战。
在下一部分中,我们将展开更多关于 Kubernetes 的话题:如何开始学习 Kubernetes,如何在本地安装和测试 Kubernetes,以及 Kubernetes 的一些优秀的监控工具。
Kubernetes 监控工具
Prometheus 监控
Prometheus 是一个功能丰富的开源监控和警报工具。Prometheus 包含一个内部数据存储用来收集指标,如生成的时间序列数据。Prometheus 还拥有众多插件,允许它将数据暴露给各种外部解决方案,并从其他数据源导入数据,包括所有主要公有云监控解决方案。
Grafana 仪表盘
Grafana 是一个优秀的仪表盘、分析和数据可视化工具。它没有 Prometheus 的全功能数据收集能力,但 Prometheus 又没有 Grafana 的数据呈现界面。事实上,他们最好是结合在一起使用 ——Prometheus 负责数据收集和汇总,Grafana 负责数据展示。它们共同创造了一个强大的组合,涵盖了数据收集、基本警报和可视化。