企业级容器云PaaS解决方案【厚PaaS+轻应用+微服务】---(2)


二.资源管理

1.计算资源管理

  • 多集群资源管理
  • 资源分区管理
  • 资源配额+资源限制
  • 服务端口号管理

2.网络资源管理

  • 跨主机容器网络方案
  • 网络策略管理
  • 集群边界路由器Ingress管理
  • 集群DNS域名服务器管理

3.存储资源管理

  • k8s支持的Volume类型
  • 共享存储管理
  • CSI(Container Storage Interface)
  • 存储资源应用场景

4.镜像资源管理

  • 镜像生命周期管理
  • 镜像库多租户权限管理
  • 镜像库远程复制管理
  • 镜像库操作审计管理
  • 开源容器镜像库



1.计算资源管理

计算资源在云平台上指:应用程序运行所需要的资源,包括cpu+memory。

多租户=》资源共享+资源隔离

k8s体系中,对计算资源的管理可以在如下三个级别进行:

  • namespace
  • pod
  • container

同时根据应用计算资源的需求和限制,提供不同级别的服务质量(QoS)管理。



多集群资源管理

大型企业中,将企业各个数据中心的服务器全部纳入一个k8s集群中进行管理是不切实际的,主要要考虑到如下问题:

  • 需要容灾备份的DC提供服务,保证业务的高可用性
  • 多个DC之间分布在不同的地区,DC之间的网络时延较长
  • 服务器由不同的云服务商托管,互相之间无法直接互联互通
  • 多个DC之间的安全策略和安全等级不同

基于以上原因,通常需要部署多个k8s集群,来共同完成应用的发布和运行。

在容器云平台上,对资源的管理首先是将多个k8s集群纳入管理,以便能够对所有资源进行统一分配和管理。

将多个k8s集群纳入统一管理方案:

  1. 通过对接每个k8s集群的master,来完成集群内的资源管理和应用部署管理
    实现:容器云平台需要通过k8s master提供的restful api去控制整个集群,包括对各种资源的CURD操作;还需完成应用的多集群部署管理、跨集群水平扩展、集群的服务发现和自动灾难切换等多集群管理;并设置相应的网络策略,以保护各集群的master不被攻击。
  2. 使用统一的Federation控制平面(k8s的一个子项目)来对多个k8s集群进行他同意管理
    实现:https://jimmysong.io/kubernetes-handbook/practice/federation.html
    Federation的设计目标是对多个k8s集群进行统一管理,将用户的应用部署到不同地域的DC或是云环境中,通过动态优化部署来节约运营成本。
    federation架构中,引入一个位于所有k8s集群之上的Federation控制平面,屏蔽了后端的各k8s子集群,向客户提供了一个统一的管理入口。
    Federation控制平面封装了多个k8s集群的master角色,提供了一个统一的master,包括Federation API Server、Federation Controller Manager,用户可以像操作单个集群一样操作Federation;还统一管理了全部k8s集群的DNS、ConfigMap,并将数据保存在集中的etcd数据库中。
    问题:
  • 为确保所有集群的运行状态符合预期,Federation控制平面会持续监控所有集群,导致网络开销和成本增加
  • Federation控制平面是“中心化”的总控节点,一旦出现问题,就可能会影响到所有集群。
  • Federation出现较晚,不是很成熟,目前k8s中的资源对象只有一部分在Federation中是可用的。


资源分区管理

在容器云平台纳管所有k8s集群之后,平台管理员就可以进行资源分配的工作,为多个租户提供应用部署运行环境了。

在一个k8s集群中,提供计算资源的的实体被称为Node,即工作节点。
Node可为物理机服务器,也可为虚拟机服务器。
每个Node都提供了计算(cpu+memory)+网络+存储三大资源,应用系统则是这些资源的使用者。

为了支持多租户模型,k8s使用namespace机制将一个集群划分为多个虚拟分区,进而实现资源隔离。类似互联网的域名,ns的名称可以看做是一级域名,在ns中部署的服务名则可看做是二级域名。
如:

  • myweb.default.svc
  • myweb.test.svc

ns的“分区”是逻辑上的,ns并不与特定的物理资源进行绑定。
多个ns下的应用可以共享相同的Node资源,将“小而轻”的容器应用以更加合理的方式在物理资源中进行调度。

对于某些独享资源的用户,则需为其划分固定的Node范围。
k8s使用【标签label+标签选择器label selector】来实现所有资源对象的角色划分及选择。
通过给Node设置特定的Label,就可以标注该Node属于哪个租户。
在总体资源不够充分的情况下,也可将一个Node设置多个Label,让多个租户共享。



资源配额+资源限制

在共享资源的环境下,管理员需要为租户设置更精细的资源配额和资源限制的管理。
各租户在自己的资源分区上部署应用时,将只能使用被分配到的总资源数量。
容器云平台应该将持续监控和统计各租户对资源的使用情况,为未来是否应该为租户增加资源或是减少资源提供依据。

在k8s集群中,为了完成【资源的配额管理+资源限制管理】,可从ns、pod、container三个级别进行管理。

  1. container级别:type=container=>kind: LimitRanger(ns)
    可对计算资源cpu+memory进行管理。
    对他们的配置项包括两种:
    资源请求ResourceRequest【defaultRequest,表示容器希望被分配到的可完全保证的资源量,Requests的值会被提供给k8s调度器scheduler,以便于优化基于资源请求的容器调度。
    资源限制ResourceLimits【default,Limits是容器能用的资源上限,这个上限的值会影响在节点上发生资源竞争是的解决策略。
    max+min+maxLimitReauestRatio
  2. pod级别:type=pod=>kind: LimitRanger(ns)
    由于一个pod可以包含多个container,所以可以对pod所含的全部容器所需的cpu+memory进行管理。
    在k8s中,可以通过创建LimitRange资源对象完成设置,LimitRange对象作用于namespace。
    max+min+maxLimitReauestRatio
  3. namespace级别:kind: ResourceQuota
    可对ResourceQuota资源对象配置,提供一个总体上的资源使用量限制:
    一方面可以设置该ns中pod可以使用到的计算资源(cpu+memory)的总量上限;
    另一方面可以限制该ns中,某种类型对象的总数量上限(包括可以创建的pod、rc、svc、secret、configmap、pvc等对象的数量限制)
    compute-resources.yaml中设置了ns为default的所有容器的cpu request综合不超过1,上限为2等。
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
  namespace: default
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1GB
    limits.cpu: "2"
    limits.memory: 2GB
    pods: "4'
    configmaps: "10"
    persistentvolumeclaims: "4"
    replicationcontrollers: "20"
    secrets: "10"
    services: "10"
    services.loadbalancers: "2"

在一个定义了ResourceQuota的k8s集群中部署了许多符合资源条件的容器应用之后,系统会自动统计出已经使用的资源数量。
kubectl describe quota compute-resources



服务端口号管理

对于租户来说,只要服务的名称保持唯一,不同的服务可以使用相同的端口号。
但是,对于需要对外提供服务的service来说,需要映射服务端口号到Node上(NodePort模式)。
容器云平台应该对映射到Node上的服务端口号提供统一管理,以保证各服务的NodePort端口号不会冲突,同时要确保与Node上其它应用监听的端口号不会产生冲突。

在容器云平台上,对端口号port的管理至少应该包含以下功能:

  • 可以查看当前对外提供服务的NodePort列表
  • 在部署新的服务且用户输入NodePort时,平台应该提示该端口号是否已被之前部署的服务使用了。
  • k8s集群外的服务可以被作为虚拟的svc纳入k8s集群中,统一管理其在物理机上监听的端口号。



2.网络资源管理

网络资源作为容器云平台的基础设施,需要为多租户的微服务之间的互联互通提供保障。
在基于k8s的容器云平台上,对于网络资源的需求通常包含依稀阿济格方面:

  • 跨主机的容器之间的网络互通
  • 多租户之间和服务之间的网络隔离
  • 集群边界路由器Ingress管理
  • 集群DNS域名服务管理

主流的开源网络方案解决。



跨主机容器网络方案

k8s网络设计的一个基本原则:每个pod都拥有一个独立的ip地址,而且假定所有的pod都在一个可以直接连通的、扁平的网络空间中,不管他们是否运行在同一个Node(宿主机)中,都可以直接通过对方的ip进行访问。
即:k8s的要求是各Node之间的容器网络能够互通,但k8s本身不提供跨主机的容器网络解决方案。

公有环境(aws、azure、gce、阿里云)通常都提供了容器网络解决方案,但在私有云环境下,任然需要容器云平台为不同的用户提供容器网络解决方案。

  1. Overlay网络解决方案
    目前,为容器设置overlay网络是最主流的跨主机容器网络解决方案。
    overlay网络是指在不改变现有网络配置的前提下,通过某种额外的网络协议,将原ip报文封装起来,形成一个逻辑上的新网络。
    overlay网络为容器云平台提供了灵活的配置方案,能够应对更多的业务需求。

  2. CNI插件解决方案
    CNI:Container Network Interface,容器网络接口。
    在k8s上建议通过CNI插件的方式部署容器网络。
    CNI是CNCF基金会下的一个项目,由一组用于配置容器的网络接口的规范和库组成,现已被k8s、rkt、Apache Mesos、Cloud Foundry和Kurma等项目采纳。
    CNI定义的是容器运行环境与网络插件之间的接口规范,仅关心容器创建时的网络配置和容器销毁时网络资源的释放,目的是提供一个普适的容器网络解决方案。
    通过一个JSON Schema定义CNI插件提供的输入和输出参数。
    一个容器可以通过绑定多个CNI插件加入多个网络中。
    目前,Flannel、Contiv Networking、Project Calico、Weave、SR-IOV等开源项目均为k8s CNI提供了具体的插件实现方案。

在CNI模型中只涉及两个概念:容器和网络。

  • 容器:拥有独立linux网络命名空间的环境,例如使用docker或rkt创建的容器。
    关键是容器需要拥有自己的linux网络命名空间,这是加入网络的必要条件。
  • 网络:表示可以互联的一组实体,这些实体拥有各自独立的、唯一ip地址,可以是容器、物理机或者其他网络设备(如路由器等)。

对容器网络的设置和操作都通过插件进行具体的实现,CNI插件包括两种类型:

  • CNI Plugin
    CNI Plugin负责为容器配置网络资源
  • IPAM Plugin
    IPAM Plugin负责对容器的IP地址进行分配和管理。
    IPAM Plugin作为CNI Plugin的一部分,与CNI Plugin一起工作。


网络策略管理

k8s从1.3版本开始引入了Network Policy机制,主要用于对容器间的网络通信进行限制和准入控制,作用于ns之间和服务之间
在k8s中使用==NetworkPolicy资源对象(自己编写yaml网络策略定义配置文件)设置网络策略,但仅定义一个网络策略是无法完成实际的网络隔离的,还需要一个策略控制器(由三方网络组件提供)==来实现。
策略控制器由第三方网络组建提供,目前calico、romana、weave等开源项目均支持k8s网络策略的具体实现。
网络策略包括默认策略和自定义策略,以完成粗粒度和细粒度的策略设置。
通过默认策略和自定义策略的组合设置,就能实现在网络层面上对租户之间和服务之间进行禁止访问或允许访问的策略限制,能够起到类似于在防火墙上设置黑白名单的效果。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
      cidr: 172.17.0.0/6
      except: 
      - 172.17.1.0/24
    - namespaceSelector:
       matchLabels:
        project: myproject
    - podSelector:
       matchLabels:
        role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
       cidr: 10.0.0.0/24
     ports:
     - protocol: TCP
       port: 5978


集群边界路由器Ingress管理

在k8s集群部,容器默认以srv的形式提供服务,由kube-proxy实现srv到容器的负载均衡功能
service的概念仅作用于k8s集群内部,集群外的客户端应用默认无法知道service名称的意义,也无法直接使用这些服务。
对于需要为k8s集群外的客户端提供服务的service,可以通过Ingress将服务暴露出去,并且如果该集群(网站)拥有真实域名,则还能将service直接与域名进行对接。

在k8s中可以通过对Ingress资源对象的配置,将不同URL的访问请求转发到后端不同的service上。
k8s将【一个Ingress资源对象的定义 + 一个具体的Ingress Controller】相结合来实现7层负载均衡器。
Ingress Controller在转发客户端请求到后端服务时,将跳过kube-proxy提供的4层LB的功能,直接转发到service的后端pod(endpoints),以提高网络转发效率。

一.常用的Ingress策略:

  1. 将请求转发到单个后端服务上(仅backend)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: test-ingress
spec:
 backend:
  serviceName: myweb
  servicePort: 8080
  1. 将到同域名不同URL的请求转发到不同的后端服务上(rules+backend)
    这种配置常用于一个网站通过不同的路径提供不同服务的场景。
    例如:/web表示访问Web页面,/api表示访问API接口,对应到后端的两个服务。
    将对URL【mywebsite.com/web】的访问请求转发到【web-service:80】服务上。
    将对URL【mywebsite.com/api】的访问请求转发到【api-service:80】服务上。
apiVersions: extensions/v1beta1
kind: Ingress
metadata:
 name: test-ingress
spec:
 rules:
 - host: mywebsite.com
   http:
    paths:
    - path: /web
      backend:
        serviceName: web-service
        servicePort: 80
    - path: /api
      backend:
        serviceName: api-service
        servicePort: 8081
        
  1. 将不同域名的请求转发到不同的后端服务上(rules+backend)
    常用于一个网站通过不同的域名或虚拟主机名提供不同服务的场景。
    例如:foo.com域名由foo-srv提供服务,bar.com域名由bar-srv提供服务。
apiVersions: extensions/v1beta1
kind: Ingress
metadata:
 name: test-ingress
spec:
 rules:
 - host: foo.com
   http:
    paths:
    - backend:
        serviceName: foo-srv
        servicePort: 80
 - host: bar.com
   http:
    paths:
    - backend:
        serviceName: bar-srv
        servicePort: 80
  1. 不使用域名的转发规则(rules+backend)
    用于一个网站不使用域名直接提供服务的场景,此时通过任意一台运行ingress-controller的Node都能访问到后端的服务。
    例如:将/demo的访问请求转发到webapp:8080/demo服务上的Ingress策略配置如下:
apiVersions: extensions/v1beta1
kind: Ingress
metadata:
 name: test-ingress
spec:
 rules:
 - http:
    paths:
    - path: /demo
      backend:
        serviceName: webapp
        servicePort: 8080

注意:在使用无域名的Ingress转发规则是,将默认使用HTTPS安全协议进行转发。
如需使用费安全的HTTP,则需调整Ingress Controller的配置,通常在一个安全的网络环境下进行配置。


二.常用的Ingress Controller
目前针对k8s Ingress提供具体Controller的开源工具包括Nginx、HAProxy和Traefik。

  1. Nginx
    Nginx是一款流行的反向代理服务器软件,同时也是一个全栈的web服务器,可以提供web服务器、http代理服务器、邮件代理服务器和负载均衡器功能。
    目前k8s社区主要维护基于Nginx的Ingess Controller(https://github.com/kubernetes/ingress-nginx),其主要机制是:通过监听用户设置的Ingress策略,自动完成Nginx相关upstream配置的生成和在线更新。
    Nginx特点如下:
    -工作在网络7层
    -模块化,有丰富的第三方功能模块支持
    -支持更强大的正则配置规则
    -配置文件热更新
    -除了作为LB,还可作为静态web服务器、缓存服务器。

  2. HAProxy
    HAProxy为另一款流行的开源代理服务器软件,使用C语言编写而成,提供高可用性、负载均衡、4层和7层代理服务器功能。
    目前面向k8s的HAProxy Ingress Controller在github上维护:https://github.com/jcmoraisjr/haproxy-ingress

  3. Traefik
    Traefix(https://traefik.io)是近两年出现的面向微服务架构的前端负载均衡器,它 能够实现自动感知k8s集群中service后端容器的变化,自动动态刷新配置文件,以快速实现服务发现。

Nginx、HAProxy和Traefik都能够用于k8s的Ingress Controller,总结对比如下:

Nginx HAProxy Traefik
性能 转发效率高 HTTP转发效率最高 吞吐率约为Nginx的85%
配置难易度 简单,支持强大的正则匹配规则 简单 简单,与微服务架构对接最好
负载均衡机制 一般 会话保持和健康检查机制全面 会话保持和健康检查机制全面
社区活跃度 活跃 一般 一般
功能使用面 代理服务器、web服务器、邮件服务器、LB等 代理服务器、LB proxy、LB


集群DNS域名服务器管理

在k8s集群推荐使用service name作为目的服务的访问地址,这就需要在一个集群范围内的DNS服务来完成从服务名到ClusterIP的解析工作。

一 集群内的DNS服务
在k8s集群内,DNS作为特殊的系统级服务,首先需要在Service ClusterIP地址范围内指定一个固定的IP地址;然后需要在每台Node的kubelet启动参数上指定--cluster-dns= --cluster-domian=cluster.local
在经过这样的设置后,kubelet会在每个pod内部为其设置DNS服务器的配置,容器内的/etc/resolv.conf配置文件内容如下:

search default.svc.cluster.local svc.cluster.local svc.cluster.local cluster.local
nameserver 169.169.0.100
options ndots:5

这就为容器环境设置了集群范围内的DNS服务器169.169.0.100,由其完成服务名与服务ClusterIP的解析。
接下来,需要部署这个集群内的DNS服务,DNS服务作为k8s的addon组件发布,经历了从skyDNS到kubeDNS再到coreDNS的演进历程。

  1. skyDNS
  2. kubeDNS
  3. CoreDNS

二 自定义DNS服务器和上游DNS服务器
k8s集群内部的DNS服务主要用于解析集群内各个service的服务名,并且这个DNS服务的地址在整个集群中需要固定下来,不能与物理网络的真是DNS服务器互相干扰
同时,很多企业在实际生产环境中都有自己的私有域名区域,例如,可能希望在集群内解析其内部的".corp"域名。
从k8s v1.6版本开始,就可以在k8s集群内配置私有DNS区域(通常被称为存根域Stub Domain),并在k8s集群配置上游域名服务

  1. k8s默认的域名解析流程
    k8s目前在pod定义中支持两个DNS策略:DefaultClusterFirstdnsPolicy默认为ClusterFirst
    如果将dnsPolicy设置为ClusterFirst,则DNS查询会被发送到集群DNS服务(由skyDNS、kubeDNS或CoreDNS提供具体实现)。
    集群DNS服务负责以集群域名为包含域名后缀的服务名,进行从服务名到ClusterIP地址的解析。
    客户端对其它域名的查询则会被转发给节点上定义的上游域名服务器。

  2. 自定义DNS服务器地址
    k8s从1.6版本开始,便可使用ConfigMap指定 【自定义的存根域(私有DNS域):stubDomains【上游DNS Server:upstreamNameservers

  3. 通过域名访问集群外的服务—自定义DNS记录
    在企业DC环境下,尝尝还需将某些主机的IP地址设置为某个内部域名,以支持客户端应用仅需配置域名就能访问k8s集群外的服务。
    kubeDNS和CoreDNS均支持用户自定义的DNS记录。
    以CoreDNS为例,可以配置一个新的custom-hosts文件,在其中定义域名(myweb.com)与IP地址的记录。

myweb.com  IN  SOA  sns.dns.icann.org noc.dns.icann.org
myweb.com  IN  NS  a.iana-servers.net
myweb.com  IN  NS  b.iana-servers.net
srv1.myweb.com  IN  A  192.168.18.4

然后通过CoreDNS的配置文件Corefile指定对该自定义域名文件的引用。

{
  ...
  file/etc/coredns/custom-hosts
  ...
}

通过上述配置即可实现在pod内对域名srv1.myweb.com的访问了。
通过k8s中service的DNS解析机制、k8s外DNS服务器的设置和自定义DNS记录等机制,可以实现对k8s集群内各容器应用所需的DNS服务进行完整管理,以及与物理网络环境的DNS服务进行对接。




3.存储资源管理

在基于k8s的容器云平台上,对存储资源的使用需求包含以下几个方面:

  • 应用配置文件、秘钥管理
  • 应用的数据持久化存储
  • 在不同的应用间共享数据存储


k8s支持的Volume类型

k8s的volume对象即为针对上述问题的解决方案。

volume类型:

  • 临时目录emptyDir:随着pod的销毁而销毁
  • 配置类:将配置以volume的形式挂载到pod内
    ConfigMap:将保存在ConfigMap资源对象中的配置文件信息挂载到容器内的某个目录下。
    Secret:将保存在Secret资源对象中的密码秘钥等信息挂载到容器内的某个文件中。
    downwardAPI:将downwardAPI的数据已环境变量或文件的形式注入到容器中。
    gitRepo:将某Git代码库挂载到容器内的某个目录下。
  • 本地存储类
    hostPath:将宿主机的目录或文件挂载到容器内进行使用。
    local:k8s从v1.9版本引入,将本地存储以PV的形式提供给容器使用,并能够实现存储空间的管理。
  • 共享存储类(PV和PVC)
    PV(persistent volume):将共享存储定义为持久存储卷,可以被多个容器应用共享使用。
    PVC(persistent volume claim):用户对存储资源的一次申请,PVC申请的对象是PV,一旦申请成功,应用就能够像使用本地目录一样使用共享存储。


共享存储管理

共享存储主要用于多个应用都能够使用的存储资源,例如:NFS存储、光纤存储、GlusterFS共享文件系统等。
在k8s系统中通过使用PV/StorageClass和PVC来完成定义,并通过volumeMount挂载到容器的目录或文件进行使用。
PV:对存储资源的抽象
PVC:声明对存储资源的需求

k8s的共享存储供应模式包括静态模式和动态模式,资源供应的结果就是创建好的PV。

  • 静态模式:集群管理员手工创建许多PV,在定义PV时需要设置后端存储的特性。

container: mountVolume ->挂载pod的volume进容器内使用
pod: volume ->引用PVC
PVC:绑定PV
PV:对应后端物理存储(静态模式下需手工创建PV)

  • 动态模式:集群管理员无需手工创建PV,而是通过对StorageClass的设置对后端存储进行动态描述,标记为某种“类型Class”。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及与PVC的绑定。PVC可以声明Class为"",说明该PVC进制使用动态模式。

container: mountVolume ->挂载pod的volume进容器内使用
pod: volume ->引用PVC
PVC:选择StorageClass
StorageClass:描述后端存储(动态资源供应下,通过StorageClass和PVC完成资源的动态绑定,系统自动生成PV)

对于不同的类型的共享存储,有的需要以静态模式进行管理(如NFS),有的可以以动态模式进行管理(如GlusterFS)。

k8s支持的共享存储类型:

  • FC(Fiber Channel):光纤通道存储
  • Flocker:开源共享存储解决方案
  • NFS:网络文件系统
  • iSCSI:iSCSI存储
  • Ceph FS和Ceph RBD(Rados Block Device):Ceph文件系统和RBD快存储
  • Cinder:OpenStack Cinder块存储
  • GlusterFS:开源分布式文件系统
  • vSphere:VMware的VMDK存储卷
  • Quobyte:统一文件存储、块存储和对象存储的数据中心文件系统
  • Portworx:容器定义存储是共享存储解决方案
  • Dell EMC ScaleIO:Dell EMC提供的一种软件定义存储解决方案
  • StorageOS:一个提供统一的存储层视图的容器解决方案。
  • gcePersistentDisk:GCE公有云提供的PersistentDisk
  • AWSElasticBlockStore:AWS公有云提供的ElasticBlockStore
  • AzureFile:Azure公有云提供的File
  • AzureDisk:Azure公有云提供的Disk


CSI(Container Storage Interface)

CSI是k8s v1.9版本开始引入的,旨在在容器和共享存储之间建立一套标准的存储访问接口。

在CSI之前,在k8s集群内提供共享存储服务是通过一种被称为“in-tree”的方式实现,该方式要求存储供应商的代码逻辑集成在k8s代码中运行,与k8s为紧耦合关系。

v1.2版本开始开发了FlexVolume模式,通过调用外部存货从供应商提供的可执行程序完成对共享存储的设置,但是依赖外部可执行程序的模式任然有两个复杂的问题需要解决:

  • 存储插件需要被安装在宿主机上,对os依赖性很强,需要安装相关的依赖包和第三方工具,使得插件的安装变得复杂
  • k8s在调用宿主机的二进制文件时,需要宿主机的root权限,存在安全隐患。

CSI规范用于将存储供应商的代码与k8s的代码完全解耦,存储插件的代码由供应商自行维护。
其中,k8s提供以下sidecar辅助容器:

  • External-attacher:监听VolumeAttachment对象并触发ControllerPublish和ControllerUnPublish操作的容器
  • External-provisioner:监听PersistentVolumeClaim对象并触发对CSI Endpoint的CreateVolume和DeleteVolume操作
  • Driver-register:使用kubelet注册CSI驱动程序的容器,并将NodeId添加到Node的annotation中。

存储供应商可以使用这些组件作为Sidecar配置在存储加减容器旁共同工作,让CSI驱动无须感知他们的存在。
CSI驱动的代码则被完全交给第三方存储供应商自行维护。

对于CSI模式提供的存储资源的使用,同样遵循k8s的PV和PVC模型,也可通过静态资源供应(PVC+PV)或动态资源供应(PVC+StorageClass)对存储资源进行管理。

静态资源管理(PVC+PV):

  1. 对于NFS共享存储,可以使用静态资源供应预先创建一个PV
apiVersion: v1
kind: PersistentVolume
metadata:
 name: data-nfsplugin
 labels:
  name: data-nfsplugin
 annotations:
  csi.volume.kubernetes.io/volume-attributes: '{"server": "192.168.18.6", "share": "/nfs"}'
spec:
 accessModes:
 - ReadWriteOnce
 capacity:
  storage: 100MB
 csi:
  driver: csi-nfsplugin
  volumeHandle: data-id
  1. 然后通过PVC对存储资源进行申请
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: data-nfsplugin
spec:
 accessModes:
 - ReadWriteOnce
 resources:
  requests:
   storage: 100MB
 selector:
  matchExpressions:
  - key: name
    operator: In
    values: ["data-nfsplugin"]

动态资源管理(PVC+StorageClass):

  1. 对于Ceph RBD共享存储,可以使用动态资源供应创建一个StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-rbd
provisioners: csi-rbdplugin
parameters:
  monitors: 192.168.18.200:6789
  pool: kubernetes
  csiProvisionerSecretName: csi-ceph-secret
  csiProvisionerSecretNamespace: default
reclaimPolicy: Delete
  1. 然后使用PVC申请存储资源
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
   requests:
    storage: 5Gi
  storageClassName: csi-rbd


存储资源应用场景

容器应用需根据应用系统的特点,综合考虑容器应用对存储类型、存储性能及数据高可用性等方面的要求,选择最适合存储资源类型。
常见的存储资源应用场景包括如下三类:

  • 将存储放置于容器内部
  • 将存储挂载在外部宿主机上
  • 使用外部共享存储



4.镜像资源管理

容器云平台除了应该提供计算、网络、存储资源的管理功能,还应该提供容器镜像的管理功能。
镜像作为容器应用的基石,需要在镜像库中同一管理,包括对镜像声明周期的管理、对镜像看多租户权限的管理、对镜像库远程复制的管理和对镜像库操作审计的管理。



镜像生命周期管理

应用的容器镜像作为应用程序部署包,应具备完善的生命周期管理。
在容器云平台上,通常基于持续集成工作流,由DevOps工具链完成镜像的自动化构建过程,并且记录每次构建的镜像的版本信息。



镜像库多租户权限管理

为了让多租户都能够对各自的应用镜像进行管理,镜像库需要为不同的租户设置不同的镜像访问权限,包括基于角色的权限控制。
对镜像库多租户的权限管理应包括如下功能:

  • 不同租户的镜像相互隔离
  • 不同的租户对镜像拥有不同的权限


镜像库远程复制管理

在多DC或跨地域多站点的环境下,为了提高多地区镜像的下载效率,至少需要两级镜像库的设置:总镜像库和子镜像库。
镜像的远程复制能以准实时的方式进行同步,即当在总镜像库中上传了新的镜像或更新了已有镜像时,能够自动触发远程复制操作。



镜像库操作审计管理

在镜像库中对镜像的操作CRUD等,应当保留操作记录,用于审计管理。



开源容器镜像库

常见开源容器镜像库:

  1. Docker Registry
    最流行的开源私有镜像仓库,以镜像格式发布,在下载后运行一个Docker Registry容器即可启动一个私有镜像库服务:
    docker run -d --name registry -p 5000:5000 -v /storage/registry:/tmp/registry registry:2
    其最大的优点是简单,只需运行一个容器就能集中管理一个集群范围内的镜像,其它机器就都能从该镜像库下载镜像了。
  2. VMware Harbor
  3. Sonatype Nexus
  4. SUSE Portus

特性对比:
以上开源容器镜像库都支持TLS和RESTful API。

你可能感兴趣的:(云计算,paas,微服务,kubernetes)