kubernetes服务管理

1. 源起

PaaS上托管的应用经常需要使用诸如数据库,分布式缓存,应用服务器之类的通用的基础设施软件,例如用户要在PaaS上托管一个Web应用的后端,那么肯定会需要MariaDB,Tomcat或者Nginx。传统的方式是在Web应用的编排里把应用依赖的MariaDB/Tomcat/Nginx也创建出来,进行相应的配置并与Web应用集成,这使开发者在开发应用的同时还需要花费大量时间去解决应用所依赖的基础设施软件的部署和配置,增加了应用托管和迁移的成本。

在理想的PaaS环境中,应用开发者应该专注于应用本身的开发,通用的基础设施软件应该由PaaS平台以服务的形式来提供,其可用性和按需动态伸缩能力也应该由平台自身来保障,应用和服务之间应该是松耦合且能够动态集成的;开发者以服务的方式按需消费应用所依赖的基础设施软件,而不需要了解服务的实现细节,也不用担心服务的可用性。

2. 服务目录简介

Kubernetes的服务管理基于Kubernetes的孵化项目Kubernetes Service Catalog project。Service Catalog(服务目录)的目标是通过其使得 K8s 上部署的应用可以通过 Service Broker轻松使用外部托管软件产品,例如由云提供商提供的数据存储服务。Service Broker其实并不是kubernetes原生的概念,它源自于Pivotal公司在2011年开源的PaaS(Platform-as-a-Service)项目Cloud Foundry。

它提供列表清单、提供(provision)和绑定(binding)来自服务代理(Service Brokers)的外部托管服务,而不需要关心如何创建或管理这些服务的详细情况。

Service Catalog的原理是通过Open Service Broker API规范集成Service Broker(服务中介),由Service Broker(服务中介)管理服务的创建和管理。OSB API规范是Cloud Foundry Service Broker API的演进。Service Broker 也是由一个标准化组织推动:open service broker

Service broker是由第三方提供和维护的一组托管服务的端点(endpoint),该第三方可以是AWS,GCP或Azure等云提供商。

通过Service Catalog,集群运营者可以浏览由Service Broker提供的托管服务列表,提供的托管服务实例,并与其绑定,使其可被Kubernetes集群中的应用程序所使用。

这种底层机制允许在Kubernetes中运行的应用程序与它们使用的服务之间松耦合。 Service Broker(服务中介)是一个黑盒实体,可以运行在Kubernetes外。 服务中介允许应用专注于自己的业务逻辑,将服务的管理交给服务中介。

目前AWS和阿里云两大共有与平台支持服务目录功能,可以通过如下链接了解:

2.1 术语解析

Service Catalog有一些常用的术语:

  • 应用(Application):服务目录中的服务与Kubernetes中的“服务”是不同的。为避免混淆,我们使用“应用”表示Kubernetes的服务实例;
  • 绑定或服务绑定(Binding):服务实例和应用之间的链接。它表示应用引用和使用特定服务实例的意图;
  • 中介或服务中介(Broker):一个实体,用于管理一组或多个服务,可以通过网络端点访问服务中介;
  • 凭证(Credentials):应用与服务实例通信所需的信息;
  • 实例或服务实例(Instance):服务的实现称为服务实例;
  • 服务类或服务(Service Class):Service Broker(服务中介)提供的一种服务类型;
  • 计划或服务计划(Plan):服务类型的变体。例如,服务可以暴露一组计划,它们提供不同程度的服务质量(QoS);

2.2 Service Catalog整体架构设计

服务目录的设计如下图所示:
这里写图片描述

作为服务目录的核心,与Kubernetes核心一样,它是一个apiserver和一个controller-manager,使用etcd进行存储。

服务目录apiserver是用于存储组件RESTful的前端,通过扩展apiserver实现,并使用Kubernetes 1.7+中提供的聚合层来呈现其API。系统的用户及系统的其他组件与API服务器进行交互,以便在服务目录资源模型上执行CRUD类型的操作。与Kubernetes本身一样,kubectl命令行工具可用于与服务目录资源模型进行交互。

控制器是服务目录的大脑。它监视资源模型(通过apiserver上watches接口),并根据其检测到的更改采取适当的操作使API资源的当前状态与用户期望的最终状态相一致;例如,当用户创建一个ClusterServiceBroker资源时,API Server将在Etcd里存入一个资源并产生一个事件,然后Controller将接受这个事件并从该资源所指向的Service Broker中请求Catalog信息。

服务目录apiserver后面的存储组件可以是etcd或第三方资源(ThirdPartyResources,即TPRs)。 rest.storage接口抽象正在使用的特定持久存储设备。当使用etcd时,etcd的实例将与Kubernetes的etcd实例不同,这意味着,服务目录将具有与Kubernetes不同的持久存储。当使用TPRs时,这些资源将被存储在Kubernetes中,因此不需要单独的持久存储。到目前为止,API服务器只能使用etcd作为其持久存储。在不久的将来,API服务器的rest.storage接口将添加对TPRs的支持。

服务目录资源模型在pkg/apis/servicecatalog/types.go的文件中定义,不同版本都在自己的pkg/apis/servicecatalog /的子目录中。

3. 场景样例

应用程序开发人员编写基于Kubernetes集群的应用程序,他们希望使用消息队列作为其应用程序的一部分。但是,他们不想自己配置和管理这个服务服务。恰好,有一家云提供商通过其服务代理(Service Broker)提供消息队列服务。

集群运营商可以设置Service Catalog并使用它与云提供商的Service Broker进行通信,以调配消息排队服务的实例并使其可用于Kubernetes集群内的应用程序。因此,应用程序开发人员不需要关心消息队列的实现细节或管理,可以简单地像服务一样使用它。

4. Service Catalog提供的API资源

这里写图片描述

如上图所示,Service Catalog安装servicecatalog.k8s.io API并提供以下Kubernetes资源:

  • ClusterServiceBroker:作为service broker的群集内代理,封装其服务器连接详细信息。这些由集群运营者创建和管理,希望使用broker服务在其集群中提供新类型的托管服务。

  • ClusterServiceClass:由特定service broker提供的托管服务。将新ClusterServiceBroker资源添加到群集时,Service catalog controller将连接到service broker以获取可用托管服务的列表清单。然后它会创建新的ClusterServiceClass资源,与每个托管服务相对应。

  • ClusterServicePlan:托管服务的特定产品。例如,托管服务可能有不同的可用套餐,例如免费套餐或付费套餐,或者可能有不同的配置选项,例如使用SSD存储或拥有更多资源。同向群集添加ClusterServiceClass一样,当添加一个新的ClusterServiceBroker时,Service Catalog会创建一个新的ClusterServicePlan资源,与每个托管服务可用的每个服务套餐对应。

  • ServiceInstance:一个提供好的ClusterServiceClass实例。这些是由集群运营者创建的托管服务的特定实例,供一个或多个集群内应用程序使用。当创建一个新的ServiceInstance资源时,Service Catalog controller连接到相应的服务代理并指示它提供服务实例。

  • ServiceBinding:访问ServiceInstance的凭据。由想让他们的应用利用ServiceInstance的集群集运营者创建。创建之后,Service Catalog controller将创建一个与此服务实例对应的Kubernetes的Secret,包含此服务实例的连接详细信息和凭证 ,可以挂载到Pod中。

通过以上这些api资源。 Service Catalog主要提供了如下功能:

  • Service Broker(服务中介)注册到Kubernetes上;
  • Service Broker(服务中介)指定一组服务(或这些服务的变体),提供给Kubernetes用户;
  • Kubernetes用户可以发现可用的服务;
  • Kubernetes用户可以请求新的服务实例;
  • Kubernetes用户可以链接服务实例到一组Pods上;

5. 实践

实践分四部分:

  • Service Catalog的部署;
  • Broker的部署;
  • Broker的注册;
  • 使用;

相关Broker的示例代码请见github

5.1 Service Catalog部署

通过helm部署

<1>chart包下载:
这里下载Service Catalog的chart文件。

<2>修改一些配置文件方便部署:
修改values.yaml:

# Default values for Service Catalog
# service-catalog image to use
image: daocloud.io/liukuan73/service-catalog:v0.1.22
# imagePullPolicy for the service-catalog; valid values are "IfNotPresent",
# "Never", and "Always"
imagePullPolicy: IfNotPresent

rbacEnable: false

      persistence:
        enabled: true
        ## If defined, storageClassName: <storageClass>
        ## If set to "-", storageClassName: "", which disables dynamic provisioning
        ## If undefined (the default) or set to null, no storageClassName spec is
        ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
        ##   GKE, AWS & OpenStack)
        ##
        storageClass: "rbd"

  enablePrometheusScrape: true

备注:

  • 我的集群没有开启rbac,故rbacEnable设置为false
  • 使用我已创建的名为“rbd”的storageclass创建pvc和pv做数据持久化

修改tepmplates/apiserver-deployment.yaml:

        image: daocloud.io/liukuan73/etcd:latest
        imagePullPolicy: IfNotPresent

<3>配置kube-apiserver 启用聚合层(Aggregation Layer)

关于聚合层的一些知识:
聚合层运行在apiserver进程内部,允许用户为集群安装额外的Kubernetes风格的API,扩展core API的功能。聚合层需要启动apiserver的时候开启方可使用。

在用户注册扩展资源之前,聚合层什么也不做。用户要注册API,必需向系统中添加一个APIService对象,用来声明API的URL路径以及处理请求的后端APIService。此后,聚合层会将发往那个路径的所有请求(e.g. /apis/myextension.mycompany.io/v1/…)都转发给注册的APIService。

一般情况下,APIService对象以extension-apiserver运行在集群中的一个pod中,如果需要主动管理添加的资源,extension-apiserver还需要与一个或多个controlller进行关联,apiserver-builder为双方提供了一个框架。

Service Catalog是Kubernetes的一种API扩展实现,方便Kubernetes集群内部应用访问集群外部、由第三方管理、提供的服务,如由云供应商提供的数据库服务。Service Catalog的安装会为它所提供的服务提供extension-apiserver和controller两个扩展组件。

开启聚合层:
修改apiserver配置文件(/etc/kubernetes/manifests/kube-apiserver.manifest),加入如下启动参数来启用aggregation layer:

- --requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem
- --requestheader-allowed-names=aggregator
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User

重新部署apiserver。

<4>通过helm部署catalog:
可以把catalog包加入到本地repo中安装:

cp -r charts/catalog /dcos/appstore/local-charts/
cd /dcos/appstore/local-charts
helm package catalog --save=false
helm repo index --url=http://10.142.21.21:8879 .
helm repo update              //此时通过help search catalog可以看到local-charts下有了catalog包
helm install local-charts/catalog --namespace=default

或直接在charts目录下执行:

helm install catalog --namespace=default

<5>kubectl api-versions查看所有的 API,确认 servicecatalog.k8s.io 已经存在
这里写图片描述

5.2 Broker部署

先安装个mariadb:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mariadb-server
  namespace: broker-test
  labels:
    app: mariadb-server
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mariadb-server
    spec:
      containers:
      - name: mariadb-server
        image: mariadb:10.1.16
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
        ports:
        - containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
  name: mariadb-server
  namespace: broker-test
spec:
  ports:
  - name: mariadb-server
    port: 3306
    targetPort: 3306
  selector:
    app: mariadb-server

Broker部署,通过helm部署:

helm install --name mariadb-broker --namespace broker-test charts/mariadb-broker

5.3 Broker注册

首先,群集运营者必须在servicecatalog.k8s.io群组内创建ClusterServiceBroker资源。此资源包含访问服务代理端点所需的URL和连接详细信息。

这是一个ClusterServiceBroker资源的例子:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ClusterServiceBroker
metadata:
  name: mariadb-broker
spec:
  url: http://mariadb-broker-mariadb-broker.broker-test.svc.cluster.local

kubectl create -f examples/1.mariadb-broker.yaml

以下是说明从一个service broker列出托管服务和套餐所涉及步骤的顺序图:
这里写图片描述

  1. 将ClusterServiceBroker资源添加到Service catalog中,它会触发对外部Service Broker的调用以获取可用服务的清单。
  2. Service Broker返回可用托管服务的清单和服务套餐的列表,它们分别在本地缓存为ClusterServiceClass资源和ClusterServicePlan资源。
  3. 然后,集群运营者可以获取可用托管服务的清单和查看可用的服务套餐。

注册好之后可以看到生成了clusterservicebroker、clusterserviceclass和clusterserviceplan:
这里写图片描述

5.4 使用

5.4.1 创建Broker实例:

集群运营者可以通过创建ServiceInstance资源来启动新实例的供应。

如下是一个ServiceInstance资源的例子:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: jpress-mariadb-instance
  namespace: broker-test
spec:
  clusterServiceClassExternalName: mariadb
  clusterServicePlanExternalName: default

kubectl create -f examples/2.jpress/2.1.jpress-instance.yaml

以下序列图说明了提供一个新的托管服务的实例所涉及的步骤:
这里写图片描述

  1. 当ServiceInstance资源创建后,Service Catalog发起到外部service broker来提供服务的一个实例。
  2. service broker创建托管服务的新实例并返回HTTP响应。
  3. 然后,群集运营者可以检查实例的状态,来确认它是否准备就绪。
    这里写图片描述

5.4.2 绑定到托管服务

在提供新实例后,群集运营者必须绑定到托管服务才能获取到应用程序使用服务所需的连接凭证和服务帐户详细信息。这是通过创建ServiceBinding资源完成的。

以下是一个ServiceBinding资源的例子:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: jpress-mariadb-binding
  namespace: broker-test
spec:
  instanceRef:
    name: jpress-mariadb-instance
  secretName: jpress-mariadb-credentials

kubectl create -f examples/2.jpress/2.2.jpress-binding.yaml

以下序列图说明了绑定到托管服务实例所涉及的步骤:
这里写图片描述

  1. 在ServiceBinding创建后,Service Catalog给外部service broker发一个调用请求,获取与服务实例绑定所需的信息。
  2. service broker为相应的服务帐户启用应用程序权限/角色。
  3. service broker返回连接和访问托管服务实例所需的信息。根据不同的提供商和不同的服务,返回的信息可能在服务提供商和其管理服务之间有所不同。

5.4.3 映射连接凭证

绑定后,最后一步是将连接凭证和服务特定的信息映射到应用程序中。这些信息存储在secret中,应用程序可以用来访问并与托管服务连接。
以下是一个创建应用时映射连接凭证的例子:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jpress
  namespace: broker-test
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: jpress
    spec:
      containers:
      - name: jpress
        image: siji/jpress:1.0
        ports:
        - containerPort: 8080
        env:
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: jpress-mariadb-credentials
              key: host
        - name: DB_PORT
          valueFrom:
            secretKeyRef:
              name: jpress-mariadb-credentials
              key: port
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: jpress-mariadb-credentials
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: jpress-mariadb-credentials
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: jpress-mariadb-credentials
              key: database

kubectl create -f examples/2.jpress/2.3.jpress-blog-system.yaml
这里写图片描述

参考

https://kubernetes.io/docs/tasks/service-catalog/install-service-catalog-using-helm/
https://jimmysong.io/kubernetes-handbook/concepts/service-catalog.html
https://github.com/kubernetes-incubator/service-catalog/blob/master/docs/resources.md
https://kubernetes.io/docs/concepts/extend-kubernetes/service-catalog/
https://www.kubernetes.org.cn/2549.html
https://www.jianshu.com/p/52b3bc647996?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

猜你喜欢

转载自blog.csdn.net/liukuan73/article/details/79279753