검색

5.4. Ansible 기반 Operator

download PDF

5.4.1. Ansible 기반 Operator를 위한 Operator SDK 시작하기

Operator SDK에는 Go 코드를 작성하지 않고도 기존 Ansible 플레이북 및 모듈을 활용하여 Kubernetes 리소스를 통합 애플리케이션으로 배포하는 Operator 프로젝트를 생성하는 옵션이 포함되어 있습니다.

Operator 개발자는 Operator SDK에서 제공하는 툴 및 라이브러리를 사용하여 Ansible 기반 Operator를 설정 및 실행하는 기본 동작을 설명하기 위해 분산형 키-값 저장소인 Memcached에 대한 Go 기반 Operator 예제를 빌드하고 클러스터에 배포할 수 있습니다.

5.4.1.1. 사전 요구 사항

  • Operator SDK CLI가 설치됨
  • OpenShift CLI (oc) v4.12 이상이 설치됨
  • Ansible v2.9.0
  • Ansible Runner v2.0.2+
  • Ansible Runner HTTP Event Emitter 플러그인 v1.0.0 이상
  • Python 3.8.6+
  • OpenShift Python client v0.12.0+
  • cluster-admin 권한이 있는 계정으로 oc 를 사용하여 OpenShift Container Platform 4.12 클러스터에 로그인함
  • 클러스터가 이미지를 가져올 수 있도록 하려면 이미지를 내보내는 리포지토리를 공개로 설정하거나 이미지 가져오기 보안을 구성해야 합니다.

5.4.1.2. Ansible 기반 Operator 생성 및 배포

Operator SDK를 사용하여 Memcached에 대한 간단한 Ansible 기반 Operator를 빌드하고 배포할 수 있습니다.

프로세스

  1. 프로젝트를 생성합니다.

    1. 프로젝트 디렉토리를 생성합니다.

      $ mkdir memcached-operator
    2. 프로젝트 디렉터리로 변경합니다.

      $ cd memcached-operator
    3. ansible 플러그인과 함께 operator-sdk init 명령을 실행하여 프로젝트를 초기화합니다.

      $ operator-sdk init \
          --plugins=ansible \
          --domain=example.com
  2. API를 생성합니다.

    간단한 Memcached API를 생성합니다.

    $ operator-sdk create api \
        --group cache \
        --version v1 \
        --kind Memcached \
        --generate-role 1
    1
    API에 대한 Ansible 역할을 생성합니다.
  3. Operator 이미지를 빌드하여 내보냅니다.

    기본 Makefile 대상을 사용하여 Operator를 빌드하고 내보냅니다. 내보낼 수 있는 레지스트리를 사용하는 이미지의 가져오기 사양에 IMG를 설정합니다.

    $ make docker-build docker-push IMG=<registry>/<user>/<image_name>:<tag>
  4. Operator를 실행합니다.

    1. CRD를 설치합니다.

      $ make install
    2. 클러스터에 프로젝트를 배포합니다. 내보낸 이미지에 IMG를 설정합니다.

      $ make deploy IMG=<registry>/<user>/<image_name>:<tag>
  5. 샘플 CR(사용자 정의 리소스)을 생성합니다.

    1. 샘플 CR을 생성합니다.

      $ oc apply -f config/samples/cache_v1_memcached.yaml \
          -n memcached-operator-system
    2. CR에서 Operator를 조정하는지 확인합니다.

      $ oc logs deployment.apps/memcached-operator-controller-manager \
          -c manager \
          -n memcached-operator-system

      출력 예

      ...
      I0205 17:48:45.881666       7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator
      {"level":"info","ts":1612547325.8819902,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
      {"level":"info","ts":1612547325.98242,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
      {"level":"info","ts":1612547325.9824686,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":4}
      {"level":"info","ts":1612547348.8311093,"logger":"runner","msg":"Ansible-runner exited successfully","job":"4037200794235010051","name":"memcached-sample","namespace":"memcached-operator-system"}

  6. CR 삭제

    다음 명령을 실행하여 CR을 삭제합니다.

    $ oc delete -f config/samples/cache_v1_memcached.yaml -n memcached-operator-system
  7. 정리합니다.

    다음 명령을 실행하여 이 절차의 일부로 생성된 리소스를 정리합니다.

    $ make undeploy

5.4.1.3. 다음 단계

5.4.2. Ansible 기반 Operator를 위한 Operator SDK 튜토리얼

Operator 개발자는 Operator SDK의 Ansible 지원을 활용하여 분산형 키-값 저장소인 Memcached에 대한 Ansible 기반 Operator 예제를 빌드하고 라이프사이클을 관리할 수 있습니다. 이 튜토리얼에서는 다음 프로세스를 안내합니다.

  • Memcached 배포 생성
  • 배포 크기가 Memcached CR(사용자 정의 리소스) 사양에 지정된 것과 같은지 확인합니다.
  • memcached Pod의 이름으로 상태 작성기를 사용하여 Memcached CR 상태를 업데이트합니다.

이 프로세스는 Operator 프레임워크의 두 가지 주요 요소를 사용하여 수행됩니다.

Operator SDK
operator-sdk CLI 툴 및 controller-runtime 라이브러리 API
OLM(Operator Lifecycle Manager)
클러스터에 대한 Operator의 설치, 업그레이드, RBAC(역할 기반 액세스 제어)
참고

5.4.2.1. 사전 요구 사항

  • Operator SDK CLI가 설치됨
  • OpenShift CLI (oc) v4.12 이상이 설치됨
  • Ansible v2.9.0
  • Ansible Runner v2.0.2+
  • Ansible Runner HTTP Event Emitter 플러그인 v1.0.0 이상
  • Python 3.8.6+
  • OpenShift Python client v0.12.0+
  • cluster-admin 권한이 있는 계정으로 oc 를 사용하여 OpenShift Container Platform 4.12 클러스터에 로그인함
  • 클러스터가 이미지를 가져올 수 있도록 하려면 이미지를 내보내는 리포지토리를 공개로 설정하거나 이미지 가져오기 보안을 구성해야 합니다.

5.4.2.2. 프로젝트 생성

Operator SDK CLI를 사용하여 memcached-operator라는 프로젝트를 생성합니다.

프로세스

  1. 프로젝트에 사용할 디렉터리를 생성합니다.

    $ mkdir -p $HOME/projects/memcached-operator
  2. 디렉터리로 변경합니다.

    $ cd $HOME/projects/memcached-operator
  3. ansible 플러그인과 함께 operator-sdk init 명령을 실행하여 프로젝트를 초기화합니다.

    $ operator-sdk init \
        --plugins=ansible \
        --domain=example.com
5.4.2.2.1. PROJECT 파일

operator-sdk init 명령으로 생성된 파일 중에는 Kubebuilder PROJECT 파일이 있습니다. 이어서 프로젝트 루트에서 실행되는 operator-sdk 명령과 help 출력에서는 이 파일을 읽고 프로젝트 유형이 Ansible임을 확인합니다. 예를 들면 다음과 같습니다.

domain: example.com
layout:
- ansible.sdk.operatorframework.io/v1
plugins:
  manifests.sdk.operatorframework.io/v2: {}
  scorecard.sdk.operatorframework.io/v2: {}
  sdk.x-openshift.io/v1: {}
projectName: memcached-operator
version: "3"

5.4.2.3. API 생성

Operator SDK CLI를 사용하여 Memcached API를 생성합니다.

프로세스

  • 다음 명령을 실행하여 그룹이 cache이고 버전이 v1, 종류가 Memcached인 API를 생성합니다.

    $ operator-sdk create api \
        --group cache \
        --version v1 \
        --kind Memcached \
        --generate-role 1
    1
    API에 대한 Ansible 역할을 생성합니다.

API가 생성되면 Operator 프로젝트에서 다음 구조를 사용하여 업데이트합니다.

Memcached CRD
샘플 Memcached 리소스 포함
관리자

다음을 사용하여 클러스터 상태를 원하는 상태로 조정하는 프로그램입니다.

  • 조정기(Ansible 역할 또는 플레이북 중 하나)
  • watches.yaml 파일(Memcached 리소스를 memcached Ansible 역할에 연결)

5.4.2.4. 관리자 수정

Memcached 리소스가 생성, 업데이트 또는 삭제될 때마다 실행되는 Ansible 역할의 형태로 조정 논리를 제공하도록 Operator 프로젝트를 업데이트합니다.

프로세스

  1. 다음 구조를 사용하여 roles/memcached/tasks/main.yml 파일을 업데이트합니다.

    ---
    - name: start memcached
      k8s:
        definition:
          kind: Deployment
          apiVersion: apps/v1
          metadata:
            name: '{{ ansible_operator_meta.name }}-memcached'
            namespace: '{{ ansible_operator_meta.namespace }}'
          spec:
            replicas: "{{size}}"
            selector:
              matchLabels:
                app: memcached
            template:
              metadata:
                labels:
                  app: memcached
              spec:
                containers:
                - name: memcached
                  command:
                  - memcached
                  - -m=64
                  - -o
                  - modern
                  - -v
                  image: "docker.io/memcached:1.4.36-alpine"
                  ports:
                    - containerPort: 11211

    memcached 역할은 memcached 배포가 있는지 확인하고 배포 크기를 설정합니다.

  2. roles/memcached/defaults/main.yml 파일을 편집하여 Ansible 역할에 사용되는 변수의 기본값을 설정합니다.

    ---
    # defaults file for Memcached
    size: 1
  3. 다음 구조를 사용하여 config/samples/cache_v1_memcached.yaml 파일에서 Memcached 샘플 리소스를 업데이트합니다.

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      labels:
        app.kubernetes.io/name: memcached
        app.kubernetes.io/instance: memcached-sample
        app.kubernetes.io/part-of: memcached-operator
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/created-by: memcached-operator
      name: memcached-sample
    spec:
      size: 3

    CR(사용자 정의 리소스) 사양의 키-값 쌍은 Ansible에 추가 변수로 전달됩니다.

참고

spec 필드에 있는 모든 변수의 이름은 Ansible을 실행하기 전에 Operator에서 스네이크 케이스(밑줄이 포함된 소문자)로 변환합니다. 예를 들어 사양의 serviceAccount는 Ansible에서 service_account로 변환됩니다.

watches.yaml 파일에서 snakeCaseParameters 옵션을 false로 설정하여 이 대소문자 변환을 비활성화할 수 있습니다. 애플리케이션에 예상대로 입력되고 있는지 확인하려면 변수에 대해 Ansible에서 일부 유형 검증을 수행하는 것이 좋습니다.

5.4.2.5. 프록시 지원 활성화

Operator 작성자는 네트워크 프록시를 지원하는 Operator를 개발할 수 있습니다. 클러스터 관리자는 OLM(Operator Lifecycle Manager)에서 처리하는 환경 변수에 대한 프록시 지원을 구성합니다. 프록시된 클러스터를 지원하려면 Operator에서 다음 표준 프록시 변수에 대한 환경을 검사하고 해당 값을 Operands에 전달해야 합니다.

  • HTTP_PROXY
  • HTTPS_PROXY
  • NO_PROXY
참고

이 튜토리얼에서는 예제 환경 변수로 HTTP_PROXY를 사용합니다.

사전 요구 사항

  • 클러스터 전체 egress 프록시가 활성화된 클러스터입니다.

프로세스

  1. roles/memcached/tasks/main.yml 파일을 다음으로 업데이트하여 배포에 환경 변수를 추가합니다.

    ...
    env:
       - name: HTTP_PROXY
         value: '{{ lookup("env", "HTTP_PROXY") | default("", True) }}'
       - name: http_proxy
         value: '{{ lookup("env", "HTTP_PROXY") | default("", True) }}'
    ...
  2. config/manager/manager.yaml 파일에 다음을 추가하여 Operator 배포에서 환경 변수를 설정합니다.

    containers:
     - args:
       - --leader-elect
       - --leader-election-id=ansible-proxy-demo
       image: controller:latest
       name: manager
       env:
         - name: "HTTP_PROXY"
           value: "http_proxy_test"

5.4.2.6. Operator 실행

다음 세 가지 방법으로 Operator SDK CLI를 사용하여 Operator를 빌드하고 실행할 수 있습니다.

  • Go 프로그램으로 클러스터 외부에서 로컬로 실행합니다.
  • 클러스터에서 배포로 실행합니다.
  • Operator를 번들로 제공하고 OLM(Operator Lifecycle Manager)을 사용하여 클러스터에 배포합니다.
5.4.2.6.1. 클러스터 외부에서 로컬로 실행

Operator 프로젝트를 클러스터 외부의 Go 프로그램으로 실행할 수 있습니다. 이는 배포 및 테스트 속도를 높이기 위한 개발 목적에 유용합니다.

프로세스

  • 다음 명령을 실행하여 ~/.kube/config 파일에 구성된 클러스터에 CRD(사용자 정의 리소스 정의)를 설치하고 Operator를 로컬로 실행합니다.

    $ make install run

    출력 예

    ...
    {"level":"info","ts":1612589622.7888272,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612589622.7897573,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    {"level":"info","ts":1612589622.789971,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    {"level":"info","ts":1612589622.7899997,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612589622.8904517,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612589622.8905244,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}

5.4.2.6.2. 클러스터에서 배포로 실행

Operator 프로젝트를 클러스터에서 배포로 실행할 수 있습니다.

프로세스

  1. 다음 make 명령을 실행하여 Operator 이미지를 빌드하고 내보냅니다. 액세스할 수 있는 리포지토리를 참조하려면 다음 단계에서 IMG 인수를 수정합니다. Quay.io와 같은 리포지토리 사이트에 컨테이너를 저장하기 위해 계정을 받을 수 있습니다.

    1. 이미지를 빌드합니다.

      $ make docker-build IMG=<registry>/<user>/<image_name>:<tag>
      참고

      Operator용 SDK에서 생성한 Dockerfile은 Go 빌드에 대해 GOARCH=amd64 를 명시적으로 참조합니다. AMD64 이외의 아키텍처의 경우 GOARCH=$TARGETARCH 로 수정할 수 있습니다. Docker는 자동으로 -platform 에서 지정한 값으로 환경 변수를 설정합니다. Buildah를 사용하면 -build-arg 를 목적으로 사용해야 합니다. 자세한 내용은 다중 아키텍처를 참조하십시오.

    2. 이미지를 리포지토리로 내보냅니다.

      $ make docker-push IMG=<registry>/<user>/<image_name>:<tag>
      참고

      두 명령 모두 이미지의 이름과 태그(예: IMG=<registry>/<user>/<image_name>:<tag>)를 Makefile에 설정할 수 있습니다. 기본 이미지 이름을 설정하려면 IMG ?= controller:latest 값을 수정합니다.

  2. 다음 명령을 실행하여 Operator를 배포합니다.

    $ make deploy IMG=<registry>/<user>/<image_name>:<tag>

    기본적으로 이 명령은 <project_name>-system 형식으로 된 Operator 프로젝트 이름을 사용하여 네임스페이스를 생성하고 배포에 사용됩니다. 이 명령은 또한 config/rbac에서 RBAC 매니페스트를 설치합니다.

  3. 다음 명령을 실행하여 Operator가 실행 중인지 확인합니다.

    $ oc get deployment -n <project_name>-system

    출력 예

    NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
    <project_name>-controller-manager       1/1     1            1           8m

5.4.2.6.3. Operator 번들링 및 Operator Lifecycle Manager를 통한 배포
5.4.2.6.3.1. Operator 번들

Operator 번들 형식은 Operator SDK 및 Operator Lifecycle Manager (OLM)의 기본 패키지 메서드입니다. Operator SDK를 사용하여 Operator 프로젝트를 번들 이미지로 빌드하고 푸시하여 OLM에서 Operator를 사용할 수 있습니다.

사전 요구 사항

  • 개발 워크스테이션에 Operator SDK CLI가 설치됨
  • OpenShift CLI (oc) v4.12 이상이 설치됨
  • Operator SDK를 사용하여 Operator 프로젝트를 초기화함

프로세스

  1. Operator 프로젝트 디렉터리에서 다음 make 명령을 실행하여 Operator 이미지를 빌드하고 내보냅니다. 액세스할 수 있는 리포지토리를 참조하려면 다음 단계에서 IMG 인수를 수정합니다. Quay.io와 같은 리포지토리 사이트에 컨테이너를 저장하기 위해 계정을 받을 수 있습니다.

    1. 이미지를 빌드합니다.

      $ make docker-build IMG=<registry>/<user>/<operator_image_name>:<tag>
      참고

      Operator용 SDK에서 생성한 Dockerfile은 Go 빌드에 대해 GOARCH=amd64 를 명시적으로 참조합니다. AMD64 이외의 아키텍처의 경우 GOARCH=$TARGETARCH 로 수정할 수 있습니다. Docker는 자동으로 -platform 에서 지정한 값으로 환경 변수를 설정합니다. Buildah를 사용하면 -build-arg 를 목적으로 사용해야 합니다. 자세한 내용은 다중 아키텍처를 참조하십시오.

    2. 이미지를 리포지토리로 내보냅니다.

      $ make docker-push IMG=<registry>/<user>/<operator_image_name>:<tag>
  2. Operator SDK generate bundlebundle validate 명령을 비롯한 다양한 명령을 호출하는 make bundle 명령을 실행하여 Operator 번들 매니페스트를 생성합니다.

    $ make bundle IMG=<registry>/<user>/<operator_image_name>:<tag>

    Operator의 번들 매니페스트는 애플리케이션을 표시, 생성, 관리하는 방법을 설명합니다. make bundle 명령은 Operator 프로젝트에서 다음 파일 및 디렉터리를 생성합니다.

    • ClusterServiceVersion 오브젝트를 포함하는 bundle/manifests라는 번들 매니페스트 디렉터리
    • bundle/metadata라는 번들 메타데이터 디렉터리
    • config/crd 디렉터리의 모든 CRD(사용자 정의 리소스 정의)
    • Dockerfile bundle.Dockerfile

    그런 다음 operator-sdk bundle validate를 사용하여 이러한 파일을 자동으로 검증하고 디스크상의 번들 표현이 올바른지 확인합니다.

  3. 다음 명령을 실행하여 번들 이미지를 빌드하고 내보냅니다. OLM에서는 하나 이상의 번들 이미지를 참조하는 인덱스 이미지를 통해 Operator 번들을 사용합니다.

    1. 번들 이미지를 빌드합니다. 이미지를 내보낼 레지스트리, 사용자 네임스페이스, 이미지 태그에 대한 세부 정보를 사용하여 BUNDLE_IMG를 설정합니다.

      $ make bundle-build BUNDLE_IMG=<registry>/<user>/<bundle_image_name>:<tag>
    2. 번들 이미지를 내보냅니다.

      $ docker push <registry>/<user>/<bundle_image_name>:<tag>
5.4.2.6.3.2. Operator Lifecycle Manager를 사용하여 Operator 배포

OLM(Operator Lifecycle Manager)은 Kubernetes 클러스터에서 Operator 및 관련 서비스를 설치, 업데이트하고 라이프사이클을 관리하는 데 도움이 됩니다. OLM은 기본적으로 OpenShift Container Platform에 설치되고 Kubernetes 확장으로 실행되므로 추가 툴 없이 모든 Operator 라이프사이클 관리 기능에 웹 콘솔과 OpenShift CLI(oc)를 사용할 수 있습니다.

Operator 번들 형식은 Operator SDK 및 OLM의 기본 패키지 메서드입니다. Operator SDK를 사용하여 OLM에서 번들 이미지를 신속하게 실행하여 올바르게 실행되는지 확인할 수 있습니다.

사전 요구 사항

  • 개발 워크스테이션에 Operator SDK CLI가 설치됨
  • Operator 번들 이미지를 빌드하여 레지스트리로 내보냄
  • Kubernetes 기반 클러스터에 OLM이 설치됨( apiextensions.k8s.io/v1 CRD(예: OpenShift Container Platform 4.12)를 사용하는 경우 v1.16.0 이상)
  • cluster-admin 권한이 있는 계정을 사용하여 oc로 클러스터에 로그인됨

프로세스

  1. 다음 명령을 입력하여 클러스터에서 Operator를 실행합니다.

    $ operator-sdk run bundle \1
        -n <namespace> \2
        <registry>/<user>/<bundle_image_name>:<tag> 3
    1
    run bundle 명령은 유효한 파일 기반 카탈로그를 생성하고 OLM을 사용하여 클러스터에 Operator 번들을 설치합니다.
    2
    선택 사항: 기본적으로 이 명령은 ~/.kube/config 파일의 현재 활성 프로젝트에 Operator를 설치합니다. -n 플래그를 추가하면 설치에 다른 네임스페이스 범위를 설정할 수 있습니다.
    3
    이미지를 지정하지 않으면 명령에서 quay.io/operator-framework/opm:latest 를 기본 인덱스 이미지로 사용합니다. 이미지를 지정하면 명령에서 번들 이미지 자체를 인덱스 이미지로 사용합니다.
    중요

    OpenShift Container Platform 4.11부터 run bundle 명령은 기본적으로 Operator 카탈로그의 파일 기반 카탈로그 형식을 지원합니다. Operator 카탈로그의 더 이상 사용되지 않는 SQLite 데이터베이스 형식은 계속 지원되지만 향후 릴리스에서 제거됩니다. Operator 작성자는 워크플로우를 파일 기반 카탈로그 형식으로 마이그레이션하는 것이 좋습니다.

    이 명령은 다음 작업을 수행합니다.

    • 번들 이미지를 참조하는 인덱스 이미지를 생성합니다. 인덱스 이미지는 불투명하고 일시적이지만 프로덕션에서 카탈로그에 번들을 추가하는 방법을 정확하게 반영합니다.
    • OperatorHub에서 Operator를 검색할 수 있도록 새 인덱스 이미지를 가리키는 카탈로그 소스를 생성합니다.
    • OperatorGroup,Subscription,InstallPlan 및 RBAC를 포함한 기타 모든 필수 리소스를 생성하여 Operator를 클러스터에 배포합니다.

5.4.2.7. 사용자 정의 리소스 생성

Operator가 설치되면 Operator에서 현재 클러스터에 제공하는 CR(사용자 정의 리소스)을 생성하여 Operator를 테스트할 수 있습니다.

사전 요구 사항

  • Memcached CR을 제공하는 Memcached Operator의 예가 클러스터에 설치됨

프로세스

  1. Operator가 설치된 네임스페이스로 변경합니다. 예를 들어 make deploy 명령을 사용하여 Operator를 배포한 경우 다음을 실행합니다.

    $ oc project memcached-operator-system
  2. 다음 사양을 포함하도록 config/samples/cache_v1_memcached.yaml의 샘플 Memcached CR 매니페스트를 편집합니다.

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    ...
    spec:
    ...
      size: 3
  3. CR을 생성합니다.

    $ oc apply -f config/samples/cache_v1_memcached.yaml
  4. Memcached Operator에서 샘플 CR에 대한 배포를 올바른 크기로 생성하는지 확인합니다.

    $ oc get deployments

    출력 예

    NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
    memcached-operator-controller-manager   1/1     1            1           8m
    memcached-sample                        3/3     3            3           1m

  5. Pod 및 CR 상태를 확인하여 상태가 Memcached Pod 이름으로 업데이트되었는지 확인합니다.

    1. Pod를 확인합니다.

      $ oc get pods

      출력 예

      NAME                                  READY     STATUS    RESTARTS   AGE
      memcached-sample-6fd7c98d8-7dqdr      1/1       Running   0          1m
      memcached-sample-6fd7c98d8-g5k7v      1/1       Running   0          1m
      memcached-sample-6fd7c98d8-m7vn7      1/1       Running   0          1m

    2. CR 상태 확인:

      $ oc get memcached/memcached-sample -o yaml

      출력 예

      apiVersion: cache.example.com/v1
      kind: Memcached
      metadata:
      ...
        name: memcached-sample
      ...
      spec:
        size: 3
      status:
        nodes:
        - memcached-sample-6fd7c98d8-7dqdr
        - memcached-sample-6fd7c98d8-g5k7v
        - memcached-sample-6fd7c98d8-m7vn7

  6. 배포 크기를 업데이트합니다.

    1. config/samples/cache_v1_memcached.yaml 파일을 업데이트하여 Memcached CR의 spec.size 필드를 3에서 5로 변경합니다.

      $ oc patch memcached memcached-sample \
          -p '{"spec":{"size": 5}}' \
          --type=merge
    2. Operator에서 배포 크기를 변경하는지 확인합니다.

      $ oc get deployments

      출력 예

      NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
      memcached-operator-controller-manager   1/1     1            1           10m
      memcached-sample                        5/5     5            5           3m

  7. 다음 명령을 실행하여 CR을 삭제합니다.

    $ oc delete -f config/samples/cache_v1_memcached.yaml
  8. 이 튜토리얼의 일부로 생성된 리소스를 정리합니다.

    • make deploy 명령을 사용하여 Operator를 테스트한 경우 다음 명령을 실행합니다.

      $ make undeploy
    • operator-sdk run bundle 명령을 사용하여 Operator를 테스트한 경우 다음 명령을 실행합니다.

      $ operator-sdk cleanup <project_name>

5.4.2.8. 추가 리소스

5.4.3. Ansible 기반 Operator의 프로젝트 레이아웃

operator-sdk CLI에서는 각 Operator 프로젝트에 대해 다양한 패키지 및 파일을 생성하거나 스캐폴드를 지정할 수 있습니다.

5.4.3.1. Ansible 기반 프로젝트 레이아웃

operator-sdk init --plugins ansible 명령을 사용하여 생성된 Ansible 기반 Operator 프로젝트에는 다음 디렉터리 및 파일이 포함됩니다.

파일 또는 디렉터리목적

Dockerfile

Operator의 컨테이너 이미지를 빌드하는 Dockerfile입니다.

Makefile

Operator 바이너리를 래핑하는 컨테이너 이미지를 빌드, 게시, 배포할 대상 및 CRD(사용자 정의 리소스 정의)를 설치 및 설치 제거할 대상입니다.

PROJECT

Operator의 메타데이터 정보가 포함된 YAML 파일입니다.

config/crd

기본 CRD 파일 및 kustomization.yaml 파일 설정입니다.

config/default

배포를 위해 모든 Operator 매니페스트를 수집합니다. make deploy 명령에서 사용합니다.

config/manager

컨트롤러 관리자 배포입니다.

config/prometheus

Operator 모니터링을 위한 ServiceMonitor 리소스입니다.

config/rbac

리더 선택 방식 및 인증 프록시 관련 역할 및 역할 바인딩입니다.

config/samples

CRD에 대해 생성된 샘플 리소스입니다.

config/testing

테스트를 위한 샘플 구성입니다.

playbooks/

플레이북을 실행할 하위 디렉터리입니다.

roles/

역할 트리를 실행할 하위 디렉터리입니다.

watches.yaml

조사할 리소스의 GVK(그룹/버전/종류) 및 Ansible 호출 메서드입니다. create api 명령을 사용하여 새 항목이 추가되었습니다.

requirements.yml

빌드 중 설치할 Ansible 컬렉션 및 역할 종속 항목이 포함된 YAML 파일입니다.

molecule/

역할 및 Operator의 끝점 테스트에 대한 개별 시나리오입니다.

5.4.4. 최신 Operator SDK 버전을 위한 프로젝트 업데이트

OpenShift Container Platform 4.12는 Operator SDK 1.25.4를 지원합니다. 워크스테이션에 1.22.2 CLI가 이미 설치되어 있는 경우 최신 버전을 설치하여 CLI를 1.25.4로 업데이트할 수 있습니다.

그러나 기존 Operator 프로젝트에서 Operator SDK 1.25.4와의 호환성을 유지하려면 1.22.2 이후의 중단된 변경 사항에 대한 업데이트 단계가 필요합니다. 1.22.2를 사용하여 이전에 생성되거나 유지 관리되는 Operator 프로젝트에서 업데이트 단계를 수동으로 수행해야 합니다.

5.4.4.1. Operator SDK 1.25.4에 대한 Ansible 기반 Operator 프로젝트 업데이트

다음 절차에서는 1.25.4와의 호환성을 위해 기존 Ansible 기반 Operator 프로젝트를 업데이트합니다.

사전 요구 사항

  • Operator SDK 1.25.4가 설치됨
  • Operator SDK 1.22.2를 사용하여 생성되거나 유지 관리되는 Operator 프로젝트

프로세스

  1. config/default/manager_auth_proxy_patch.yaml 파일을 다음과 같이 변경합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: controller-manager
      namespace: system
    spec:
      template:
        spec:
          containers:
          - name: kube-rbac-proxy
            image: registry.redhat.io/openshift4/ose-kube-rbac-proxy:v4.12 1
            args:
            - "--secure-listen-address=0.0.0.0:8443"
            - "--upstream=http://127.0.0.1:8080/"
            - "--logtostderr=true"
            - "--v=0"
    ...
    1
    태그 버전을 v4.11 에서 v4.12 로 업데이트합니다.
  2. Makefile 을 다음과 같이 변경합니다.

    1. 다중 아키텍처 빌드 지원을 활성화하려면 docker-buildx 대상을 프로젝트 Makefile 에 추가합니다.

      Makefile의 예

      # PLATFORMS defines the target platforms for  the manager image be build to provide support to multiple
      # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
      # - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
      # - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
      # - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> than the export will fail)
      # To properly provided solutions that supports more than one platform you should use this option.
      PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
      .PHONY: docker-buildx
      docker-buildx: test ## Build and push docker image for the manager for cross-platform support
      	# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
      	sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
      	- docker buildx create --name project-v3-builder
      	docker buildx use project-v3-builder
      	- docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross
      	- docker buildx rm project-v3-builder
      	rm Dockerfile.cross

    2. Operator 프로젝트에서 64비트 ARM 아키텍처에 대한 지원을 활성화하려면 Makefile 을 다음과 같이 변경합니다.

      이전 Makefile

      OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
      ARCH := $(shell uname -m | sed 's/x86_64/amd64/')

      New Makefile

      OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
      ARCH := $(shell uname -m | sed 's/x86_64/amd64/' |  sed 's/aarch64/arm64/')

    3. 다음 예와 같이 Kustomize 버전을 v4.5.5 로 업데이트합니다.

      이전 Makefile

      .PHONY: kustomize
      KUSTOMIZE = $(shell pwd)/bin/kustomize
      kustomize: ## Download kustomize locally if necessary.
      ifeq (,$(wildcard $(KUSTOMIZE)))
      ifeq (,$(shell which kustomize 2>/dev/null))
      	@{ \
      	set -e ;\
      	mkdir -p $(dir $(KUSTOMIZE)) ;\
      	curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.8.7/kustomize_v3.8.7_$(OS)_$(ARCH).tar.gz | \
      	tar xzf - -C bin/ ;\
      	}
      else

      New Makefile

      .PHONY: kustomize
      KUSTOMIZE = $(shell pwd)/bin/kustomize
      kustomize: ## Download kustomize locally if necessary.
      ifeq (,$(wildcard $(KUSTOMIZE)))
      ifeq (,$(shell which kustomize 2>/dev/null))
      	@{ \
      	set -e ;\
      	mkdir -p $(dir $(KUSTOMIZE)) ;\
      	curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v4.5.5/kustomize_v4.5.5_$(OS)_$(ARCH).tar.gz | \ 1
      	tar xzf - -C bin/ ;\
      	}
      else

      1
      버전 v3.8.7v4.5.5 로 업데이트합니다.
      중요

      kustomize 버전 4.0.0go-getter 플러그인을 제거하고 이전 버전과 호환되지 않는 변경 사항을 도입했습니다. 이전 버전의 Kustomize에 의존하는 Operator 프로젝트는 최신 릴리스에서 작동하지 않을 수 있습니다.

    4. Makefile 에 변경 사항을 적용하고 Operator를 다시 빌드하려면 다음 명령을 입력합니다.

      $ make
  3. 다음 예와 같이 Operator의 Dockerfile에서 이미지 태그를 업데이트합니다.

    Dockerfile 예

    FROM registry.redhat.io/openshift4/ose-ansible-operator:v4.12 1

    1
    version 태그를 v4.12 로 업데이트합니다.
  4. 다음 예와 같이 config/default/kustomizations.yaml 파일을 업데이트합니다.

    kustomizations.yaml 파일의 예

    # Adds namespace to all resources.
    namespace: memcached-operator-system
    # Value of this field is prepended to the
    # names of all resources, e.g. a deployment named
    # "wordpress" becomes "alices-wordpress".
    # Note that it should also match with the prefix (text before '-') of the namespace
    # field above.
    namePrefix: memcached-operator-
    
    # Labels to add to all resources and selectors.
    #labels: 1
    #- includeSelectors: true 2
    #  pairs:
    #    someName: someValue
    
    resources: 3
    - ../crd
    - ../rbac
    - ../manager

    1
    commonLabels 필드를 labels 필드로 바꿉니다.
    2
    includeSelectors: true 를 추가합니다.
    3
    bases 필드를 resources 필드로 바꿉니다.
  5. 다음과 같은 변경 사항으로 molecule/default/kustomize.yml 파일을 업데이트합니다.

    molecule/default/kustomize.yml 파일의 예

    ---
    - name: Build kustomize testing overlay
      # load_restrictor must be set to none so we can load patch files from the default overlay
      command: '{{ kustomize }} build --load-restrictor LoadRestrictionsNone' 1
      args:
        chdir: '{{ config_dir }}/testing'
      register: resources
      changed_when: false

    1
    --load_restrictor none--load-restrictor LoadRestrictionNone 로 바꿉니다.

5.4.4.2. 추가 리소스

5.4.5. Operator SDK의 Ansible 지원

5.4.5.1. 사용자 정의 리소스 파일

Operator는 Kubernetes 확장 메커니즘인 CRD(사용자 정의 리소스 정의)를 사용하므로 CR(사용자 정의 리소스)이 기본 제공되는 네이티브 Kubernetes 오브젝트처럼 보이고 작동합니다.

CR 파일 형식은 Kubernetes 리소스 파일입니다. 오브젝트에는 필수 및 선택적 필드가 있습니다.

표 5.1. 사용자 정의 리소스 필드
필드설명

apiVersion

생성할 CR의 버전입니다.

kind

생성할 CR의 종류입니다.

metadata

생성할 Kubernetes별 메타데이터입니다.

spec(선택 사항)

Ansible에 전달되는 변수의 키-값 목록입니다. 이 필드는 기본적으로 비어 있습니다.

status

오브젝트의 현재 상태를 요약합니다. Ansible 기반 Operator의 경우 CRD에 대해 status 하위 리소스가 활성화되고, 기본적으로 CR statuscondition 정보를 포함하는 operator_sdk.util.k8s_status Ansible 모듈에서 관리합니다.

annotations

CR에 추가할 Kubernetes별 주석입니다.

다음 CR 주석 목록은 Operator의 동작을 수정합니다.

표 5.2. Ansible 기반 Operator 주석
주석설명

ansible.operator-sdk/reconcile-period

CR 조정 간격을 지정합니다. 이 값은 표준 Golang 패키지 time을 사용하여 구문 분석합니다. 특히 ParseDuration은 기본 접미사인 s를 적용하여 초 단위로 값을 지정하는 데 사용됩니다.

Ansible 기반 Operator 주석의 예

apiVersion: "test1.example.com/v1alpha1"
kind: "Test1"
metadata:
  name: "example"
annotations:
  ansible.operator-sdk/reconcile-period: "30s"

5.4.5.2. watches.yaml 파일

GVK(그룹/버전/종류)는 Kubernetes API의 고유 ID입니다. watches.yaml 파일에는 GVK로 확인하는 CR(사용자 정의 리소스)에서 Ansible 역할 또는 플레이북으로의 매핑 목록이 포함됩니다. Operator는 이 매핑 파일이 미리 정의된 위치(/opt/ansible/watches.yaml)에 있을 것으로 예상합니다.

표 5.3. watches.yaml 파일 매핑
필드설명

group

조사할 CR 그룹입니다.

version

조사할 CR 버전입니다.

kind

조사할 CR의 종류입니다.

role(기본값)

컨테이너에 추가된 Ansible 역할의 경로입니다. 예를 들어 roles 디렉터리가 /opt/ansible/roles/에 있고 역할 이름이 busybox인 경우 이 값은 /opt/ansible/roles/busybox입니다. 이 필드는 playbook 필드와 함께 사용할 수 없습니다.

playbook

컨테이너에 추가된 Ansible 플레이북의 경로입니다. 이 플레이북은 역할을 호출하는 방법이 될 것으로 예상됩니다. 이 필드는 role 필드와 함께 사용할 수 없습니다.

reconcilePeriod(선택 사항)

지정된 CR에 대한 조정 간격, 즉 역할 또는 플레이북이 실행되는 간격입니다.

manageStatus(선택 사항)

true(기본값)로 설정된 경우 Operator는 일반적으로 CR의 상태를 관리합니다. false로 설정하면 지정된 역할이나 플레이북 또는 별도의 컨트롤러에서 CR의 상태를 관리합니다.

watches.yaml 파일의 예

- version: v1alpha1 1
  group: test1.example.com
  kind: Test1
  role: /opt/ansible/roles/Test1

- version: v1alpha1 2
  group: test2.example.com
  kind: Test2
  playbook: /opt/ansible/playbook.yml

- version: v1alpha1 3
  group: test3.example.com
  kind: Test3
  playbook: /opt/ansible/test3.yml
  reconcilePeriod: 0
  manageStatus: false

1
Test1test1 역할에 매핑하는 간단한 예입니다.
2
Test2를 플레이북에 매핑하는 간단한 예입니다.
3
더 복잡한 Test3 종류 예제입니다. 플레이북에서 CR 상태를 다시 큐에 넣거나 관리하지 않습니다.
5.4.5.2.1. 고급 옵션

GVK별 watches.yaml 파일에 고급 기능을 추가하여 사용할 수 있습니다. 해당 기능은 group, version, kind, playbook 또는 role 필드로 이동할 수 있습니다.

일부 기능은 해당 CR의 주석을 사용하여 리소스별로 덮어쓸 수 있습니다. 덮어쓸 수 있는 옵션에는 아래에 지정된 주석이 있습니다.

표 5.4. 고급 watches.yaml 파일 옵션
기능YAML 키설명덮어쓸 주석기본값

기간 조정

reconcilePeriod

특정 CR에 대한 조정 실행 간격입니다.

ansible.operator-sdk/reconcile-period

1m

상태 관리

manageStatus

Operator에서 각 CR status 섹션의 conditions 섹션을 관리할 수 있습니다.

 

true

종속 리소스 조사

watchDependentResources

Operator에서 Ansible을 통해 생성한 리소스를 동적으로 조사할 수 있습니다.

 

true

클러스터 범위 리소스 조사

watchClusterScopedResources

Operator에서 Ansible을 통해 생성한 클러스터 범위 리소스를 조사할 수 있습니다.

 

false

최대 실행기 아티팩트 수

maxRunnerArtifacts

Ansible Runner에서 각 개별 리소스에 대해 Operator 컨테이너에 보관하는 아티팩트 디렉터리의 수를 관리합니다.

ansible.operator-sdk/max-runner-artifacts

20

고급 옵션이 있는 watches.yml 파일의 예

- version: v1alpha1
  group: app.example.com
  kind: AppService
  playbook: /opt/ansible/playbook.yml
  maxRunnerArtifacts: 30
  reconcilePeriod: 5s
  manageStatus: False
  watchDependentResources: False

5.4.5.3. Ansible로 전송된 추가 변수

추가 변수는 Ansible로 보낸 다음 Operator에서 관리할 수 있습니다. CR(사용자 정의 리소스)의 spec 섹션은 키-값 쌍을 추가 변수로 전달합니다. 이는 ansible-playbook 명령에 전달된 추가 변수와 동일합니다.

또한 Operator는 CR 이름 및 CR 네임스페이스에 대한 meta 필드에 추가 변수를 전달합니다.

다음 CR 예제의 경우

apiVersion: "app.example.com/v1alpha1"
kind: "Database"
metadata:
  name: "example"
spec:
  message: "Hello world 2"
  newParameter: "newParam"

Ansible에 추가 변수로 전달되는 구조는 다음과 같습니다.

{ "meta": {
        "name": "<cr_name>",
        "namespace": "<cr_namespace>",
  },
  "message": "Hello world 2",
  "new_parameter": "newParam",
  "_app_example_com_database": {
     <full_crd>
   },
}

messagenewParameter 필드는 최상위 레벨에서 추가 변수로 설정되며, meta는 Operator에 정의된 CR에 대한 관련 메타데이터를 제공합니다. meta 필드는 Ansible의 점 표기법을 사용하여 액세스할 수 있습니다. 예를 들면 다음과 같습니다.

---
- debug:
    msg: "name: {{ ansible_operator_meta.name }}, {{ ansible_operator_meta.namespace }}"

5.4.5.4. Ansible Runner 디렉터리

Ansible Runner는 컨테이너에서 실행되는 Ansible에 대한 정보를 보관합니다. 해당 정보는 /tmp/ansible-operator/runner/<group>/<version>/<kind>/<namespace>/<name>에 있습니다.

추가 리소스

5.4.6. Ansible용 Kubernetes 컬렉션

Ansible을 사용하여 Kubernetes에서 애플리케이션 라이프사이클을 관리하려면 Ansible용 Kubernetes 컬렉션을 사용하면 됩니다. 개발자는 이 Ansible 모듈 컬렉션을 통해 YAML로 작성된 기존 Kubernetes 리소스 파일을 활용하거나 네이티브 Ansible에서 라이프사이클 관리를 표시할 수 있습니다.

기존 Kubernetes 리소스 파일과 함께 Ansible을 사용할 때의 가장 큰 이점 중 하나는 Jinja 템플릿을 사용할 수 있다는 점입니다. 그러면 Ansible의 몇 가지 간단한 변수를 사용하여 리소스를 사용자 정의할 수 있습니다.

이 섹션에서는 Kubernetes 컬렉션 사용에 대해 자세히 설명합니다. 시작하려면 로컬 워크스테이션에 컬렉션을 설치하고 플레이북을 사용하여 테스트한 후 Operator 내에서 사용하십시오.

5.4.6.1. Ansible용 Kubernetes 컬렉션 설치

로컬 워크스테이션에 Ansible용 Kubernetes 컬렉션을 설치할 수 있습니다.

프로세스

  1. Ansible 2.9 이상을 설치합니다.

    $ sudo dnf install ansible
  2. OpenShift python 클라이언트 패키지를 설치합니다.

    $ pip3 install openshift
  3. 다음 메서드 중 하나를 사용하여 Kubernetes 컬렉션을 설치합니다.

    • Ansible Galaxy에서 컬렉션을 직접 설치할 수 있습니다.

      $ ansible-galaxy collection install community.kubernetes
    • Operator를 이미 초기화한 경우 프로젝트의 최상위 수준에 requirements.yml 파일이 있을 수 있습니다. 이 파일은 Operator 작동을 위해 설치해야 하는 Ansible 종속 항목을 지정합니다. 기본적으로 이 파일은 community.kubernetes 컬렉션과 operator_sdk.util 컬렉션을 설치합니다. 이 컬렉션은 Operator별 fuctions에 대한 모듈 및 플러그인을 제공합니다.

      requirements.yml 파일에서 종속 모듈을 설치하려면 다음을 수행합니다.

      $ ansible-galaxy collection install -r requirements.yml

5.4.6.2. 로컬에서 Kubernetes 컬렉션 테스트

Operator 개발자는 매번 Operator를 실행하고 다시 빌드하는 대신 로컬 머신에서 Ansible 코드를 실행할 수 있습니다.

사전 요구 사항

  • Ansible 기반 Operator 프로젝트를 초기화하고 Operator SDK를 사용하여 생성한 Ansible 역할이 있는 API 생성
  • Ansible용 Kubernetes 컬렉션 설치

프로세스

  1. Ansible 기반 Operator 프로젝트 디렉터리에서 원하는 Ansible 논리로 roles/<kind>/tasks/main.yml 파일을 수정합니다. roles/<kind>/ 디렉터리는 API를 생성하는 동안 --generate-role 플래그를 사용할 때 생성됩니다. 교체 가능한 <kind>는 API에 지정한 종류와 일치합니다.

    다음 예제에서는 state라는 변수 값에 따라 구성 맵을 생성 및 삭제합니다.

    ---
    - name: set ConfigMap example-config to {{ state }}
      community.kubernetes.k8s:
        api_version: v1
        kind: ConfigMap
        name: example-config
        namespace: <operator_namespace> 1
        state: "{{ state }}"
      ignore_errors: true 2
    1
    구성 맵이 생성할 네임스페이스를 지정합니다.
    2
    ignore_errors: true를 설정하면 존재하지 않는 구성 맵을 삭제해도 실패하지 않습니다.
  2. roles/<kind>/defaults/main.yml 파일을 수정하여 state를 기본적으로 present로 설정합니다.

    ---
    state: present
  3. 프로젝트의 최상위 디렉터리에 playbook.yml 파일을 생성하여 Ansible 플레이북을 생성하고 <kind> 역할을 포함합니다.

    ---
    - hosts: localhost
      roles:
        - <kind>
  4. Playbook을 실행합니다.

    $ ansible-playbook playbook.yml

    출력 예

    [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [localhost] ********************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************
    ok: [localhost]
    
    TASK [memcached : set ConfigMap example-config to present] ********************************************************************************
    changed: [localhost]
    
    PLAY RECAP ********************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

  5. 구성 맵이 생성되었는지 확인합니다.

    $ oc get configmaps

    출력 예

    NAME               DATA   AGE
    example-config     0      2m1s

  6. stateabsent로 설정하여 플레이북을 재실행합니다.

    $ ansible-playbook playbook.yml --extra-vars state=absent

    출력 예

    [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [localhost] ********************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************
    ok: [localhost]
    
    TASK [memcached : set ConfigMap example-config to absent] ********************************************************************************
    changed: [localhost]
    
    PLAY RECAP ********************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

  7. 구성 맵이 삭제되었는지 확인합니다.

    $ oc get configmaps

5.4.6.3. 다음 단계

5.4.7. Operator 내에서 Ansible 사용

로컬에서 Ansible용 Kubernetes 컬렉션 사용에 익숙한 후 CR(사용자 정의 리소스)이 변경될 때 Operator 내부에서 동일한 Ansible 논리를 트리거할 수 있습니다. 이 예제에서는 Operator에서 조사하는 특정 Kubernetes 리소스에 Ansible 역할을 매핑합니다. 이 매핑은 watches.yaml 파일에서 수행됩니다.

5.4.7.1. 사용자 정의 리소스 파일

Operator는 Kubernetes 확장 메커니즘인 CRD(사용자 정의 리소스 정의)를 사용하므로 CR(사용자 정의 리소스)이 기본 제공되는 네이티브 Kubernetes 오브젝트처럼 보이고 작동합니다.

CR 파일 형식은 Kubernetes 리소스 파일입니다. 오브젝트에는 필수 및 선택적 필드가 있습니다.

표 5.5. 사용자 정의 리소스 필드
필드설명

apiVersion

생성할 CR의 버전입니다.

kind

생성할 CR의 종류입니다.

metadata

생성할 Kubernetes별 메타데이터입니다.

spec(선택 사항)

Ansible에 전달되는 변수의 키-값 목록입니다. 이 필드는 기본적으로 비어 있습니다.

status

오브젝트의 현재 상태를 요약합니다. Ansible 기반 Operator의 경우 CRD에 대해 status 하위 리소스가 활성화되고, 기본적으로 CR statuscondition 정보를 포함하는 operator_sdk.util.k8s_status Ansible 모듈에서 관리합니다.

annotations

CR에 추가할 Kubernetes별 주석입니다.

다음 CR 주석 목록은 Operator의 동작을 수정합니다.

표 5.6. Ansible 기반 Operator 주석
주석설명

ansible.operator-sdk/reconcile-period

CR 조정 간격을 지정합니다. 이 값은 표준 Golang 패키지 time을 사용하여 구문 분석합니다. 특히 ParseDuration은 기본 접미사인 s를 적용하여 초 단위로 값을 지정하는 데 사용됩니다.

Ansible 기반 Operator 주석의 예

apiVersion: "test1.example.com/v1alpha1"
kind: "Test1"
metadata:
  name: "example"
annotations:
  ansible.operator-sdk/reconcile-period: "30s"

5.4.7.2. Ansible 기반 Operator를 로컬에서 테스트

Operator 프로젝트의 최상위 디렉터리에서 make run 명령을 사용하여 로컬에서 실행되는 Ansible 기반 Operator 내부의 논리를 테스트할 수 있습니다. make run Makefile 대상은 watches.yaml 파일에서 읽고 ~/.kube/config 파일을 사용하여 k8s 모듈과 같은 방식으로 Kubernetes 클러스터와 통신하는 ansible-operator 바이너리를 로컬로 실행합니다.

참고

환경 변수 ANSIBLE_ROLES_PATH를 설정하거나 ansible-roles-path 플래그를 사용하여 역할 경로를 사용자 정의할 수 있습니다. ANSIBLE_ROLES_PATH 값에 역할이 없는 경우 Operator는 {{current directory}}/roles에서 역할을 찾습니다.

사전 요구 사항

프로세스

  1. CR(사용자 정의 리소스)에 대한 CRD(사용자 정의 리소스 정의) 및 적절한 RBAC(역할 기반 액세스 제어) 정의를 설치합니다.

    $ make install

    출력 예

    /usr/bin/kustomize build config/crd | kubectl apply -f -
    customresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created

  2. make run 명령을 실행합니다.

    $ make run

    출력 예

    /home/user/memcached-operator/bin/ansible-operator run
    {"level":"info","ts":1612739145.2871568,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.10.1","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"}
    ...
    {"level":"info","ts":1612739148.347306,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"}
    {"level":"info","ts":1612739148.3488882,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2}
    {"level":"info","ts":1612739148.3490262,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false}
    {"level":"info","ts":1612739148.3490646,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612739148.350217,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    {"level":"info","ts":1612739148.3506632,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    {"level":"info","ts":1612739148.350784,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612739148.5511978,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612739148.5512562,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}

    이제 Operator에서 이벤트의 CR을 조사하므로 CR을 생성하면 Ansible 역할이 실행됩니다.

    참고

    config/samples/<gvk>.yaml CR 매니페스트 예제를 살펴보십시오.

    apiVersion: <group>.example.com/v1alpha1
    kind: <kind>
    metadata:
      name: "<kind>-sample"

    spec 필드가 설정되지 않았기 때문에 추가 변수 없이 Ansible이 호출됩니다. CR에서 Ansible로 추가 변수를 전달하는 방법은 다른 섹션에서 설명합니다. Operator에 적절한 기본값을 설정하는 것이 중요합니다.

  3. 기본 변수 statepresent로 설정하여 CR 인스턴스를 생성합니다.

    $ oc apply -f config/samples/<gvk>.yaml
  4. example-config 구성 맵이 생성되었는지 확인합니다.

    $ oc get configmaps

    출력 예

    NAME                    STATUS    AGE
    example-config          Active    3s

  5. config/samples/<gvk>.yaml 파일을 수정하여 state 필드를 absent로 설정합니다. 예를 들면 다음과 같습니다.

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    spec:
      state: absent
  6. 변경 사항을 적용합니다.

    $ oc apply -f config/samples/<gvk>.yaml
  7. 구성 맵이 삭제되었는지 확인합니다.

    $ oc get configmap

5.4.7.3. 클러스터에서 Ansible 기반 Operator 테스트

Operator 내부에서 로컬로 사용자 정의 Ansible 논리를 테스트한 후 OpenShift Container Platform 클러스터의 Pod 내부에서 Operator를 테스트할 수 있습니다. 이 논리는 프로덕션 용도로 선호됩니다.

Operator 프로젝트를 클러스터에서 배포로 실행할 수 있습니다.

프로세스

  1. 다음 make 명령을 실행하여 Operator 이미지를 빌드하고 내보냅니다. 액세스할 수 있는 리포지토리를 참조하려면 다음 단계에서 IMG 인수를 수정합니다. Quay.io와 같은 리포지토리 사이트에 컨테이너를 저장하기 위해 계정을 받을 수 있습니다.

    1. 이미지를 빌드합니다.

      $ make docker-build IMG=<registry>/<user>/<image_name>:<tag>
      참고

      Operator용 SDK에서 생성한 Dockerfile은 Go 빌드에 대해 GOARCH=amd64 를 명시적으로 참조합니다. AMD64 이외의 아키텍처의 경우 GOARCH=$TARGETARCH 로 수정할 수 있습니다. Docker는 자동으로 -platform 에서 지정한 값으로 환경 변수를 설정합니다. Buildah를 사용하면 -build-arg 를 목적으로 사용해야 합니다. 자세한 내용은 다중 아키텍처를 참조하십시오.

    2. 이미지를 리포지토리로 내보냅니다.

      $ make docker-push IMG=<registry>/<user>/<image_name>:<tag>
      참고

      두 명령 모두 이미지의 이름과 태그(예: IMG=<registry>/<user>/<image_name>:<tag>)를 Makefile에 설정할 수 있습니다. 기본 이미지 이름을 설정하려면 IMG ?= controller:latest 값을 수정합니다.

  2. 다음 명령을 실행하여 Operator를 배포합니다.

    $ make deploy IMG=<registry>/<user>/<image_name>:<tag>

    기본적으로 이 명령은 <project_name>-system 형식으로 된 Operator 프로젝트 이름을 사용하여 네임스페이스를 생성하고 배포에 사용됩니다. 이 명령은 또한 config/rbac에서 RBAC 매니페스트를 설치합니다.

  3. 다음 명령을 실행하여 Operator가 실행 중인지 확인합니다.

    $ oc get deployment -n <project_name>-system

    출력 예

    NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
    <project_name>-controller-manager       1/1     1            1           8m

5.4.7.4. Ansible 로그

Ansible 기반 Operator는 Ansible 실행에 대한 로그를 제공합니다. 이 로그는 Ansible 작업을 디버깅하는 데 유용할 수 있습니다. 로그에는 Operator의 내부 및 Kubernetes와의 상호 작용에 대한 세부 정보가 포함될 수 있습니다.

5.4.7.4.1. Ansible 로그 보기

사전 요구 사항

  • 클러스터에서 배포로 실행되는 Ansible 기반 Operator

프로세스

  • Ansible 기반 Operator에서 로그를 보려면 다음 명령을 실행합니다.

    $ oc logs deployment/<project_name>-controller-manager \
        -c manager \1
        -n <namespace> 2
    1
    manager 컨테이너의 로그를 확인합니다.
    2
    make deploy 명령을 사용하여 Operator를 배포로 실행한 경우 <project_name>-system 네임스페이스를 사용합니다.

    출력 예

    {"level":"info","ts":1612732105.0579333,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.10.1","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"}
    {"level":"info","ts":1612732105.0587437,"logger":"cmd","msg":"WATCH_NAMESPACE environment variable not set. Watching all namespaces.","Namespace":""}
    I0207 21:08:26.110949       7 request.go:645] Throttling request took 1.035521578s, request: GET:https://172.30.0.1:443/apis/flowcontrol.apiserver.k8s.io/v1alpha1?timeout=32s
    {"level":"info","ts":1612732107.768025,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":"127.0.0.1:8080"}
    {"level":"info","ts":1612732107.768796,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2}
    {"level":"info","ts":1612732107.7688773,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false}
    {"level":"info","ts":1612732107.7688901,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612732107.770032,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    I0207 21:08:27.770185       7 leaderelection.go:243] attempting to acquire leader lease  memcached-operator-system/memcached-operator...
    {"level":"info","ts":1612732107.770202,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    I0207 21:08:27.784854       7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator
    {"level":"info","ts":1612732107.7850506,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612732107.8853772,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612732107.8854098,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":4}

5.4.7.4.2. 로그에서 전체 Ansible 결과 활성화

환경 변수 ANSIBLE_DEBUG_LOGSTrue로 설정하여 로그에서 전체 Ansible 결과를 확인할 수 있습니다. 이 방법은 디버깅 시 유용할 수 있습니다.

프로세스

  • 다음 구성을 포함하도록 config/manager/manager.yamlconfig/default/manager_auth_proxy_patch.yaml 파일을 편집합니다.

          containers:
          - name: manager
            env:
            - name: ANSIBLE_DEBUG_LOGS
              value: "True"
5.4.7.4.3. 로그에서 verbose 디버깅 활성화

Ansible 기반 Operator를 개발하는 동안 로그에서 추가 디버깅을 활성화하는 것이 도움이 될 수 있습니다.

프로세스

  • ansible.sdk.operatorframework.io/verbosity 주석을 사용자 정의 리소스에 추가하여 원하는 세부 정보 표시 수준을 활성화합니다. 예를 들면 다음과 같습니다.

    apiVersion: "cache.example.com/v1alpha1"
    kind: "Memcached"
    metadata:
      name: "example-memcached"
      annotations:
        "ansible.sdk.operatorframework.io/verbosity": "4"
    spec:
      size: 4

5.4.8. 사용자 정의 리소스 상태 관리

5.4.8.1. Ansible 기반 Operator의 사용자 정의 리소스 상태 정보

Ansible 기반 Operator는 이전 Ansible 실행에 대한 일반적인 정보를 사용하여 CR(사용자 정의 리소스) status 하위 리소스를 자동으로 업데이트합니다. 여기에는 다음과 같이 성공 및 실패한 작업의 수와 관련 오류 메시지가 포함됩니다.

status:
  conditions:
  - ansibleResult:
      changed: 3
      completion: 2018-12-03T13:45:57.13329
      failures: 1
      ok: 6
      skipped: 0
    lastTransitionTime: 2018-12-03T13:45:57Z
    message: 'Status code was -1 and not [200]: Request failed: <urlopen error [Errno
      113] No route to host>'
    reason: Failed
    status: "True"
    type: Failure
  - lastTransitionTime: 2018-12-03T13:46:13Z
    message: Running reconciliation
    reason: Running
    status: "True"
    type: Running

Ansible 기반 Operator를 사용하면 Operator 작성자가 operator_sdk.util 컬렉션에 포함된 k8s_status Ansible 모듈로 사용자 정의 상태 값을 제공할 수 있습니다. 그러면 작성자는 원하는 키-값 쌍을 사용하여 Ansible 내에서 status를 업데이트할 수 있습니다.

기본적으로 Ansible 기반 Operator에는 항상 위에 표시된 것처럼 일반 Ansible 실행 출력이 포함됩니다. 애플리케이션에서 Ansible 출력을 통해 상태를 업데이트하지 않도록 하려면 애플리케이션에서 수동으로 상태를 추적하면 됩니다.

5.4.8.2. 수동으로 사용자 정의 리소스 상태 추적

operator_sdk.util 컬렉션을 사용하면 Ansible 기반 Operator를 수정하여 애플리케이션에서 CR(사용자 정의 리소스) 상태를 수동으로 추적할 수 있습니다.

사전 요구 사항

  • Operator SDK를 사용하여 Ansible 기반 Operator 프로젝트 생성

프로세스

  1. manageStatus 필드를 false로 설정하여 watches.yaml 파일을 업데이트합니다.

    - version: v1
      group: api.example.com
      kind: <kind>
      role: <role>
      manageStatus: false
  2. operator_sdk.util.k8s_status Ansible 모듈을 사용하여 하위 리소스를 업데이트합니다. 예를 들어 키 test 및 값 data를 사용하여 업데이트하려면 operator_sdk.util을 다음과 같이 사용하면 됩니다.

    - operator_sdk.util.k8s_status:
        api_version: app.example.com/v1
        kind: <kind>
        name: "{{ ansible_operator_meta.name }}"
        namespace: "{{ ansible_operator_meta.namespace }}"
        status:
          test: data
  3. 역할의 meta/main.yml 파일에 컬렉션을 선언할 수 있습니다. 이 파일은 스캐폴드된 Ansible 기반 Operator에 포함됩니다.

    collections:
      - operator_sdk.util
  4. 역할 메타에 컬렉션을 선언한 후에는 k8s_status 모듈을 직접 호출할 수 있습니다.

    k8s_status:
      ...
      status:
        key1: value1
Red Hat logoGithubRedditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

© 2024 Red Hat, Inc.