본문 바로가기
kubernetes

[kubernetes] operator-sdk를 사용하여 쿠버네티스 오퍼레이터 구축하기 (operator sdk 예제)

by devjh 2021. 11. 5.
반응형

operator-sdk는 operator 개발 플로우를 제공하는 프레임워크로

해당 게시글은 operator의 개념에 대해 먼저 숙지해야 합니다.

 

[kubernetes] 쿠버네티스 오퍼레이터란(kubernetes operator)

이번 게시글에서는 쿠버네티스 오퍼레이터에 대해 정리합니다. 게시글을 읽기전 쿠버네티스 아키텍쳐와 동작원리, cr, crd, 게시글을 읽어보시면 이해가 더 수월할 것 같습니다. [kubernetes] 쿠버네

frozenpond.tistory.com

operator-sdk란

operator 개발 플로우를 제공하는 프레임워크입니다.

간단한 kubernetes operator를 구축해보는 예제입니다.

 

1. 목표

apiVersion: mygroup.example.com/v1
kind: Hello
metadata:
  name: hello-sample
  namespace: jh
spec:
  size: 3 # cr의 size라는 field로 pod의 갯수를 제어하겠습니다.

hello라는 kind의 resource를 만들거나 spec.size 필드를 변경하면 operator가 이를 감시해 deployment와 service(nodeport)를 구축하고 pod의 복제본수를 제어해 주는 예제입니다.

2. operator-sdk 설치

 

Installation Guide

Install operator-sdk Follow the steps in the installation guide to learn how to install the operator-sdk CLI tool. Additional Prerequisites git go version 1.15 docker version 17.03+. kubectl and access to a Kubernetes cluster of a compatible version.

sdk.operatorframework.io

해당 사이트에 가서 설치 매뉴얼을 따라가도 되지만

git과 golang(1.15v 이상)이 있다면 편리하게 설치가 가능합니다.

git clone https://github.com/operator-framework/operator-sdk
cd operator-sdk
git checkout master
make install

# 해당 명령어를 입력했을때 version이 출력되면 설치 완료입니다. 
operator-sdk version

 

3. resource 정의

operator-sdk create api --version=v1 --kind=Hello --group=mygroup

## 아래와 같은 질문이 올라오면 모두 y 해줍니다.
Create Resource [y/n]
y
Create Controller [y/n]
y

 

4. golang을 이용해 crd를 정의

api/{version} 아레에 위치한 {kind}_types.go 파일을 수정하면

crd가 알아서 구축됩니다.

추후 make manifest라는 명령어를 사용하면 go 파일로 정의한 crd의 yaml파일이 생성되고 적용됩니다.

 

Hello에서 spec에 size라는 필드를 사용할예정이므로 해당 struct에 size를 추가합니다.

type HelloSpec struct {
	Size int32 `json:"size"` // 이부분을 추가합니다.
}

 

5. golang을 이용해 controller를 커스터마이징합니다.

// test용 Reconcile 메서드입니다
func (r *HelloReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	myLogger := r.Log.WithValues("hello", req.NamespacedName)

	myLogger.Info("변경사항이 발생하였습니다.")
	// your logic here

	return ctrl.Result{}, nil
}

/controllers 아래에 위치한 {kind}_controller.go 파일을 수정해서 Controller의 로직을 직접 구현합니다.

cr의 변경사항은 Reconcile이라는 메서드에서 시작되므로 해당메서드를 아래와 같이 수정해봅니다.

해당 로직을 작성한후 cr을 apply해서 etcd에 넣어놓으면 변경사항이 발생했다는 로그가 올라올 겁니다.

 

spec.size를 변경하더라도 etcd에 변경이 기록될때마다 해당 로직을 타게됩니다.

 

1차목표는 단순 동작이므로 로그만 찍어본후

cr에 spec에 맞게 쿠버네티스 api서버에 요청만 보내면 구축 완료입니다.

 

api 서버에 요청을 보내는 소스코드는 아래 github에 저장되어 있습니다.

(line by line으로 사용법을 정리해놨습니다.)

https://github.com/jaeho310/operator-sdk-logic/blob/main/logic.go

 

GitHub - jaeho310/operator-sdk-logic

Contribute to jaeho310/operator-sdk-logic development by creating an account on GitHub.

github.com

 

6. type파일 상태 업데이트, , api server에 crd 반영

$ make generate

고맙게도 operator-sdk는 make파일로 다 준비를 해놨습니다.

 

type파일 상태를 업데이트합니다.

 

7. crd yaml파일 생성, crd 적용

$ make manifests
$ make install

etcd에 crd가 올라가고

config/crd/bases 아래에 crd의 yaml파일이 생성됩니다.

 

여기까지 완료되었다면 crd가 잘 적용됐는지 확인해봅니다.

$ kubectl get crd
$ kubectl explain {kind}

 

8. operator 실행

정상적으로 적용이 되었다면 operator를 실행합니다.

$ make run

# or

$ go run main.go

# or

ide를 이용해서 디버깅합니다.

이제 etcd에 들어있는 cr을 감시할 준비가 되었습니다.

 

9. cr apply!

config/samples 아래 {group}{version}{kind}.yaml 이름으로 cr파일이 있습니다.
crd를 참고하여 작성하고 apply하고 내가만든 애플리케이션이 정상적으로 동작하는지 확인합니다.

 

 

10. 배포(제공하는 make파일 사용)

operator-sdk는 배포를 위한 makefile도 제공합니다.

# makefile에 있는 docker-build, docker-push, docker deploy를 이용 합니다.
# 준비되어있는 dockerfile을 이용해 이미지를 만들고 레지스트리에 푸쉬합니다.
$ make docker-build IMG=myrepo/test/operator-tutorial:1
$ make docker-push IMG=myrepo/test/operator-tutorial:1

# 배포합니다.
$ make deploy IMG=IMG=myrepo/test/operator-tutorial:1

# projectname-system으로 새로운 namespace가 생성됩니다. 
$ kubectl get all -n tutorial-system

# 하나의 pod에 두개의 컨테이너가 생성되어있습니다.
# manager라는 이름의 컨테이너에서 로그를 확인하시면 됩니다.

 

11. 배포(직접 배포)

operator-sdk가 제공하는 makefile을 이용하지않고 사용하려면

레지스트리에 이미지만 푸쉬한후 /config/manager , /config/rbac 하위 내용을 참고하여 serviceaccount, clusterrole, clusterrolebinding, deployment를 직접 만들어저서 사용합니다.

operator는 k8s api서버를 조작하므로 해당 팟이 api서버에 접근하려면 인증인가 작업을 꼭 해줘야합니다.(단순히 로그만 찍는경우는 필요하지 않지만 쿠버네티스 api서버에 resource 변경 요청을하려면 필요합니다.)

 

[kubernetes] 쿠버네티스 인증, 인가(rbac)

1. 쿠버네티스 인증이란? 쿠버네티스 사용자가 맞는지 확인하는 작업입니다. 쿠버네티스 마스터노드에는 api서버가 있으며 보통 쿠버네티스 클라이언트인 kubectl을 이용하여 요청을 보냅니다. 이

frozenpond.tistory.com

아래의 내용은 pod에 슈퍼 계정인 cluster-admin 권한을 부여하여 실행시키는 yaml파일입니다. (pod만 사용해서 컨테이너를 띄우면 마스터노드 api서버에 접근할 권한이 없어 에러가 발생합니다.)

apiVersion: v1
kind: Namespace
metadata:
  labels:
    control-plane: controller-manager
  name: operators
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: controller-manager
  namespace: operators
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: manager-rolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: manager-role
subjects:
- kind: ServiceAccount
  name: controller-manager
  namespace: operators
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: controller-manager
  namespace: operators
  labels:
    control-plane: controller-manager
spec:
  selector:
    matchLabels:
      control-plane: controller-manager
  replicas: 1
  template:
    metadata:
      labels:
        control-plane: controller-manager
    spec:
      securityContext:
        runAsNonRoot: true
      containers:
      - command:
        - /manager
        args:
        - --leader-elect
        image: ~~~~~~/myoperator:v4
        name: manager
        securityContext:
          allowPrivilegeEscalation: false
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8081
          initialDelaySeconds: 15
          periodSeconds: 20
        readinessProbe:
          httpGet:
            path: /readyz
            port: 8081
          initialDelaySeconds: 5
          periodSeconds: 10
        resources:
          limits:
            cpu: 100m
            memory: 30Mi
          requests:
            cpu: 100m
            memory: 20Mi
      serviceAccountName: controller-manager
      terminationGracePeriodSeconds: 10
---

직접 배포할때는 config/crd/bases아래에 있는 crd yaml파일, 인증관련 yaml파일, 애플리케이션(operator)의 deployment를 정의한 yaml파일을 3가지를 쿠버네티스에 적용시킨 후,

cr을 만들어 apply 하면 쿠버네티스 클러스터를 애플리케이션이 원하는대로 동작하게 할 수 있습니다.

 

 

 

 

 

반응형

댓글