無知

갈 길이 먼 공부 일기

기술 공부/쿠버네티스

쿠버네티스 (18) | CRD, 서비스 카탈로그, 오픈시프트, Helm

moozii 2022. 4. 14. 22:33
앞으로의 스터디 내용은 <Kubernetes in Action>을 기반으로 진행합니다.
자세한 내용은, 해당 책을 확인해주세요! 
http://www.yes24.com/Product/Goods/89607047 

 

 

1. 사용자 정의 API 오브젝트
  1.1 CustomResourceDefinition
  1.2. 사용자 정의 컨트롤러
  1.3. 사용자 정의 오브젝트 유효성 검증
  1.4. 사용자 정의 API 서버
2. 서비스 카탈로그를 통한 셀프 서비스
  2.1. 서비스 카탈로그 소개
  2.2 서비스 카탈로그 API 서버 및 컨트롤러 매니저
  2.3. ServiceBroker와 OpenServiceBroker API
  2.4. 프로비저닝과 서비스 사용
  2.5. 바인딩 해제와 프로비저닝 해제
3. 쿠버네티스 기반 플랫폼
  3.1. 레드햇 오픈시프트 컨테이너 플랫폼
  3.2. Deis Workflow와 Helm

 

 

개요

  • 사용자 정의 오브젝트 및 컨트롤러 생성
  • 사용자 정의 API 서버 추가
  • 서비스 카탈로그를 통한 서비스 셀프 프로비저닝
  • 레드햇 오픈시프트 컨테이너 플랫폼
  • Deis Workflow, Helm

 

 

 

1. 사용자 정의 API 오브젝트

1.1 CustomResourceDefinition

1.1.1 개요

CRD = 새로운 리소스 유형을 정의하기 위한 오브젝트.(전신=ThirdPartyResource)
CRD를 게시하면 JSON, YAML 등 매니페스트를 API 서버에 게시해 사용자 정의 리소스 인스턴스 생성이 가능.
CRD 리소스가 가시적인 작업을 하기 위해서는 그에 해당하는 컨트롤러 배포도 필수적.

 

 

 

1.1.2. 생성 방법

1.1.2.1. 사용자 정의 리소스 매니페스트 정의

$ cat imaginary-kubia-website.yaml

# 웹사이트 유형의 리소스를 생성. 해당 인스턴스는 쿠버네티스가 웹서버 파드를 기동해 서비스로 노출하게 함.
# 깃레포 내에 웹사이트 파일을 저장.

apiVersion: "extensions.example.com/v1"
kind: Website
metadata:
  name: kubia // 서비스와 파드에 사용되는 웹사이트 이름
spec:
  gitRepo: https://github.com/luksa/kubia-website-example.git

기존 Kubia 레포 상의 예시는 과거 버전이므로, 새로운 버전에 맞게 재작성해보았다. 아래의 가이드 예시를 참고했다. apiVersion이 추가된 것이 특징이다.


https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/

 

Extend the Kubernetes API with CustomResourceDefinitions

This page shows how to install a custom resource into the Kubernetes API by creating a CustomResourceDefinition. Before you begin You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster.

kubernetes.io

 

 

1.1.2.2. CRD 오브젝트를 API 서버에 게시

$ cat website-crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: websites.extensions.example.com
spec:
  scope: Namespaced
  group: extensions.example.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                gitRepo:
                  type: string
  names:
    kind: Website
    singular: website
    plural: websites

기존 Kubia 레포 상의 예시는 과거 버전이므로, 새로운 버전에 맞게 재작성해보았다. 아래의 가이드 예시를 참고했다. apiVersion을 업데이트하고, versions: 항목을 추가해 served, storage, schema 등의 항목을 추가한 것이 특징이다. 이전에 비해 CRD 자체에 스펙을 명시해 추가해주는 것도 특징이다.


https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/

 

Extend the Kubernetes API with CustomResourceDefinitions

This page shows how to install a custom resource into the Kubernetes API by creating a CustomResourceDefinition. Before you begin You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster.

kubernetes.io

 

$ kubectl create -f website-crd.yaml
customresourcedefinition.apiextensions.k8s.io/websites.extensions.example.com created

$ kubectl create -f imaginary-kubia-website.yaml
website.extensions.example.com/kubia created

 

아래의 실습으로 생성 결과를 확인한다.

 

$ k get websites
NAME    AGE
kubia   2m18s

$ k get website kubia -o yaml
apiVersion: extensions.example.com/v1
kind: Website
metadata:
  creationTimestamp: "2022-04-05T00:39:37Z"
  generation: 1
  name: kubia
  namespace: default
  resourceVersion: "358288"
  uid: b40cab63-949a-49b5-9cb6-4271e829fb84
spec:
  gitRepo: https://github.com/luksa/kubia-website-example.git

 

 

 

1.2. 사용자 정의 컨트롤러

1.2.1. 기능

컨트롤러의 역할은 API 서버를 감시하다 사용자 정의 리소스가 생성하면, 그 리소스 생성에 맞춰 사전에 정의한 작업을 수행하는 것이다. 책 속 예시로는 웹사이트 리소스가 서버에 생성됨을 확인하고, 서비스와 웹서버 파드(디플로이먼트)를 생성하는 역할을 수행한다.

예시 컨트롤러 이미지는 다음과 같다 : https://hub.docker.com/r/luksa/website-controller

 

Docker Hub

 

hub.docker.com

 

예시 컨트롤러 이미지의 기능은 아래와 같다.

  1. 사용자 정의 리소스 오브젝트 감시 (Website 오브젝트 감시)
    http://localhost:8001/apis/extensions.example.com/v1/websites?watch=true URL 요청을 통해 감시. API 서버에 직접 연결하기보다는 파드 내 사이트카 컨테이너로 앰배서더 컨테이너를 실행해 kubectl proxy 프로세스를 통해 연결. 프록시가 암호화 인증을 처리하며 요청을 API 서버로 전달.
  2. HTTP GET 요청을 받은 API 서버의 감시 이벤트 반환
    신규 오브젝트 생성 시마다 ADDED 이벤트 발송
  3. 컨트롤러의 감시 이벤트 수신
  4. 컨트롤러의 감시 이벤트 내 정보 추출
    리소스 오브젝트에서 오브젝트 이름, 깃레포 URL을 추출
  5. 컨트롤러의 JSON 매니페스트 작성 및 API 서버 게시
  6. 디플로이먼트 오브젝트, 서비스 오브젝트 생성
  7. 디플로이먼트의 파드 템플릿 기반 파드 생성
    파드 템플릿은 Nginx 서버 실행 컨테이너 + gitsync 프로세스 실행 컨테이너로 구성. 로컬 디렉터리는 emptyDir 볼륨을 Nginx 컨테이너와 공유.
  8. 서비스의 웹서버 파드 노출
    노드포트 서비스 타입으로 생성해 각 노드의 임의 포트로 파드 노출.
  9. 리소스 인스턴스 삭제 시 API 서버 DELETED 감시 이벤트 발송
  10. 컨트롤러의 디플로이먼트, 서비스 리소스 삭제 (웹서버 종료 및 제거)

 

# Website Controller Deployment

$ cat website-controller.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: website-controller
  labels:
    app: website-controller
spec:
  replicas: 1
  selector:
    matchLabels:
      app: website-controller
  template:
    metadata:
      labels:
        app: website-controller
    spec:
      serviceAccountName: website-controller
      containers:
      - name: main
        image: luksa/website-controller
      - name: proxy
        image: luksa/kubectl-proxy:1.6.2

기존 책 속 예시 파일에 조금 수정을 거쳤다. apiVersion이 업데이트되기도 했고, 그러면서 디플로이먼트 매니페스트 작성 양식에 selector 항목이 추가되는 등 조금 수정이 필요했다. 자세한 가이드는 아래 링크를 참조하자.


https://kubernetes.io/ko/docs/concepts/workloads/controllers/deployment/

 

디플로이먼트

디플로이먼트(Deployment) 는 파드와 레플리카셋(ReplicaSet)에 대한 선언적 업데이트를 제공한다. 디플로이먼트에서 의도하는 상태 를 설명하고, 디플로이먼트 컨트롤러(Controller)는 현재 상태에서 의

kubernetes.io

 

 

 

1.2.2. 생성 방법

1.2.2.1. 컨트롤러 파드가 실행될 서비스 어카운트를 우선 생성

$ k create serviceaccount website-controller
serviceaccount/website-controller created

1.2.2.1.1. 클러스터 내 RBAC이 활성화된 경우 컨트롤러의 감시 작업 혹은 디플로이먼트 생성에 문제가 발생하므로 사전에 클러스터롤바인딩을 생성해 서비스어카운트를 바인딩.

$ k create clusterrolebinding website-controller --clusterrole=cluster-admin \
  --serviceaccount=default:website-controller
clusterrolebinding.rbac.authorization.k8s.io/website-controller created

 

1.2.2.2. 디플로이먼트로 컨트롤러 생성

$ k create -f website-controller.yaml
deployment.apps/website-controller created

 

1.2.2.3. 동작 확인

$ k create -f kubia-website.yaml
website.extensions.example.com/kubia created

$ k get po
NAME                                  READY   STATUS    RESTARTS       AGE
...
website-controller-56f5d89486-kw4vt   2/2     Running   1 (3m2s ago)   3m8s

$ k logs website-controller-56f5d89486-kw4vt -c main
2022/04/05 01:13:09 website-controller started.
2022/04/05 01:14:45 Received watch event: ADDED: kubia: https://github.com/luksa/kubia-website-example.git
2022/04/05 01:14:45 Creating services with name kubia-website in namespace default
2022/04/05 01:14:45 response Status: 201 Created
2022/04/05 01:14:45 Creating deployments with name kubia-website in namespace default
2022/04/05 01:14:45 response Status: 404 Not Found

$ k get deploy,svc,po
NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
...
deployment.apps/website-controller   1/1     1            1           4m30s

NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes      ClusterIP   10.96.0.1                443/TCP        69d
...
service/kubia-website   NodePort    10.107.251.48            80:30107/TCP   2m43s

NAME                                      READY   STATUS    RESTARTS        AGE
...
pod/website-controller-56f5d89486-kw4vt   2/2     Running   1 (4m23s ago)   4m29s

안타깝게도 웹사이트 컨트롤러의 생성과 웹사이트 리소스 인스턴스 생성 인식까지는 성공적이어서 서비스가 잘 생성되었지만, 웹사이트 디플로이먼트를 만들어 그 파드를 띄우는 작업에는 실패한 것으로 보인다

 

만약 성공적으로 수행되었다면 정적 웹사이트의 배포가 진행되어 클러스터 노드의 임의 포트로 사용 가능했을 것이다. 그외로 기능적으로 확장하기 위해 인그레스 오브젝트를 만들거나 웹사이트 액세스 가능한 URL 주소를 인스턴스 status 섹션에 추가하는 등의 작업도 가능하다고 한다.

 

 

 

1.3. 사용자 정의 오브젝트 유효성 검증

책의 내용 상으로는 CRD 오브젝트에 유효성 스키마가 지정되지 않았다 했지만, 앞서 말했다시피 최신 버전 실습에서는 스키마 지정이 필수이기 때문에 콘텐츠 유효성 검증이 이뤄진다 볼 수 있다.

 

Custom resources are validated via OpenAPI v3 schemas, by x-kubernetes-validations when the Validation Rules feature is enabled, and you can add additional validation using admission webhooks.

Source : https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation

 

 

 

1.4. 사용자 정의 API 서버

1.4.1. API 서버 애그리게이션

1.4.1.1. 개요

사용자 정의 API 서버를 기본 쿠버네티스 API 서버와 통합할 수 있도록 하는 기능이다. 여러 애그리게이션된 API 서버가 단일 경로로 노출되어, 클라이언트는 애그리게이션된 API 서버에 연결해 요청을 적절히 전달하는 방식을 취한다.

 

이를 통해 사용자 정의 API 서버 내에 오브젝트 유형을 직접 구현할 수도 있다.

이를 통해 ETCD에 리소스를 저장하는 방식이 2가지로 나눠진다.

 

1. 오브젝트 유형을 직접 구현해 자체 ETCD 인스턴스 혹은 ETCD 클러스터를 사용자 정의 서버가 실행해서 그 저장소에 저장하는 방식이거나,
2. 혹은 주 서버 / 코어 서버 ETCD 저장소에 CRD 오브젝트를 만들어 인스턴스를 생성하고 리소스를 저장하는 방식이다.

 

 

1.4.1.2. 생성 방법

1.4.1.2.1. 사용자 정의 API 서버 등록

$ cat apiservice.yaml
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: v1alpha1.extensions.example.com
spec:
  group: extensions.example.com
  version: v1alpha1
  groupPriorityMinimum: 150
  versionPriority: 150
  service:
    namespace: default
    name: website-api

 

책 속 사례와 달리 양식이 변경되었고 사용 apiVersion이 변경되는 등 매니페스트 작성 방식이 달라졌기 때문에 자세한 사항은 아래 가이드를 참고하여 작성했다.

https://kubernetes.io/docs/tasks/extend-kubernetes/configure-aggregation-layer/

 

$ k create -f apiservice.yaml
apiservice.apiregistration.k8s.io/v1alpha1.extensions.example.com created

이를 통해 extensions.example.com API 그룹과, 버전 v1alpha1 리소스를 포함하는 주 API 서버로 전달된 클라이언트 요청은, website-api 서비스로 노출된 사용자 정의 API 서버 파드로 포워딩하게 된다.

 

 

1.4.1.2.2. 사용자 정의 클라이언트 생성

 

1.4.1.2.2.1. kubectl client 이용한 yaml 파일 기반 리소스 생성

1.4.1.2.2.2. 사용자 API 서버에 덧붙인 사용자 정의 CLI 도구 빌드

 

 

쿠버네티스 API 애그리게이션 레이어(aggregation layer)

애그리게이션 레이어는 코어 쿠버네티스 API가 제공하는 기능 이외에 더 많은 기능을 제공할 수 있도록 추가 API를 더해 쿠버네티스를 확장할 수 있게 해준다. 추가 API는 메트릭 서버와 같이 미리 만들어진 솔루션이거나 사용자가 직접 개발한 API일 수 있다.

애그리게이션 레이어는 사용자 정의 리소스와는 다르며, 애그리게이션 레이어는 kube-apiserver 가 새로운 종류의 오브젝트를 인식하도록 하는 방법이다.애그리게이션 레이어애그리게이션 레이어는 kube-apiserver 프로세스 안에서 구동된다. 확장 리소스가 등록되기 전까지, 애그리게이션 레이어는 아무 일도 하지 않는다. API를 등록하기 위해서, 사용자는 쿠버네티스 API 내에서 URL 경로를 "요구하는(claim)" APIService 오브젝트를 추가해야 한다. 이때, 애그리게이션 레이어는 해당 API 경로(예: /apis/myextensions.mycompany.io/v1/...)로 전송되는 모든 것을 등록된 APIService로 프록시하게 된다.

APIService를 구현하는 가장 일반적인 방법은 클러스터 내에 실행되고 있는 파드에서 extension API server 를 실행하는 것이다. extension API server를 사용해서 클러스터의 리소스를 관리하는 경우 extension API server("extension-apiserver" 라고도 한다)는 일반적으로 하나 이상의 컨트롤러와 쌍을 이룬다. apiserver-builder 라이브러리는 extension API server와 연관된 컨틀로러에 대한 스켈레톤을 제공한다.

1. 사용자의 환경에서 Aggregator를 동작시키려면, 애그리게이션 레이어를 설정한다.
2. 다음에, 확장 API 서버를 구성해서 애그리게이션 레이어와 연계한다.

대안으로, 쿠버네티스 API를 커스텀 리소스 데피니션으로도 확장 가능하다.
https://kubernetes.io/ko/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/ 
 

쿠버네티스 API 애그리게이션 레이어(aggregation layer)

애그리게이션 레이어는 코어 쿠버네티스 API가 제공하는 기능 이외에 더 많은 기능을 제공할 수 있도록 추가 API를 더해 쿠버네티스를 확장할 수 있게 해준다. 추가 API는 메트릭 서버와 같이 미리

kubernetes.io

 

Extend the Kubernetes API with CustomResourceDefinitions

https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ 

 

kube-aggregator : Coming Soon!
Implements https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md  .
It provides
1. Provide an API for registering API servers.
2. Summarize discovery information from all the servers.
3. Proxy client requests to individual servers.

https://github.com/kubernetes/kube-aggregator 

Aggregated API Servers

Abstract

We want to divide the single monolithic API server into multiple aggregated servers. Anyone should be able to write their own aggregated API server to expose APIs they want. Cluster admins should be able to expose new APIs at runtime by bringing up new aggregated servers.

Source : https://github.com/kubernetes/design-proposals-archive/blob/main/api-machinery/aggregated-api-servers.md

 

 

 

 

 

2. 서비스 카탈로그를 통한 셀프 서비스

2.1. 서비스 카탈로그 소개

2.1.1. 개요

서비스 카탈로그를 통해 서비스 실행에 필요한 리소스들(파드, 서비스, 컨피그맵 등)을 직접 다루지 않고도 바로 서비스 인스턴스를 프로비저닝할 수 있다. 서비스 카탈로그는 4가지 일반 API 리소스를 제공한다.

 

https://kubernetes.io/ko/docs/concepts/extend-kubernetes/service-catalog/

 
  1. ClusterServiceBroker:
    서비스를 프로비저닝할 수 있는 외부 시스템을 기술한다.
    클러스터 관리자가 가장 먼저 제공하고자 하는 서비스의 브로커를 생성한다. 쿠버네티스는 브로커에 제공 가능 서비스 목록을 요청한다.
  2. ClusterServiceClass:
    프로비저닝 가능한 서비스 유형을 기술한다.
    쿠버네티스가 제공 가능 서비스 목록을 요청한 후 각 서비스의 ClusterServiceClass 리소스를 생성한다.
  3. ServiceInstance:
    프로비저닝된 서비스의 한 인스턴스이다.
    사용자가 서비스를 프로비저닝하는 경우 직접 생성한다.
  4. ServiceBinding:
    클라이언트(파드) 세트와 서비스 인스턴스 간의 바인딩을 나타낸다.
    사용자가 서비스 인스턴스 생성 후 바인딩에 사용한다.
    바인딩까지 완료된 파드는 프로비저닝된 서비스 인스턴스 연결에 필요한 모든 자격증명 및 데이터가 담긴 시크릿이 주입된다.

 

https://livebook.manning.com/book/kubernetes-in-action/chapter-18/123

 
서비스 카탈로그는 servicecatalog.k8s.io API를 설치하고 다음 쿠버네티스 리소스를 제공한다.

1. ClusterServiceBroker:
서버 연결 세부 사항을 캡슐화한, 서비스 브로커의 클러스터 내부 대표. 이들은 클러스터 내에서 새로운 유형의 매니지드 서비스를 사용할 수 있도록 하려는 클러스터 운영자가 만들고 관리한다.

2. ClusterServiceClass:
특정 서비스 브로커가 제공하는 매니지드 서비스. 새로운 ClusterServiceBroker 리소스가 클러스터에 추가되면 서비스 카탈로그 컨트롤러는 서비스 브로커에 연결해서 사용 가능한 매니지드 서비스 목록을 얻는다. 그 다음 각 매니지드 서비스에 해당하는 새로운 ClusterServiceClass 리소스를 만든다.

3. ClusterServicePlan:
매니지드 서비스의 특별 요청. 예를 들어, 매니지드 서비스는 무료 혹은 유료 티어와 같이 사용 가능한 서로 다른 상품이 있거나, SSD 스토리지를 사용하거나 더 많은 리소스를 갖는 등 다른 구성 옵션을 가질 수 있다. ClusterServiceClass와 유사하게, 새로운 ClusterServiceBroker가 클러스터에 추가되면, 서비스 카탈로그는 각 매니지드 서비스에 사용 가능한 서비스 플랜에 해당하는 새로운 ClusterServicePlan 리소스를 작성한다.

4. ServiceInstance:
ClusterServiceClass의 프로비저닝된 인스턴스. 클러스터 운영자가 하나 이상의 클러스터 애플리케이션에서 사용할 수 있도록 매니지드 서비스의 특정 인스턴스를 사용하기 위해 생성한다. 새로운 ServiceInstance리소스가 생성되면, 서비스 카탈로그 컨트롤러는 해당 서비스 브로커에 연결하여 서비스 인스턴스를 프로비저닝하도록 지시한다.

5. ServiceBinding:
ServiceInstance에 대한 자격 증명에 액세스한다. 자신의 애플리케이션이 ServiceInstance를 사용하기를 원하는 클러스터 운영자가 이들을 생성한다. 서비스 카탈로그 컨트롤러는 생성 시 파드에 마운트될 수 있는 서비스 인스턴스에 대한 연결 세부 정보와 자격 증명이 포함된 쿠버네티스 '시크릿(secret)'을 생성한다.

https://kubernetes.io/ko/docs/concepts/extend-kubernetes/service-catalog/ 
 

서비스 카탈로그

서비스 카탈로그는 쿠버네티스 클러스터 내에서 실행되는 응용 프로그램이 클라우드 공급자가 제공하는 데이터 저장소 서비스와 같은 외부 관리 소프트웨어 제품을 쉽게 사용할 수 있도록하는

kubernetes.io

 

https://kubernetes.io/ko/docs/concepts/extend-kubernetes/service-catalog/

 

다음은 서비스 브로커에서 사용 가능한 매니지드 서비스와 플랜을 나열하는 단계를 설명하는 시퀀스 다이어그램이다.

1. ClusterServiceBroker 리소스가 서비스 카탈로그에 추가되면, 사용 가능한 서비스 목록에 대한 외부 서비스 브로커에 대한 호출을 발생시킨다.

2. 서비스 브로커는 사용 가능한 매니지드 서비스 목록과 서비스 플랜 목록을 반환한다. 이 목록은 각각 로컬 ClusterServiceClass와 ClusterServicePlan 리소스로 캐시된다.

3. 그런 다음 클러스터 운영자는 다음의 명령어를 사용하여 가용한 관리 서비스 목록을 얻을 수 있다.
kubectl get clusterserviceclasses -o=custom-columns=SERVICE\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName

https://kubernetes.io/ko/docs/concepts/extend-kubernetes/service-catalog/ 
 

 

 

2.2 서비스 카탈로그 API 서버 및 컨트롤러 매니저

서비스 카탈로그는 3가지 구성 요소로 구성된 분산시스템이다.

  1. 서비스 카탈로그 API 서버 : 서비스 카탈로그 리소스들이 게시되어 생성됨
  2. ETCD 스토리지 : 생성된 리소스가 저장됨 (혹은 API 서버 CRD를 대체 스토리지 메커니즘으로 사용 가능)
  3. 컨트롤러 매니저 : 컨트롤러를 실행. 컨트롤러는 서비스 카탈로그 API 서버와 통신하며 API에 서비스 브로커 리소스를 생성해 외부 서비스 브로커로 하여금 프로비저닝하도록 함.

 

 

 

2.3. ServiceBroker와 OpenServiceBroker API

2.3.1. 개요

클러스터 관리자는 서비스 카탈로그에 1개 이상의 외부 서비스 브로커를 등록 가능하다. 각 브로커는 OpenServiceBroker API를 구현해야 한다.

 

 

2.3.2. OpenServiceBroker API

서비스 카탈로그와 브로커의 통신 수단인 REST API.

  • 서비스 목록 검색 : GET /v2/catalog
  • 서비스 인스턴스 프로비저닝 : PUT /v2/service_instance/:id
  • 서비스 인스턴스 디프로비저닝 : DELETE /v2/service_instance/:id
  • 서비스 인스턴스 업데이트 : PATCH /v2/service_instance/:id
  • 서비스 인스턴스 바인딩 설정 : PUT /v2/service_instance/:id/service_bindings/:binding_id
  • 서비스 인스턴스 바인딩 해제 : DELETE /v2/service_instance/:id/service_bindings/:binding_id

 

서비스 카탈로그는 오픈 서비스 브로커 API를 사용하여 쿠버네티스 API 서버가 초기 프로비저닝을 협상하고 애플리케이션이 매니지드 서비스를 사용하는데 필요한 자격 증명을 검색하는 중개자 역할을 하는 서비스 브로커와 통신한다. 이는 CRD 기반 아키텍처를 사용해서 구현되었다.

https://kubernetes.io/ko/docs/concepts/extend-kubernetes/service-catalog/

 

The Open Service Broker API defines an HTTP(S) interface between Platforms and Service Brokers.

The Service Broker is the component of the service that implements the Service Broker API, for which a Platform is a client. Service Brokers are responsible for advertising a catalog of Service Offerings and Service Plans to the Platform, and acting on requests from the Platform for provisioning, binding, unbinding, and deprovisioning.

In general, provisioning reserves a resource on a service; we call this reserved resource a Service Instance. What a Service Instance represents can vary by service. Examples include a single database on a multi-tenant server, a dedicated cluster, or an account on a web application.

What a Service Binding represents MAY also vary by service. In general, creation of a Service Binding either generates credentials necessary for accessing the resource or provides the Service Instance with information for a configuration change.

A Platform MAY expose services from one or many Service Brokers, and an individual Service Broker MAY support one or many Platforms using different URL prefixes and credentials.

Source : https://github.com/openservicebrokerapi/servicebroker/blob/v2.16/spec.md
Resource : https://github.com/openservicebrokerapi/servicebroker

 

 

2.3.3. 서비스 카탈로그 내 브로커 등록과 서비스 조회

$ cat database-broker.yaml
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ClusterServiceBroker
metadata:
  name: database-broker
spec:
  url: http://database-osbapi.myorganization.org

일부 변경되어 새로 작성했다. 책 속 매니페스트는 다소 변경이 필요하니 다음 가이드를 참조하자. 참고로 해당 예제 코드는 다른 유형의 데이터베이스를 프로비저닝하는 가상의 브로커로, 프로비저닝 가능 서비스 목록 검색에 활용된다. 서비스 카탈로그는 해당 브로커를 통한 서비스 검색 이후 클러스터서비스클래스 리소스를 생성해 각각 단일 유형의 서비스를 명세하고, 클러스서비스 플랜을 통해 각 서비스에 필요한 서비스 수준 (프리미엄인지 무료인지 등)을 결정한다.
https://kubernetes.io/ko/docs/concepts/extend-kubernetes/service-catalog/

 

해당 브로커 생성은 다음과 같은 오류가 발생한다.

$ k create -f database-broker.yaml
error: unable to recognize "database-broker.yaml": no matches for kind "ClusterServiceBroker" in version "servicecatalog.k8s.io/v1beta1"

오류 발생 사유는, 서비스 카탈로그를 미리 생성하지 않았기 때문인 것으로 보인다.

You need to install service catalog first. You're getting that error because you haven't installed service catalog, so the API server doesn't recognize the clusterservicebroker type.

Source : https://github.com/kubernetes-sigs/service-catalog/issues/2535

 

서비스 카탈로그 설치를 찾아보니, 별도로 생성, 설치하는 방법이 존재해 시도했다.

가이드 : https://kubernetes.io/docs/tasks/service-catalog/install-service-catalog-using-helm/

$ helm repo add svc-cat https://kubernetes-sigs.github.io/service-catalog
"svc-cat" has been added to your repositories

$ helm search repo service-catalog
NAME                	CHART VERSION	APP VERSION	DESCRIPTION
svc-cat/catalog     	0.3.1        	           	service-catalog webhook server and controller-m...
svc-cat/catalog-v0.2	0.2.3        	           	service-catalog API server and controller-manag...

$ helm install catalog svc-cat/catalog --namespace catalog
Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest: [unable to recognize "": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1", unable to recognize "": no matches for kind "ClusterRole" in version "rbac.authorization.k8s.io/v1beta1", unable to recognize "": no matches for kind "ClusterRoleBinding" in version "rbac.authorization.k8s.io/v1beta1", unable to recognize "": no matches for kind "MutatingWebhookConfiguration" in version "admissionregistration.k8s.io/v1beta1", unable to recognize "": no matches for kind "ValidatingWebhookConfiguration" in version "admissionregistration.k8s.io/v1beta1"]

 

서비스 카탈로그 설치가 실패했다. 그 이유는 apiVersion에 맞게 K8S 측에서 Helm Template을 업데이트하지 않았기 때문인 것으로 보인다. 우선 실습은 넘어가면서, 이론적인 부분만 파악하는 것이 적절해보인다.

It appears the chart refers to deprecated artifacts as of 1.22. Example: “The apiextensions.k8s.io/v1beta1 API version of CustomResourceDefinition is no longer served as of v1.22.”

Source : https://github.com/kubernetes-sigs/service-catalog/issues/2906

 

본래대로면 브로커를 생성한 후, k get serviceClasses를 통해 클러스터 내 프로비저닝이 가능한 전체 서비스 목록 검색이 가능하다. 이러한 서비스 유형 클래스는, 무료/유료 플랜 정보도 포함한다.

$ kubectl get clusterserviceclasses -o=custom-columns=SERVICE\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
 SERVICE NAME                           EXTERNAL NAME
 4f6e6cf6-ffdd-425f-a2c7-3c9258ad2468   cloud-provider-service
 ...                                    ...

 

 

 

2.4. 프로비저닝과 서비스 사용

2.4.1. ServiceInstance 프로비저닝

$ cat database-instance.yaml

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: my-postgres-db
  namespace: default
spec:
  # 이전에 반환된 서비스 중 하나를 참조
  clusterServiceClassExternalName: postgres-database
  clusterServicePlanExternalName: free
  #####
  # 이곳에 서비스 브로커가 사용할 수 있는
  # 파라미터를 추가할 수 있다.
  parameters:
    init-db-args: --data-checksums
  #####

이를 통해 my-postgres-db라는 서버 인스턴스를 만들고 클러스터서비스클래스와 플랜을 지정한다. 리소스 생성 시 서비스 카탈로그는 브로커에 접속해 프로비저닝을 요청하고 파라미터를 전달한다. 결국 실제 프로비저닝의 실행은 브로커가 맡는다.

 

2.4.2. 서비스 인스턴스 바인딩

$ cat my-postgres-db-binding.yaml

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: my-postgres-db-binding
  namespace: default
spec:
  instanceRef:
    name: my-postgres-db // 이전에 생성한 서비스 인스턴스 참조
  #####
  # 서비스 브로커가 사용할 수 있는 secretName, 서비스 어카운트 파라미터 등의
  # 추가 정보를 여기에 추가할 수 있다.
  secretName: postgres-secret // 서비스 접근용 자격증명
  #####

프로비저닝된 서비스 인스턴스를 사용하기 위해 바인딩 리소스를 생성한다. 서비스 카탈로그는 바인딩 리소스에 정의한 이름으로 새로운 시크릿을 만들어 그곳에 데이터를 저장한다. 생성된 시크릿을 파드에 마운트해서 서비스 인스턴스에 연결 가능하다.

 

연결 자격 증명 매핑

바인딩 후 마지막 단계는 연결 자격 증명과 서비스 특화 정보를 애플리케이션에 매핑하는 것이다. 이런 정보는 클러스터의 애플리케이션이 액세스하여 매니지드 서비스와 직접 연결하는데 사용할 수 있는 시크릿으로 저장된다.


파드 구성 파일

이 매핑을 수행하는 한 가지 방법은 선언적 파드 구성을 사용하는 것이다.

다음 예시는 서비스 자격 증명을 애플리케이션에 매핑하는 방법을 설명한다. sa-key라는 키는 provider-cloud-key라는 볼륨에 저장되며, 애플리케이션은 이 볼륨을 /var/secrets/provider/key.json에 마운트한다. 환경 변수 PROVIDER_APPLICATION_CREDENTIALS는 마운트된 파일의 값에서 매핑된다.

다음 예시는 시크릿 값을 애플리케이션 환경 변수에 매핑하는 방법을 설명한다. 이 예시에서 메시지 큐 토픽 이름은 topic 라는 키의 provider-queue-credentials 시크릿에서 환경 변수 TOPIC에 매핑된다.

https://kubernetes.io/ko/docs/concepts/extend-kubernetes/service-catalog/#%EC%97%B0%EA%B2%B0-%EC%9E%90%EA%B2%A9-%EC%A6%9D%EB%AA%85-%EB%A7%A4%ED%95%91

 

 

 

2.5. 바인딩 해제와 프로비저닝 해제

$ k delete servicebinding my-postgres-db-binding
$ k delete serviceinstance my-postgres-db

바인딩을 삭제하면 컨트롤러는 시크릿을 삭제하고 브로커를 호출해 바인딩을 해제한다.

서비스 인스턴스를 삭제하면 카탈로그는 브로커에 프로비저닝 해제 작업을 요청한다.

 

 

 

 

 

3. 쿠버네티스 기반 플랫폼

3.1. 레드햇 오픈시프트 컨테이너 플랫폼

3.1.1. 개요

오픈시프트는 클러스터에 CI 솔루션을 별도 통합할 필요 없이 애플리케이션의 이미지 빌드와 배포를 자동화한다. 또한 사용자 및 그룹 관리 기능을 제공해 보안이 강화된 멀티 테넌트 클러스터를 구성할 수 있다. 쿠버네티스 네임스페이스 단위로 사용자의 접근권한 관리와 애플리케이션 격리를 제공한다.

 

3.1.2. 오픈시프트의 추가 리소스

  • 사용자 / 그룹 / 프로젝트 :
    오픈시프트는 사용자 관리 기능, RBAC을 제공한다. 프로젝트는 어노테이션이 추가된 네임스페이스와 같아서, 사용자는 접근 권한이 부여된 프로젝트에만 접근 가능하고, 그 권한 관리는 클러스터 관리자 부여한다.
  • 애플리케이션 템플릿 :
    오픈시프트는 매니페스트의 파라미터화를 제공한다. 파라미터화 가능한 목록을 템플릿이라 명명한다. 매니페스트에 placeholder를 갖는 오브젝트의 목록으로 템플릿을 인스턴스화할 때 처리 과정을 거쳐 placeholder가 파라미터로 대체된다. 오픈시프트 측은 사전 제작된 템플릿 목록을 제공해 빠르게 복잡한 리소스를 생성할 수 있도록 돕는다.
  • BuildConfig :
    BuildConfig는 깃 레포 내 커밋 후 이미지 빌드를 자동으로 트리거하는 리소스이다., 이를 통해 오픈시프트가 클러스터 애플리케이션 빌드 및 배포를 바로 소스코드가 있는 깃 레포지토리에서 수행할 수 있는 기능을 제공한다. 이미지 빌드 및 배포를 오픈시프트가 대신 수행하는 것이다. 정확히는 리포지터리 훅이 오픈시프트에 커밋 알림을 보내 변경사항을 기반으로 빌드하는 Source To Image 메커니즘을 기반으로 한다.
  • DeploymentConfig :
    새로 빌드된 이미지를 인식하고 새 이미지의 롤아웃을 시작하게 하는 리소스이다. BuildConfig가 이미지를 빌드하면 ImageStream이라 하는 이미지의 스트림에 그 이미지를 추가하는데, 이 ImageStream을 DeploymentConfig가 가리키고 있다가 새로운 이미지 빌드를 인식하면 배포를 진행한다. 배포 전/후에 훅을 구성할 수도 있다. 디플로이먼트와 달리 레플리케이션컨트롤러를 기반으로 파드를 생성한다.
    (현재 기준으로도 그렇다는 것을 확인했다. 다만 오픈시프트 문서도 Deployment Config보다 쿠버네티스 디플로이먼트의 활용을 권고한다. )
  • Route :
    인그레스와 유사한 기능을 수행하는 리소스이다. 인그레스 컨트롤러와 같이 로드밸런서 및 프록시 등의 기능을 제공하는 Router를 사용해야 한다. TLS termination, 트래픽 분할 등 인그레스보다 더 추가적인 구성 조절이 가능하다.

참고 리소스_1 : https://docs.openshift.com/container-platform/4.10/cicd/builds/understanding-buildconfigs.html

참고 리소스_2 : https://docs.openshift.com/container-platform/4.10/applications/deployments/what-deployments-are.html

시험용 Minishift : https://github.com/minishift/minishift

 

 

 

3.2. Deis Workflow와 Helm

3.2.1. Deis Workflow

쿠버네티스 클러스터 상에 배포되는 워크플로. [현재는 유지되지 않는 프로젝트이다]

실행 시 서비스 및 레플리케이션 컨트롤러 생성을 통해 개발자 친화적 환경 구성에 도움을 준다.
구체적으로는 아래와 같은 추가 기능을 제공한다.

  • git push deis master로 변경사항 푸시 후 배포 자동화
  • Source To Image 메커니즘
  • 애플리케이션 롤아웃, 롤백 기능
  • 에지 라우팅
  • 메트릭 및 로그
  • 알람

 

Deis Workflow is no longer maintained.

09/07/2017 Deis Workflow v2.18 final release before entering maintenance mode
03/01/2018 End of Workflow maintenance: critical patches no longer merged

Deis Workflow is an open source Platform as a Service (PaaS) that adds a developer-friendly layer to any Kubernetes cluster, making it easy to deploy and manage applications. Deis Workflow is the second major release (v2) of the Deis PaaS.

https://github.com/deis/workflow

 

Hephy Workflow is the open source fork of Deis Workflow PaaS.
Some of the old documentation and README are still preserved so they may reference "Deis Workflow". Hephy Workflow is the community continuation of the Deis Workflow project after it was end-of-lifed by the Deis team which moved on to do bigger projects at Microsoft Azure.

05/08/2021 Hephy Workflow v2.23.0 release

https://github.com/teamhephy/workflow

 

 

 

3.2.2. Helm

쿠버네티스 패키지 관리자이다.

Helm CLI 도구(클라이언트)와 Tiller(서버 구성 요소)로 구성되며 클러스터 내 파드로 실행된다.

  • 용도 : 쿠버네티스 클러스터 내 애플리케이션 패키지 배포 및 관리
  • 기능 : 구성 정보를 포함한 컨피그와 차트를 병합해 릴리스를 생성
  • 이점 : 쿠버네티스 애플리케이션 매니페스트의 구축 관리 부담 감소. 애플리케이션 실행 시 필요한 구성요소 및 구성 방법에 대한 부담 감소.
  • 용어 : Helm Chart = 애플리케이션 패키지
  • 용법 : helm install [NAME] [CHART] [flags]
  • 공식 사이트 : https://helm.sh/
  • 커뮤니티 유지 차트 목록 : https://artifacthub.io/packages/search?kind=0&sort=relevance&page=1