【K8s是什么?】比较Docker容器、K8s和GKE的架构与优势

Docker容器——微服务的现代化基础

容器化服务为何会诞生呢?

现如今的软件应用数量大增,其呈现方式也从过去所有服务全装在一起的形式,发展成分散且轻量的分散式架构与无服务器技术(Serverless),让软件产品在迭代更新与服务运行上能更快速且稳定。而容器化技术就彷彿是轻量化时代的里程碑,所以下面我们就首先来认识什么是 Docker 容器化服务吧。

Docker 容器的出现

在认识 Docker 容器前,这边先来了解虚拟主机(VM)当前所面临的困境。过去架设一个网站,除了需要静态的程序与图片等网页资源,如 HTML、CSS和 Javascript 等;也会用到处理客户端连线的 Apache、Nginx 等网站服务器,和储存与读取资料的资料库。

而 VM 若以分散式服务来规划这样的三层式架构,会变成一个服务对应一台专门的VM,并以内网串接进行资料传递。这样当一台 VM 坏掉或过载,就能以镜像(Image)重启或增加 VM,确保网站正常服务。

但是,VM 需要搭配作业系统(OS)的配置会产生3个问题。第一,每个服务都需占据大量的基础设施资源创建 OS;第二,重启或新增 VM 需花费大量时间开机,导致服务从中断到恢复的过程非常漫长;第三,若遇到公司需将服务搬迁的状况,OS 的版本与规格会增加搬迁困难度,非常不符合现在的软件的营运需求。而“Docker 容器化服务”,便是解决上述问题的一帖良药。

Docker 容器的优势

Docker 容器通过封装应用程式与其相依性配置形成轻量的镜像,且可直接运行在宿主机(host machine)上,减少对宿主机负荷的同时提供更多容器服务使用。而轻量化带来的好处除了上述所提,它也让 Docker 容器提供一致性的发布环境,使开发团队可轻易地携带与转换运行环境,提高协同作业的便利性。

另外,Docker 容器还能在数秒内完成建置,让我们可快速地发布与更新服务。反观 VM 镜像因需涵盖 OS 相关内容而相对肥大,且还须透过监视器(Hypervisor)模拟硬件环境以执行镜像,消耗更多的服务资源并徒增宿主机的负荷。

Kubernetes(K8s)——Docker 容器编排工具

上面我们了解到一台宿主机可运行多个 Docker 容器服务,但是如果我们今天启用了多个 Docker 容器在多个宿主机上,该如何管理这些容器呢?

这时,我们需要的就是容器编排工具(Container Orchestration)。现在有各种容器编排工具,比如 Docker 的 Docker Swarm、可以用来测试的 Docker Compose 和红帽的 OpenShift 等,而当中最具代表性的无疑就是 Google 于 2014 年对外开放的 Kubernetes(K8s)!

K8s 前身是 Google 内部的 Borg 丛集管理系统。而如下图所示,过去管理者需各别管理不同主机内的容器。为了确保所有容器服务正常,管理者需设置对应的监控系统并手动重新部署有问题的环境,在管理上非常不易。

而 K8s 则提供可弹性运行分散式系统的自动化管理架构,透过集中化的管理介面控管所有节点。从服务的自动部署、自动修复、负载平衡、权限控管,到服务间的沟通与滚动式更新都可以透过 K8s 达成。

Kubernetes 提供的服务:

  1. 支援负载平衡并分配网络流量与服务自动扩展,达成高扩展性的稳定服务。
  2. 可自动挂载自定的储存系统,与外部基础设施串接。
  3. 可通过 YAML 描述档部署容器服务,且可指定容器所需之 CPU 与 RAM。
  4. 可自动重启失败的容器、替换容器,并删除不健康的容器。
  5. 可储存管理敏感资料如密码、钥匙,使其能供给容器使用。
  6. 可执行 Canary 部署、Blue/Green 部署、滚动式更新、回滚更新。

K8s 是什么?——Cluster 介绍

K8s 是以丛集(Cluster)作为单位来控管其内部的系统。在 Cluster 中,我们可将其切分为控管单元的 Control Plane 与服务资源单位的节点(Node)。简单来说,用户会通过 Control Plane 对 Node 与其内部的 Pod(多个容器组成的最小单位)进行管理与监控,而 Control Plane 内又由以下四种服务组成。

Control Plane 服务元件:

  1. API Server:作为内外沟通的界面接收请求并触发操作。
  2. etcd:K8s 的储存服务,会储存状态、设置与敏感资料。
  3. Scheduler:为 K8s 的调度服务,决定哪些 Pod 要分配给哪些 Node。
  4. Controllers:通过多个控制器如 Replication Controller、Endpoint Controller、SA and Token Controller 来调节系统状态。

K8s 是什么?——Node, Pod 介绍

接着来认识 K8s 中实际提供服务的两个单位,Node 与 Pod。我们可将 Node 视为具有定义的运算与储存资源的独立机器,让最小单位的 Pod 能被建立在其中。而 Node 中还有两个服务元件,分别是 kubelet 与 kube-proxy。kubelet 负责接收 Pods 的当前状态以检查当中的容器健康状态;而 kube-proxy 则是用来传递 Node 内外网络流量给 Pod 的网络代理。

而 Pod 作为 K8s 中的最小元件,负责运作与管理一个或多个容器服务,而 K8s 不以容器为最小单位,是因为网络界面的管理将会非常复杂而困难。所以每个 Pod 中都会有一个独立的网络界面,用以提供 Cluster 内的 IP 位置以便于服务间的沟通与对外的开放。

而 Pod 内则转用 Port 来对接各别容器服务,使内外流量皆能准确地传递给指定的容器。考虑到容器服务重启会造成资料遗失,K8s 除了设计服务为无状态(stateless)外,也可通过 Volume 将 Pod 内的 Container 转为有状态(stateful)服务。

K8s 服务——Pod 的垂直与水平扩展

依据上述所提 Pod 的特性,我们在设计 K8s 服务部署时,可考虑将彼此互相有需求的容器放进同一个 Pod,避免有容器还没启动,另一个有依赖性服务的 Pod 就先一步运行而造成错误。而既然以 Pod 作为容器服务的群组单位,我们的自动扩展(Auto Scaling)自然是要以 Pod 作为运作的单位。

如上图所示,K8s 的 Pod 有两种自动扩展模式。一个是在 Node 中增加更多相同服务 Pod 的 Horizontal Pod Autoscaler(HPA);另一个是对单一 Pod 进行运算与储存资源扩充的 Vertical Pod Autoscaler(VPA)。而当 Pod 进行 HPA,K8s 的负载平衡会自动为我们将流量平均分配给每个 Pod,使服务能在用户无感的情境下扩展。

K8s 劣势——构建过程与 Day-2 维护管理

在了解了 K8s 的强大服务能力后,相信大家现在应该迫不及待想使用,但是尽管 K8s 提供了许多强大的功能,使用前我们还是要先经历一段冗长的安装设置过程。例如 Cluster 与 Node,都需各别进行设置与相关套件的安装。如下图所示,资源计算、第三方套件安装、 K8s 环境建置、网络设定等,全都是非常繁琐的过程。且只要有一个环节出错,光除错就需要大量的时间。

除了安装设置,Day-2 维护管理也是场大工程,从写排程收集 Log 到设置额外套件监控状态数值,都须人工完成。而一旦硬件出问题,又会有更多事项要处理简直没完没了。所以下面我们就要来了解 GCP 上的 K8s 能为我们做什么,有效减少使用 K8s 会遇到的难题。

Google Kubernetes Engine(GKE)—— K8s 代管服务

前面讲述了容器化服务与 K8s 提供的自动化部署与管理服务所带来的好处,但同时我们也看到了其中需面对的难题。所以接下来将为大家介绍 Google Kubernetes Engine(GKE)的服务架构,了解 GKE 如何解决先前我们提到的问题,提供使用者更便捷的服务。

GKE 是什么——服务架构介绍

如下图所示,GKE 基本的用户操作界面与 K8s 相同。使用者可通过 kubectl 指令对 GKE Cluster 的 Control Plane 呼叫 API,来控制 Cluster 内部元件。且呼叫 API 的方式可通过 HTTP、gRPC、GUI 下达,也就是说除了原本 K8s 的指令式控制外,我们也能通过 GKE Console 控制台界面来操作 Control Plane。而 Control Plane 的建置、更新与维护皆由 GKE 代管,所以运算、储存等硬件资源,和 K8s 软件、网络环境的安装与更新都可假手 GKE 处理,大量减轻使用者的负担。

另外 GKE 也会自动利用 Google Compute Engine(GCE)创建 Node,让运算资源能有效运用云端的便利与扩充性。而除了基本元件设置会使用 GCP 的资源,GKE 也内建了许多 GCP 服务的串接。如 VPC 网路环境的串接、作为容器服务曝露点的 Load Balancing,和前面提到 Day-2 所需要的稽核纪录需求。由于 GKE 已内建将各层级纪录资讯即时收集入 Logging,所以使用者可通过 Monitoring 观察使用即时状态。除此之外当然还有代管式资料库、网络防护工具和大数据分析等云端服务可供使用,而这完善的资源整合,也让我们能更专注于促进公司发展的软件开发。

GKE 特点——不同 Cluster 类型的 HA 实践

前面提到 GKE Cluster 具备自动化建置功能,我们可通过console控制台界面设置自订的 Cluster 与 Node 来建构 GKE 的整体环境。而云端服务应用上的一个重要效益就是高可用性(High Availability)部署的可能性,这点在 GKE Cluster 的自动化建置上也能直观地被体现。

介绍 K8s Cluster 时我们提到 K8s 将控制与资源分成 Control Plane 与 Data Plane(即 Nodes),而 GKE 也将其 Cluster 的建置类型依照 Control Plane 与 Data Plane 的 HA 组合进行分类。所以假设我们因成本考量不希望建置 HA,那 GKE 提供的 Single-zone Cluster,可让 Control Plane 与 Data Plane 皆建立在单一 Zone 内,只要该 Zone 的机房不发生问题,部署于其中的 GKE 服务就都能有效运转。

但若今天考量到服务稳定性,无法接受任何单一机房事故导致服务中断,那我们就能使用 Multi-zone 的 Cluster,将 Data Plane 部署于同一 Region 内的所有 Zone。如此一来即便今天运作主要服务的 Zone 发生事故,也仅会发生无法连接 Cluster API Server 的状况,我们部署的容器服务依旧能运行。而若要让 Control Plane 也不中断就可选择 Regional 的 Cluster,将 Control Plane 也部署于同 Region 的每一个 Zone 内达成完全的 HA。

GKE 介绍― Node Pools 服务

前文我们提到在 GKE 中,Node 是由 GCE 创建的。且有别于自行创建的 K8s 需手动对各别 Node 安装对应资源并建置网络环境,GKE 在 Cluster 建置时便会依据我们对 Node 的需求,建立对应的 VM 资源并设置所需的所有环境。另外还能做到基于 Node 的自动扩展,避免硬件资源匮乏。

基于上述优势,GKE 更发展出了 Node Pools 服务,我们可依据容器服务所需的资源来定义多个 Node Pool。举例来说当今天只需用最小的计算能力执行容器服务,可选择最便宜的 VM 机型作为 Node Pool。但如果要运行有 ML 功能的容器,那就可以设定一个具有 NVIDIA GPU 的 Node Pool,大幅提升其计算能力。

而部署服务时,我们可透过描述档 (YAML)指定 Pod 要执行在哪个 Node Pool 中,以便灵活依据不同服务的资源需求配置 Pod 到合适的 Node Pool,防止不必要的消耗进而减少project成本。此外,我们知道 GCE 可通过 Service Account 指定权限并使用对应的 GCP 服务。所以同理,我们也能在 Node Pool 中指派 Service Account ,使同 Pool 中的 Node 都可使用同权限允许的存取服务,提升project安全性。

GKE 介绍―三层安全防护机制

我们知道在安全防护概念中,最好的策略就是在每一个层级都加上防护的措施。因此这边将介绍能替 K8s 加上层层防护的 Layer of Defense。如下图所示,我们可将 GKE 的安全防护机制分为 Project、Cluster 与应用程序部署层级。而 GKE 作为建立在 GCP 上的代管服务,当然也预设将所有云端内部传输与储存的资料加密,实践标准的资料防护。

preview

Project 层级防护机制

GKE 是建立在 VPC 网络环境上的服务架构,所以从 Project 层级来看,Firewall rules 是可有效保护 GKE 环境的。这边提醒务必要将 GKE 所在的 VPC 防火墙对外存取范围限缩,最好仅限工作环境的 IP Range。而 GKE 延续所有 GCP 服务预设有即时纪录 Audit Logging,只要通过简易的设置就能看到所有 GKE 操作的日记纪录,达到公司内部的安全防护。

另外,当我们部署 Ingress 服务,GKE 会使用 HTTP(s) Load Balancer 来开放容器的对外服务,因此只要搭配 Cloud Armor 就能防御 L3、L4 与 L7 的攻击,并限缩存取服务的用户 IP 和地理位置等资讯,提升服务提供窗口的安全性。同理,在 Project 层级,我们也能通过 IAM 限制操作者权限,结合上述的 Service Account 赋予 Node 权限。

Cluster 层级防护机制

接著是 Cluster 层级的防护措施。首先,基于对 Control Plane 的保护,Cluster 在建置时便可设置为 Private Cluster,让 Cluster 所在的 VM 不具备外部直接存取的能力,进而构成封闭的开发环境。此外,我们甚至可以设置针对 Control Plane 存取的白名单,限定只有特定的网段才能进到 Control Plane 执行操作。

对比前面提到的 IAM 权限,K8s 中也有著相似的角色权限服务,即 RBAC(Role-based access control)。RBAC 通过赋予角色权限来指定特定用户访问 K8s API 的能力,另外我们还可更进一步在 Cluster 层级去设置更细微的用户权限划分,安全性上可谓是层层把关。

而 K8s API 的防护还不只如此,所有从 Control Plane 传输的流量,不论是 Control Plane to Node 还是 Control Plane to Control Plane,皆会通过 TLS 进行加密传输以防止被破坏。而在 Pod to Pod 的网络连线上,GKE 也整合了开源的 Calico 网路防护政策,我们只需在创建 Cluster 时一键勾选,就能在 GKE 内创建容器服务间的流量传输安全政策。

应用部署层级防护机制

最后是应用部署层级的防护。我们知道在软件服务中,最容易被入侵的就是来源不明的第三方软件。开发Project时,我们可能需要使用一些被分享在网络上的软件,这当中只要有人恶意于软件中添加木马,我们辛苦开发的软件就会非常危险。因此,GKE 可搭配 Google Artifact Registry 的 Vulnerability Scanning,扫描并认证 Docker image 的安全性,再通过设定 Binary Authorization Policy 确保所有部署的 Docker Image 皆通过认证,确保应用程式部署流程的安全性。

如何决定要不要使用 GKE 服务?

到这里,相信大家对容器、K8s 与 GKE 都有了一定的了解,那么接下来的问题就是我们到底该如何决定是否需要使用 GKE 呢?代管服务虽然方便而强大,但仍旧有着其性质本身的限制,因此下面提供5个考量点,方便各位评估当下状况是否需使用 GKE 服务。

是否使用 GKE 服务可参考以下问题:

  1. 是否需要自动化的软硬件更新服务?
  2. 是否需要定制化的 K8s 网络连接服务?
  3. 是否需要自动化且安全的 CI/CD 流程?
  4. 是否需要自动化的资源扩展?
  5. 是否需要自动化的 Log 收集与即时监控?

以上就是容器化服务和 Google Kubernetes Engine 的介绍,未来我们会再分享 GKE 的相关实作教学。大家对文中内容有任何问题都可留言询问,也欢迎留下感兴趣的 GCP 内容。 最后,如果想更了解 GCP 或有技术服务相关需求也都欢迎联络我们获得更进一步的资讯。

Leave a Reply