operator는 왜 필요한가 

- deployment 보단 statefulset에서 많이 쓰인다

- DB기동 전후 스크립트, 백업자동화, failover , scale in/out 에 필요한 작업을 커스터마이징 하기 위해 필요하다 

 

CRD를 만들고 / CRD를 사용하는 CR을 만들고 / CR을 사용하는 Operator 를 만든다 

 

"사용자 정의 리소스를 Custom Resource라고 한다. Service, Pod와 같은 리소스를 사용자가 직접 등록할 수 있다. Custom Resource를 등록하기 위해서 Custom Resource에 대한 스펙 (이름, 인자 등등)을 정의해야 하는데, 스펙을 정의한 YAML 문서를 Custom Resource Definition (CRD)라고 한다. "

출처: https://bcho.tistory.com/1391 [조대협의 블로그:티스토리]

 

 

 

CRD 만들기 

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: crdtests.sua.com
spec:
  group: sua.com
  names:
    kind: crdtest
    listKind: crdtestList
    plural: crdtests
    singular: crdtest
  scope: Namespaced
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              message:
                type: string

- metadata.name :

    "plural.group" 형식 으로 만든다 

     [cr의 복수형 이름].[api 그룹명 (도메인형식)] 

- spec.group :

   리소스가 속한 API그룹 지정

   여러 crd를 그룹화할 수 있다 

 

- spec.names.listkind : 

   crdtest라는 리소스 객체를 리스트에 달아놓을 수가 있다. 

-  spec.names.plural:

   복수형 이름

-  spec.names.singular :

   딘수형 이름 

 

- spec.scope : 

  리소스의 범위 지정 

 

- spec.version.served: 

  해당버전의 리소스가 api 서버에 제공

  client는 이 버전을 사용해서 리소스 생성/조회/업데이트 가능 

  false 로 할 경우 , client 는 해당 버전으로 리소스 생성 불가 

- spec.version.storaged: 

  해당버전의 리소스가 기본 저장소 서버에 제공

 

- spec.vesion.schema :

  리소스의 기본 타입을 object 로 선언하고, property로 해당 리소스를 사용할때 규칙을 정한다 

  property에 spec이 있으니 해당 CRD를 사용할때는 spec이라는 속성을 필수로 써야하며, spec의 설정 값으로 message 항목이 들어가야한다 

아래 처럼 CR을 만들어야한다 

apiVersion: my.domain/v1
kind: HelloWorld
metadata:
  name: example-helloworld
spec:
  message: "Hello, Kubernetes!"

 

 

적용

[root@tech7 test2]# k apply -f crd.yaml
customresourcedefinition.apiextensions.k8s.io/crdtests.sua.com created
[root@tech7 test2]# k get customresourcedefinitions.apiextensions.k8s.io  crdtests.sua.com
NAME               CREATED AT
crdtests.sua.com   2024-08-26T09:03:30Z

 

 

CR 설정하기

apiVersion: sua.com/v1
kind: crdtest
metadata:
  name: cr-test
spec:
  message: "Hello, Kubernetes! I made CR"

 

 

 

 

 

Operator 만들기 

python으로 만들어본다

kopf란?

Kubernetes Operator Pythonic Framework 

python 으로 k8s Operator를 쉽게 만들 수 있게 도와주는 프레임워크이다 

 

sample 코드 만들기

import kopf

@kopf.on.create('sua.com', 'v1', 'crdtest')
def on_create(spec, **kwargs):
    message = spec.get('message', 'Hello, Operator!')
    print(f"Received message: {message}")

- kopf를 import 한다 

- @데코레이터 

   kopf.on.create :  CR이 생성될 때 호출 된다 

- def on_create 

   CR이 생성될 떄 호출된다 

- spec.get 

  spec 딕션어리에 message라는 필드를 가져온다 

 

operator 실행하기 

[root@tech7 kopf]# kopf run operator.py
/usr/local/lib/python3.9/site-packages/kopf/_core/reactor/running.py:179: FutureWarning: Absence of either namespaces or cluster-wide flag will become an error soon. For now, switching to the cluster-wide mode for backward compatibility.
  warnings.warn("Absence of either namespaces or cluster-wide flag will become an error soon."
[2024-08-27 14:49:46,200] kopf._core.engines.a [INFO    ] Initial authentication has been initiated.
[2024-08-27 14:49:46,207] kopf.activities.auth [INFO    ] Activity 'login_via_client' succeeded.
[2024-08-27 14:49:46,207] kopf._core.engines.a [INFO    ] Initial authentication has finished.

 

 

operator는 crdtest라는 crd로 create 된게 있으면 메세지를 프린트한다 

 

CR 적용하기 

[root@tech7 test2]# k apply -f cr.yaml
crdtest.sua.com/cr-test created
[root@tech7 test2]# k get crdtests.sua.com
NAME      AGE
cr-test   2m16s

 

operator 로그가 남는다 

[2024-08-27 14:49:53,831] root                 [INFO    ] Received message: Hello, Kubernetes! I made CR
Received message: Hello, Kubernetes! I made CR
[2024-08-27 14:49:53,831] kopf.objects         [INFO    ] [default/cr-test] Handler 'on_create' succeeded.
[2024-08-27 14:49:53,832] kopf.objects         [INFO    ] [default/cr-test] Creation is processed: 1 succeeded; 0 failed.