Kubernetes详细介绍
一、Kubernetes是什么?
Kubernetes是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
通过Kubernetes可以:
· 快速部署应用
· 快速扩展应用
· 无缝对接新的应用功能
· 节省资源,优化硬件资源的使用
Kubernetes的目标是:促进完善组件和工具的生态系统,以减轻应用程序在公有云或私有云中运行的负担。
二、Kubernetes 特点
· 可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
· 可扩展: 模块化, 插件化, 可挂载, 可组合
· 自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展
Kubernetes是Google 2014年创建管理的,是Google 10多年大规模容器管理技术Borg的开源版本。
三、Why containers?
传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。
新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。
容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在build或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚机轻量、更“透明”,这更便于监控和管理。最后,容器优势总结:
· 快速创建/部署应用:与VM虚拟机相比,容器镜像的创建更加容易。
· 持续开发、集成和部署:提供可靠且频繁的容器镜像构建/部署,并使用快速和简单的回滚(由于镜像不可变性)。
· 开发和运行相分离:在build或者release阶段创建容器镜像,使得应用和基础设施解耦。
· 开发,测试和生产环境一致性:在本地或外网(生产环境)运行的一致性。
· 云平台或其他操作系统:可以在 Ubuntu、RHEL、 CoreOS、on-prem、Google Container Engine或其它任何环境中运行。
· 分布式,弹性,微服务化:应用程序分为更小的、独立的部件,可以动态部署和管理。
· 资源隔离
· 资源利用:更高效
四、使用Kubernetes能做什么?
可以在物理或虚拟机的Kubernetes集群上运行容器化应用,Kubernetes能提供一个以“容器为中心的基础架构”,满足在生产环境中运行应用的一些常见需求,如:
· 多个进程(作为容器运行)协同工作。(Pod)
· 存储系统挂载
· 应用健康检测
· 应用实例的复制
· Pod自动伸缩/扩展
· 负载均衡
· 滚动更新
· 资源监控
· 日志访问
· 调试应用程序
· 提供认证和授权
Kubernetes集群架构拓扑图:
五、Kubernetes架构
Kubernetes主要由以下几个核心组件组成:
· etcd保存了整个集群的状态;
· apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
· controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
· scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
· kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
· Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
· kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
除了核心组件,还有一些推荐的插件:
· kube-dns负责为整个集群提供DNS服务;
· Ingress Controller为服务提供外网入口;
· Heapster提供资源监控;
· Dashboard提供GUI;
· Federation提供跨可用区的集群;
· Fluentd-elasticsearch提供集群日志采集、存储与查询.
六、Kubernetes集群高可用
要将kubernetes应用于生成环境,那么就应该构建高可用的kubernetes集群,下图为官方推荐的生成环境高可用集群拓扑图:
所需要的软件版本:
服务名称 | 版本 | 用途 |
ETCD | 3.2.9 | 存储kubernetes集群状态信息 |
Master | 1.8.3 | 主控节点 |
Node | 1.8.3 | 工作节点 |
Haproxy | 1.7.9 | 负载均衡器 |
Keepalived | 1.3.5 | 高可用 |
Docker | 17.03.2-ce | 容器软件 |
Glusterfs | 3.10.7 | 分布式存储,用来存储日志 |
Tengine | 2.2.0 | 反向代理,互联网入口 |
Harbor | 1.2.2 | 镜像仓库 |
注:因当前服务数量不多,故网络采用直接路由模式,直接手动配置路由即可 |
各类插件版本:
服务名称 | 版本 | 用途 |
Dashboard | 官方1.6.3 | Kubernetes-UI界面 |
DNS | 官方1.14.5 | 集群内部dns解析 |
Heapster | v1.4.3 | 集群监控 |
EFK | 5.5.1/2.0.1 | 日志收集存储 |
Traefik | 1.4.3 | Ingress集群服务暴露 |
服务器规划:
服务名称 | 用途 | 所需数量 | IP规划 |
Etcd | 集群信息存储 | 3台,etcd和master部署于同一机器 | |
Master | 主控节点 | ||
Node | 工作节点 | 根据实际情况确定 | |
Haproxy/keepalived | 高可用/负载均衡 | 2台 | |
Glusterfs | 日志存储 | 4台 | |
Tengine | 互联网入口 | 复用之前 | |
Harbor | 镜像仓库 | 2台 |
下面就官方推荐的高可用架构图所需的系统环境、软件及各类插件进行相关说明:
6.1、kubernetes集群信息存储:etcd
Etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现。etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理日志复制以保证强一致性。Raft是一个来自Stanford的新的一致性算法,适用于分布式系统的日志复制,Raft通过选举的方式来实现一致性,在Raft中,任何一个节点都可能成为Leader。
在分布式系统中,如何管理节点间的状态一直是一个难题,etcd像是专门为集群环境的服务发现和注册而设计,它提供了数据TTL失效、数据改变监视、多值、目录监听、分布式锁原子操作等功能,可以方便的跟踪并管理集群节点的状态。etcd的特性如下:
· 简单: curl可访问的用户的API(HTTP+JSON)
· 安全: 可选的SSL客户端证书认证
· 快速: 单实例每秒 1000 次写操作
· 可靠: 使用Raft保证一致性
etcd是kubernetes官方推荐使用的专门用来存储集群信息的键值存储系统。
6.2、Kubernetes网络方案选择
6.2.1、直接路由:
节点数量不多的情况下,通过在每个node上启动docker的时候通过设置—bip并添加对应的路由可以实现各个pod直接的网络互联互通,并且可与其他物理机或者虚拟机进行直接通信,因为没有数据包的拆包解包工作。
直接路由网络优势:性能较好,容易管理
直接路由网络劣势:网络隔离性差,每次新增节点都需要手动设置路由规则。
6.2.2、Flannel容器网络:
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址,在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。并使这些容器之间能够通过IP地址相互找到,也就是相互ping通。
Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
Flannel实质上是一种“覆盖网络(overlaynetwork)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等数据转发方式,默认的节点间数据通信方式是UDP转发。
Flannel之所以可以搭建kubernets依赖的底层网络,是因为它可以实现以下两点:
· 它给每个node上的docker容器分配相互不想冲突的IP地址;
· 它能给这些IP地址之间建立一个覆盖网络,同过覆盖网络,将数据包原封不动的传递到目标容器内。
Flannel网络优势:部署简单,性能还行
Flannel网络劣势:无法隔离多子网,对上层设计依赖度高,没有IPAM,IP地址浪费,对docker启动方案有绑定。
6.2.3、Calico容器网络:
Calico介绍
· Calico是一个纯3层的数据中心网络方案,而且无缝集成像OpenStack这种IaaS云架构,能够提供可控的VM、容器、裸机之间的IP通信。Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,它是一个纯三层的方法,使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心。
· Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息像整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。
· Calico节点组网可以直接利用数据中心的网络结构(无论是L2或者L3),不需要额外的NAT,隧道或者Overlay Network。
· Calico基于iptables还提供了丰富而灵活的网络Policy,保证通过各个节点上的ACLs来提供Workload的多租户隔离、安全组以及其他可达性限制等功能。
Calico架构图
Calico网络优势:性能较好,可控性高,隔离性好
Calico网络劣势:操作起来比较复杂,维护成本高,对iptables有依赖
考虑到当前的实际业务情况,节点数量不多,同时对于网络隔离性要求也不是很高,因此暂定先选择直接路由网络方案。
6.3、Kubernetes业务系统存储方案
一个运行中的容器,缺省情况下,对文件系统的写入,都是发生在其分层文件系统的可写层的,一旦容器运行结束,所有写入都会被丢弃。因此需要对持久化支持,当前kubernetes支持多种存储方案,主要有以下几种:
EmptyDir
顾名思义,EmptyDir是一个空目录,他的生命周期和所属的 Pod 是完全一致的,EmptyDir的用处是,可以在同一 Pod 内的不同容器之间共享工作过程中产生的文件,pod被删除后存储的数据也会消失。
缺省情况下,EmptyDir 是使用主机磁盘进行存储的,也可以设置emptyDir.medium 字段的值为Memory,来提高运行速度,但是这种设置,对该卷的占用会消耗容器的内存份额。
HostPath
这种会把宿主机上的指定卷加载到容器之中,当然,如果 Pod 发生跨主机的重建,其内容就难保证了。
这种卷一般和DaemonSet搭配使用,用来操作主机文件,例如进行日志采集的 EFK 中的 FluentD 就采用这种方式,加载主机的容器日志目录,达到收集本主机所有日志的目的。
NFS/GlusterFS/CephFS/AWS/GCE 等等
各种存储支持的方式不尽相同,NFS属于网络存储,能实现数据的共享,但是因为属于单节点,磁盘IO性能可能不足,glusterfs为分布式对象存储,数据的写入与读取性能相对来说比单节点要快,同时本身支持多节点的条带复制可保证数据的高可用,cephfs既支持块存储也支持对象存储,与glusterfs差不多,其他诸如云服务商提供的云存储也是一个不错的存储方案。
6.4、Kubernetes服务发现和负载均衡
内部使用者的服务发现
Kubernetes在一个集群内创建的对象或者在代理集群节点上发出访问的客户端我们称之为内部使用者。要把服务暴露给内部使用者,Kubernetes支持两种方式:环境变量和DNS。
环境变量
当kubelet在某个节点上启动一个Pod时,它会给这个Pod的容器为当前运行的Service设置一系列环境变量,这样Pod就可以访问这些Service了。一般地情况是{SVCNAME}_SERVICE_HOSTh和{SVCNAME}_SERVICE_PORT变量, 其中{SVCNAME}是Service名字变成大写,中划线变成下划线。比如Service "redis-master",它的端口是 TCP 6379,分配到的Cluster IP地址是 10.0.0.11,kubelet可能会产生下面的变量给新创建的Pod容器:
REDIS_MASTER_SERVICE_HOST= 10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR= 10.0.0.11
注意,只有在某个Service后创建的Pod才会有这个Service的环境变量。
DNS
一个可选的Kubernetes附件(强烈建议用户使用)是DNS服务。它跟踪集群中Service对象,为每个Service对象创建DNS记录。这样所有的Pod就可以通过DNS访问服务了。
比如说我们在Kubernetes 名字空间"my-ns"中有个叫my-service的服务,DNS服务会创建一条"my-service.my-ns"的DNS记录。同在这个命名空间的Pod就可以通过"my-service"来得到这个Service分配到的Cluster IP,在其它命名空间的Pod则可以用全限定名"my-service.my-ns"来获得这个Service的地址。
Pod IP and Service Cluster IP
Pod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,但Service Cluster IP就不一样了,没有网络设备为这个地址负责。它是由kube-proxy使用Iptables规则重新定向到其本地端口,再均衡到后端Pod的。我们前面说的Service环境变量和DNS都使用Service的Cluster IP和端口。
就拿上面我们提到的图像处理程序为例。当我们的Service被创建时,Kubernetes给它分配一个地址10.0.0.1。这个地址从我们启动API的service-cluster-ip-range参数(旧版本为portal_net参数)指定的地址池中分配,比如--service-cluster-ip-range=10.0.0.0/16。假设这个Service的端口是1234。集群内的所有kube-proxy都会注意到这个Service。当proxy发现一个新的service后,它会在本地节点打开一个任意端口,建相应的iptables规则,重定向服务的IP和port到这个新建的端口,开始接受到达这个服务的连接。
当一个客户端访问这个service时,这些iptable规则就开始起作用,客户端的流量被重定向到kube-proxy为这个service打开的端口上,kube-proxy随机选择一个后端pod来服务客户。这个流程如下图所示:
根据Kubernetes的网络模型,使用Service Cluster IP和Port访问Service的客户端可以坐落在任意代理节点上。外部要访问Service,我们就需要给Service外部访问IP。
外部访问Service
Service对象在Cluster IP range池中分配到的IP只能在内部访问,如果服务作为一个应用程序内部的层次,还是很合适的。如果这个Service作为前端服务,准备为集群外的客户提供业务,我们就需要给这个服务提供公共IP了。
外部访问者是访问集群代理节点的访问者。为这些访问者提供服务,我们可以在定义Service时指定其spec.publicIPs,一般情况下publicIP 是代理节点的物理IP地址。和先前的Cluster IP range上分配到的虚拟的IP一样,kube-proxy同样会为这些publicIP提供Iptables 重定向规则,把流量转发到后端的Pod上。有了publicIP,我们就可以使用load balancer等常用的互联网技术来组织外部对服务的访问了。
spec.publicIPs在新的版本中标记为过时了,代替它的是spec.type=NodePort,这个类型的service,系统会给它在集群的各个代理节点上分配一个节点级别的端口,能访问到代理节点的客户端都能访问这个端口,从而访问到服务。
通常情况下,service和pod仅可在集群内部网络中通过IP地址访问。所有到达边界路由器的流量或被丢弃或被转发到其他地方。从概念上讲,可能像下面这样:
Ingress是授权入站连接到达集群服务的规则集合
你可以给Ingress配置提供外部可访问的URL、负载均衡、SSL、基于名称的虚拟主机等。用户通过POST Ingress资源到API server的方式来请求ingress。 Ingress controller负责实现Ingress,通常使用负载平衡器,它还可以配置边界路由和其他前端,这有助于以HA方式处理流量。
为了使Ingress正常工作,集群中必须运行Ingress controller。 这与其他类型的控制器不同,其他类型的控制器通常作为kube-controller-manager二进制文件的一部分运行,在集群启动时自动启动。 你需要选择最适合自己集群的Ingress controller或者自己实现一个,社区通常使用nginx来实现。
开源界还有一个可以实现ingress的软件:traefik,相比较于nginx,traefik不需要额外再创建ingresscontroller,它本身已经实现了ingresscontroller功能,同时Træfɪk 是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。 它支持多种后台 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) 来自动化、动态的应用它的配置文件设置。
它具有以下特性:
· 非常快
· 无需安装其他依赖,通过Go语言编写的单一可执行文件
· 支持 Rest API
· 多种后台支持:Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, 并且还会更多
· 后台监控, 可以监听后台变化进而自动化应用新的配置文件设置
· 配置文件热更新。无需重启进程
· 正常结束http连接
· 后端断路器
· 轮询,rebalancer 负载均衡
· Rest Metrics
· 支持最小化 官方 docker 镜像
· 后台支持SSL
· 前台支持SSL(包括SNI)
· 清爽的AngularJS前端页面
· 支持Websocket
· 支持HTTP/2
· 网络错误重试
· 支持Let’s Encrypt (自动更新HTTPS证书)
· 高可用集群模式
· 清爽的界面
Traefik 拥有一个基于AngularJS编写的简单网站界面,可实时查看loadblancer相关情况。
6.5、Kubernetes各类插件
6.5.1、Web UI(仪表板):Dashboard
仪表板是一个基于Web的Kubernetes用户界面。您可以使用仪表板将集装箱化的应用程序部署到Kubernetes集群,对集装箱化的应用程序进行故障排除,并管理集群本身及其附带资源。您可以使用Dashboard获取群集上运行的应用程序的概述,以及创建或修改单个Kubernetes资源(例如部署,作业,DaemonSet等)。例如,您可以扩展部署,启动滚动更新,重新启动pod或使用部署向导部署新的应用程序。仪表板还提供有关群集中Kubernetes资源状态以及可能发生的任何错误的信息。
当前kubernetes官方提供的webui界面比较简单,诸如容器的直接启停、删除,审计日志,弹性伸缩等功能尚未实现,需要进行二次开发。
6.5.2、Kubernetes监控:Heapster
Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS。Kubernetes有个出名的监控agent—cAdvisor。在每个kubernetes Node上都会运行cAdvisor,它会收集本机以及容器的监控数据(cpu,memory,filesystem,network,uptime)。在较新的版本中,K8S已经将cAdvisor功能集成到kubelet组件中。每个Node节点可以直接进行web访问。
Heapster是一个收集者,将每个Node上的cAdvisor的数据进行汇总,然后导到第三方工具(如InfluxDB)。
框架图:
Heapster首先从K8S Master获取集群中所有Node的信息,然后通过这些Node上的kubelet获取有用数据,而kubelet本身的数据则是从cAdvisor得到。所有获取到的数据都被推到Heapster配置的后端存储中,并还支持数据的可视化。现在后端存储 + 可视化的方法,如InfluxDB + grafana。
6.5.3、Kubernetes日志插件:EFK
在初步完成Kubernetes集群架构的建立后,通过搭建一些监控组件,我们已经能够实现
· 图形化的监控每个node,pod的状态信息和资源情况
· 通过scale进行replicateSet的扩展和伸缩
· 通过kubectl logs 或dashboard去查看每个Pod的运行日志
但是,在分布式架构中节点的规模往往是很庞大的,一个典型的生产环境可能有几十上百个minion节点,在这种情况下就需要建立一套集中的日志监控和管理系统,简单的通过volumn外挂到存储的方式实现weblogic的日志输出到共享存储也是可行的,但这种方式的问题在于:
· 无法获取pod和container的信息
· 无法获取集群中其他节点的运行信息
因此还是需要寻找平台级别的架构方案.在kubernetes的官方文档中,
Kubernetes给出了几种日志方案,并给出Cluster-level logging的参考架构:
也就是说,我们自己启动运行的Pod的内部容器进程通过streaming的方式把日志输出到minion主机,然后由运行在相同主机的另外一个pod,logging-agent-pod把日志获取到,同时把日志传回Backend, Bankend实际上是基于不同的实现,比如Elasticsearch-logging,以及展示的kibana平台。
Kubernetes建议采用这种结点级别的logging-agent,并提供了其中的两种,一种用于Google Cloud Platform的Stackdriver Logging,另一种就是Elasticsearch,两种都是采用fluentd做为在结点上运行的Agent(日志代理)。
6.5.4、镜像仓库插件:Harbor
Harbor是由VMWare公司开源的容器镜像仓库。事实上,Harbor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制 ,AD/LDAP集成以及审计日志等。容器的核心在于镜象的概念,由于可以将应用打包成镜像,并快速的启动和停止,因此容器成为新的炙手可热的基础设施CAAS,并为敏捷和持续交付包括DevOps提供底层的支持。
而Harbor和Docker Registry所提供的容器镜像仓库,就是容器镜像的存储和分发服务。之所以会有这样的服务存在,是由于以下三个原因:
· 提供分层传输机制,优化网络传输
Docker镜像是是分层的,而如果每次传输都使用全量文件(所以用FTP的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层的UUID为标识,确定传输的对象。
· 提供WEB界面,优化用户体验
只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。
· 支持水平扩展集群
当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。
上面这些就是Docker Registry所完成的主要工作,而Harbor在此之上,又提供了用户、同步等诸多特性。
一、Harbor的安全机制
企业中的软件研发团队往往划分为诸多角色,如项目经理、产品经理、测试、运维等。在实际的软件开发和运维过程中,这些角色对于镜像的使用需求是不一样的。从安全的角度,也是需要通过某种机制来进行权限控制的。
Harbor为这种需求提供了用户和成员两种管理概念。
在Harbor中,用户主要分为两类。一类为管理员,另一类为普通用户。两类用户都可以成为项目的成员。而管理员可以对用户进行管理。
成员是对应于项目的概念,分为三类:管理员、开发者、访客。管理员可以对开发者和访客作权限的配置和管理。测试和运维人员可以访客身份读取项目镜像,或者公共镜像库中的文件。从项目的角度出发,显然项目管理员拥有最大的项目权限,如果要对用户进行禁用或限权等,可以通过修改用户在项目中的成员角色来实现,甚至将用户移除出这个项目。
二、Harbor的镜像同步
为什么需要镜像同步
由于对镜像的访问是一个核心的容器概念,在实际使用过程中,一个镜像库可能是不够用的,下例情况下,我们可能会需要部署多个镜像仓库:
· 国外的公有镜像下载过慢,需要一个中转仓库进行加速
· 容器规模较大,一个镜像仓库不堪重负
· 对系统稳定性要求高,需要多个仓库保证高可用性
· 镜像仓库有多级规划,下级仓库依赖上级仓库
更常用的场景是,在企业级软件环境中,会在软件开发的不同阶段存在不同的镜像仓库:
· 在开发环境库,开发人员频繁修改镜像,一旦代码完成,生成稳定的镜像即需要同步到测试环境。
· 在测试环境库,测试人员对镜像是只读操作,测试完成后,将镜像同步到预上线环境库。
· 在预上线环境库,运维人员对镜像也是只读操作,一旦运行正常,即将镜像同步到生产环境库。
· 在这个流程中,各环境的镜像库之间都需要镜像的同步和复制。
Harbor的镜像同步机制
有了多个镜像仓库,在多个仓库之间进行镜像同步马上就成为了一个普遍的需求。比较传统的镜像同步方式,有两种:
· 第一种方案,使用Linux提供的RSYNC服务来定义两个仓库之间的镜像数据同步。
· 第二种方案,对于使用IaaS服务进行镜像存储的场景,利用IaaS的配置工具来对镜像的同步进行配置。
这两种方案都依赖于仓库所在的存储环境,而需要采用不同的工具策略。Harbor则提供了更加灵活的方案来处理镜像的同步,其核心是三个概念:
· 用Harbor自己的API来进行镜像下载和传输,作到与底层存储环境解耦。
· 利用任务调度和监控机制进行复制任务的管理,保障复制任务的健壮性。在同步过程中,如果源镜像已删除,Harbor会自动同步删除远端的镜像。在镜像同步复制的过程中,Harbor会监控整个复制过程,遇到网络等错误,会自动重试。
· 提供复制策略机制保证项目级的复制需求。在Harbor中,可以在项目中创建复制策略,来实现对镜像的同步。与Docker Registry的不同之处在于,Harbor的复制是推(PUSH)的策略,由源端发起,而Docker Registry的复制是拉(PULL)的策略,由目标端发起。
Harbor的多级部署
在实际的企业级生产运维场景,往往需要跨地域,跨层级进行镜像的同步复制,比如集团企业从总部到省公司,由省公司再市公司的场景。这一部署场景可简化如下图:
更复杂的部署场景如下图:
转载于:https://blog.51cto.com/superleedo/2133869