3.3. Special Resource Operator 사용
SRO(Special Resource Operator)는 드라이버 컨테이너의 빌드 및 배포를 관리하는 데 사용됩니다. 컨테이너를 빌드하고 배포하는 데 필요한 오브젝트는 Helm 차트에 정의할 수 있습니다.
이 섹션의 예제에서는 simple-kmod SpecialResource 오브젝트를 사용하여 Helm 차트를 저장하기 위해 생성된 ConfigMap 오브젝트를 가리킵니다.
3.3.1. 구성 맵을 사용하여 simple-kmod SpecialResource 구축 및 실행 링크 복사링크가 클립보드에 복사되었습니다!
이 예에서 simple-kmod 커널 모듈은 SRO(Special Resource Operator)에서 드라이버 컨테이너를 관리하는 방법을 보여줍니다. 컨테이너는 구성 맵에 저장된 Helm 차트 템플릿에 정의되어 있습니다.
사전 요구 사항
- 실행 중인 OpenShift Container Platform 클러스터가 있어야 합니다.
-
Image Registry Operator 상태를 클러스터의
Managed로 설정합니다. -
OpenShift CLI(
oc)를 설치합니다. -
cluster-admin권한이 있는 사용자로 OpenShift CLI에 로그인했습니다. - NFD (Node Feature Discovery) Operator를 설치했습니다.
- SRO가 설치되어 있어야 합니다.
-
Helm CLI(
helm)가 설치되어 있어야 합니다.
절차
simple-kmod
SpecialResource오브젝트를 생성하려면 이미지 스트림과 빌드 구성을 정의하여 이미지를 빌드하고, 컨테이너를 실행하도록 서비스 계정, 역할, 역할 바인딩 및 데몬 세트를 정의합니다. 커널 모듈을 로드할 수 있도록 권한 있는 보안 컨텍스트로 데몬 세트를 실행하려면 서비스 계정, 역할 및 역할 바인딩이 필요합니다.templates디렉터리를 생성하고 이 디렉터리로 변경합니다.$ mkdir -p chart/simple-kmod-0.0.1/templates$ cd chart/simple-kmod-0.0.1/templates이미지 스트림 및 빌드 구성에 대한 이 YAML 템플릿을
templates디렉터리에0000-buildconfig.yaml로 저장합니다.apiVersion: image.openshift.io/v1 kind: ImageStream metadata: labels: app: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}}1 name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}}2 spec: {} --- apiVersion: build.openshift.io/v1 kind: BuildConfig metadata: labels: app: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverBuild}}3 name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverBuild}}4 annotations: specialresource.openshift.io/wait: "true" specialresource.openshift.io/driver-container-vendor: simple-kmod specialresource.openshift.io/kernel-affine: "true" spec: nodeSelector: node-role.kubernetes.io/worker: "" runPolicy: "Serial" triggers: - type: "ConfigChange" - type: "ImageChange" source: git: ref: {{.Values.specialresource.spec.driverContainer.source.git.ref}} uri: {{.Values.specialresource.spec.driverContainer.source.git.uri}} type: Git strategy: dockerStrategy: dockerfilePath: Dockerfile.SRO buildArgs: - name: "IMAGE" value: {{ .Values.driverToolkitImage }} {{- range $arg := .Values.buildArgs }} - name: {{ $arg.name }} value: {{ $arg.value }} {{- end }} - name: KVER value: {{ .Values.kernelFullVersion }} output: to: kind: ImageStreamTag name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}}:v{{.Values.kernelFullVersion}}5 templates디렉터리에 설정된 RBAC 리소스 및 데몬에 대한 다음 YAML 템플릿을1000-driver-container.yaml로 저장합니다.apiVersion: v1 kind: ServiceAccount metadata: name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} rules: - apiGroups: - security.openshift.io resources: - securitycontextconstraints verbs: - use resourceNames: - privileged --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} subjects: - kind: ServiceAccount name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} namespace: {{.Values.specialresource.spec.namespace}} --- apiVersion: apps/v1 kind: DaemonSet metadata: labels: app: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} annotations: specialresource.openshift.io/wait: "true" specialresource.openshift.io/state: "driver-container" specialresource.openshift.io/driver-container-vendor: simple-kmod specialresource.openshift.io/kernel-affine: "true" specialresource.openshift.io/from-configmap: "true" spec: updateStrategy: type: OnDelete selector: matchLabels: app: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} template: metadata: labels: app: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} spec: priorityClassName: system-node-critical serviceAccount: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} serviceAccountName: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} containers: - image: image-registry.openshift-image-registry.svc:5000/{{.Values.specialresource.spec.namespace}}/{{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}}:v{{.Values.kernelFullVersion}} name: {{.Values.specialresource.metadata.name}}-{{.Values.groupName.driverContainer}} imagePullPolicy: Always command: ["/sbin/init"] lifecycle: preStop: exec: command: ["/bin/sh", "-c", "systemctl stop kmods-via-containers@{{.Values.specialresource.metadata.name}}"] securityContext: privileged: true nodeSelector: node-role.kubernetes.io/worker: "" feature.node.kubernetes.io/kernel-version.full: "{{.Values.KernelFullVersion}}"chart/simple-kmod-0.0.1디렉터리로 변경합니다.$ cd ..차트에 대한 다음 YAML을
chart/simple-kmod-0.0.1디렉터리에Chart.yaml로 저장합니다.apiVersion: v2 name: simple-kmod description: Simple kmod will deploy a simple kmod driver-container icon: https://avatars.githubusercontent.com/u/55542927 type: application version: 0.0.1 appVersion: 1.0.0
chart디렉토리에서hhelm package명령을 사용하여 차트를 생성합니다.$ helm package simple-kmod-0.0.1/출력 예
Successfully packaged chart and saved it to: /data/<username>/git/<github_username>/special-resource-operator/yaml-for-docs/chart/simple-kmod-0.0.1/simple-kmod-0.0.1.tgz차트 파일을 저장할 구성 맵을 생성합니다.
구성 맵 파일의 디렉터리를 생성합니다.
$ mkdir cmHelm 차트를
cm디렉터리에 복사합니다.$ cp simple-kmod-0.0.1.tgz cm/simple-kmod-0.0.1.tgzHelm 차트가 포함된 Helm 리포지터리를 지정하는 인덱스 파일을 생성합니다.
$ helm repo index cm --url=cm://simple-kmod/simple-kmod-chartHelm 차트에 정의된 오브젝트의 네임스페이스를 생성합니다.
$ oc create namespace simple-kmod구성 맵 오브젝트를 생성합니다.
$ oc create cm simple-kmod-chart --from-file=cm/index.yaml --from-file=cm/simple-kmod-0.0.1.tgz -n simple-kmod
구성 맵에서 생성한 Helm 차트를 사용하여 simple-kmod 오브젝트를 배포하려면 다음
SpecialResource매니페스트를 사용합니다. 이 YAML을simple-kmod-configmap.yaml로 저장합니다.apiVersion: sro.openshift.io/v1beta1 kind: SpecialResource metadata: name: simple-kmod spec: #debug: true1 namespace: simple-kmod chart: name: simple-kmod version: 0.0.1 repository: name: example url: cm://simple-kmod/simple-kmod-chart2 set: kind: Values apiVersion: sro.openshift.io/v1beta1 kmodNames: ["simple-kmod", "simple-procfs-kmod"] buildArgs: - name: "KMODVER" value: "SRO" driverContainer: source: git: ref: "master" uri: "https://github.com/openshift-psap/kvc-simple-kmod.git"명령줄에서
SpecialResource파일을 만듭니다.$ oc create -f simple-kmod-configmap.yaml
노드에서 simple-kmod 커널 모듈을 제거하려면 oc delete 명령을 사용하여 simple-kmod SpecialResource API 오브젝트를 삭제합니다. 드라이버 컨테이너 Pod가 삭제되면 커널 모듈이 언로드됩니다.
검증
simple-kmod 리소스는 오브젝트 매니페스트에 지정된 대로 simple-kmod 네임스페이스에 배포됩니다. 잠시 후 simple-kmod 드라이버 컨테이너의 빌드 Pod가 실행되기 시작합니다. 몇 분 후에 빌드가 완료되면 드라이버 컨테이너 pod가 실행됩니다.
oc get pods명령을 사용하여 빌드 Pod의 상태를 표시합니다.$ oc get pods -n simple-kmod출력 예
NAME READY STATUS RESTARTS AGE simple-kmod-driver-build-12813789169ac0ee-1-build 0/1 Completed 0 7m12s simple-kmod-driver-container-12813789169ac0ee-mjsnh 1/1 Running 0 8m2s simple-kmod-driver-container-12813789169ac0ee-qtkff 1/1 Running 0 8m2soc logs명령과 위의oc get pods명령에서 얻은 빌드 Pod 이름을 사용하여 simple-kmod 드라이버 컨테이너 이미지 빌드의 로그를 표시합니다.$ oc logs pod/simple-kmod-driver-build-12813789169ac0ee-1-build -n simple-kmodsimple-kmod 커널 모듈이 로드되었는지 확인하려면 위의
oc get pods명령에서 반환된 드라이버 컨테이너 Pod 중 하나에서lsmod명령을 실행합니다.$ oc exec -n simple-kmod -it pod/simple-kmod-driver-container-12813789169ac0ee-mjsnh -- lsmod | grep simple출력 예
simple_procfs_kmod 16384 0 simple_kmod 16384 0
sro_kind_completed_info SRO Prometheus 지표는 배포되는 다양한 오브젝트의 상태에 대한 정보를 제공합니다. 이는 SRO CR 설치 문제를 해결하는 데 유용할 수 있습니다. SRO는 환경의 상태를 확인하는 데 사용할 수 있는 다른 유형의 메트릭도 제공합니다.
3.3.2. hub-and-spoke 토폴로지를 위한 simple-kmod SpecialResource를 구축하고 실행 링크 복사링크가 클립보드에 복사되었습니다!
hub-and-spoke 배포에서 Special Resource Operator(SRO)를 사용하여 hub 클러스터를 하나 이상의 관리 클러스터에 연결할 수 있습니다.
다음 예제 절차에서는 SRO가 허브에서 드라이버 컨테이너를 빌드하는 방법을 보여줍니다. SRO는 허브 클러스터 리소스를 감시하고 사용자 지정에 제공하는 리소스를 생성하는 데 사용하는 helm 차트의 OpenShift Container Platform 버전을 식별합니다.
사전 요구 사항
- 실행 중인 OpenShift Container Platform 클러스터가 있어야 합니다.
-
OpenShift CLI(
oc)를 설치합니다. -
cluster-admin권한이 있는 사용자로 OpenShift CLI에 로그인했습니다. - SRO가 설치되어 있어야 합니다.
-
Helm CLI(
helm)가 설치되어 있어야 합니다. - RHACM(Red Hat Advanced Cluster Management)을 설치했습니다.
- 컨테이너 레지스트리를 구성했습니다.
절차
다음 명령을 실행하여
templates디렉터리를 생성합니다.$ mkdir -p charts/acm-simple-kmod-0.0.1/templates다음 명령을 실행하여
templates디렉터리로 변경합니다.$ cd charts/acm-simple-kmod-0.0.1/templatesBuildConfig,Policy및PlacementRule리소스에 대한 템플릿 파일을 생성합니다.이미지 스트림에 대한 이 YAML 템플릿을 저장하고
templates디렉터리에0001-buildconfig.yaml로 .apiVersion: build.openshift.io/v1 kind: BuildConfig metadata: labels: app: {{ printf "%s-%s" .Values.specialResourceModule.metadata.name .Values.kernelFullVersion | replace "." "-" | replace "_" "-" | trunc 63 }} name: {{ printf "%s-%s" .Values.specialResourceModule.metadata.name .Values.kernelFullVersion | replace "." "-" | replace "_" "-" | trunc 63 }} annotations: specialresource.openshift.io/wait: "true" spec: nodeSelector: node-role.kubernetes.io/worker: "" runPolicy: "Serial" triggers: - type: "ConfigChange" - type: "ImageChange" source: dockerfile: | FROM {{ .Values.driverToolkitImage }} as builder WORKDIR /build/ RUN git clone -b {{.Values.specialResourceModule.spec.set.git.ref}} {{.Values.specialResourceModule.spec.set.git.uri}} WORKDIR /build/simple-kmod RUN make all install KVER={{ .Values.kernelFullVersion }} FROM registry.redhat.io/ubi8/ubi-minimal RUN microdnf -y install kmod COPY --from=builder /etc/driver-toolkit-release.json /etc/ COPY --from=builder /lib/modules/{{ .Values.kernelFullVersion }}/* /lib/modules/{{ .Values.kernelFullVersion }}/ strategy: dockerStrategy: dockerfilePath: Dockerfile.SRO buildArgs: - name: "IMAGE" value: {{ .Values.driverToolkitImage }} {{- range $arg := .Values.buildArgs }} - name: {{ $arg.name }} value: {{ $arg.value }} {{- end }} - name: KVER value: {{ .Values.kernelFullVersion }} output: to: kind: DockerImage name: {{.Values.registry}}/{{.Values.specialResourceModule.metadata.name}}-{{.Values.groupName.driverContainer}}:{{.Values.kernelFullVersion}}ACM 정책에 대한 이 YAML 템플릿을
templates디렉터리에0002-policy.yaml로 저장합니다.apiVersion: policy.open-cluster-management.io/v1 kind: Policy metadata: name: policy-{{.Values.specialResourceModule.metadata.name}}-ds annotations: policy.open-cluster-management.io/categories: CM Configuration Management policy.open-cluster-management.io/controls: CM-2 Baseline Configuration policy.open-cluster-management.io/standards: NIST-CSF spec: remediationAction: enforce disabled: false policy-templates: - objectDefinition: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: config-{{.Values.specialResourceModule.metadata.name}}-ds spec: remediationAction: enforce severity: low namespaceselector: exclude: - kube-* include: - '*' object-templates: - complianceType: musthave objectDefinition: apiVersion: v1 kind: Namespace metadata: name: {{.Values.specialResourceModule.spec.namespace}} - complianceType: mustonlyhave objectDefinition: apiVersion: v1 kind: ServiceAccount metadata: name: {{.Values.specialResourceModule.metadata.name}} namespace: {{.Values.specialResourceModule.spec.namespace}} - complianceType: mustonlyhave objectDefinition: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{.Values.specialResourceModule.metadata.name}} namespace: {{.Values.specialResourceModule.spec.namespace}} rules: - apiGroups: - security.openshift.io resources: - securitycontextconstraints verbs: - use resourceNames: - privileged - complianceType: mustonlyhave objectDefinition: apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{.Values.specialResourceModule.metadata.name}} namespace: {{.Values.specialResourceModule.spec.namespace}} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{.Values.specialResourceModule.metadata.name}} subjects: - kind: ServiceAccount name: {{.Values.specialResourceModule.metadata.name}} namespace: {{.Values.specialResourceModule.spec.namespace}} - complianceType: musthave objectDefinition: apiVersion: apps/v1 kind: DaemonSet metadata: labels: app: {{ printf "%s-%s" .Values.specialResourceModule.metadata.name .Values.kernelFullVersion | replace "." "-" | replace "_" "-" | trunc 63 }} name: {{ printf "%s-%s" .Values.specialResourceModule.metadata.name .Values.kernelFullVersion | replace "." "-" | replace "_" "-" | trunc 63 }} namespace: {{.Values.specialResourceModule.spec.namespace}} spec: updateStrategy: type: OnDelete selector: matchLabels: app: {{ printf "%s-%s" .Values.specialResourceModule.metadata.name .Values.kernelFullVersion | replace "." "-" | replace "_" "-" | trunc 63 }} template: metadata: labels: app: {{ printf "%s-%s" .Values.specialResourceModule.metadata.name .Values.kernelFullVersion | replace "." "-" | replace "_" "-" | trunc 63 }} spec: priorityClassName: system-node-critical serviceAccount: {{.Values.specialResourceModule.metadata.name}} serviceAccountName: {{.Values.specialResourceModule.metadata.name}} containers: - image: {{.Values.registry}}/{{.Values.specialResourceModule.metadata.name}}-{{.Values.groupName.driverContainer}}:{{.Values.kernelFullVersion}} name: {{.Values.specialResourceModule.metadata.name}} imagePullPolicy: Always command: [sleep, infinity] lifecycle: preStop: exec: command: ["modprobe", "-r", "-a" , "simple-kmod", "simple-procfs-kmod"] securityContext: privileged: truetemplates디렉터리에 정책을 배치하기 위해 이 YAML 템플릿을0003-policy.yaml로 저장합니다.apiVersion: apps.open-cluster-management.io/v1 kind: PlacementRule metadata: name: {{.Values.specialResourceModule.metadata.name}}-placement spec: clusterConditions: - status: "True" type: ManagedClusterConditionAvailable clusterSelector: matchExpressions: - key: name operator: NotIn values: - local-cluster --- apiVersion: policy.open-cluster-management.io/v1 kind: PlacementBinding metadata: name: {{.Values.specialResourceModule.metadata.name}}-binding placementRef: apiGroup: apps.open-cluster-management.io kind: PlacementRule name: {{.Values.specialResourceModule.metadata.name}}-placement subjects: - apiGroup: policy.open-cluster-management.io kind: Policy name: policy-{{.Values.specialResourceModule.metadata.name}}-ds다음 명령을 실행하여
charts/acm-simple-kmod-0.0.1디렉토리로 변경합니다.cd ..차트에 대한 다음 YAML 템플릿을
charts/acm-simple-kmod-0.0.1디렉터리에Chart.yaml로 저장합니다.apiVersion: v2 name: acm-simple-kmod description: Build ACM enabled simple-kmod driver with SpecialResourceOperator icon: https://avatars.githubusercontent.com/u/55542927 type: application version: 0.0.1 appVersion: 1.6.4
차트디렉터리에서 명령을 사용하여 차트를 만듭니다.$ helm package acm-simple-kmod-0.0.1/출력 예
Successfully packaged chart and saved it to: <directory>/charts/acm-simple-kmod-0.0.1.tgz차트 파일을 저장할 구성 맵을 만듭니다.
다음 명령을 실행하여 구성 맵 파일의 디렉터리를 생성합니다.
$ mkdir cm다음 명령을 실행하여 Helm 차트를
cm디렉터리에 복사합니다.$ cp acm-simple-kmod-0.0.1.tgz cm/acm-simple-kmod-0.0.1.tgz다음 명령을 실행하여 Helm 차트가 포함된 Helm 리포지터리를 지정하는 인덱스 파일을 생성합니다.
$ helm repo index cm --url=cm://acm-simple-kmod/acm-simple-kmod-chart다음 명령을 실행하여 Helm 차트에 정의된 오브젝트의 네임스페이스를 생성합니다.
$ oc create namespace acm-simple-kmod다음 명령을 실행하여 구성 맵 오브젝트를 생성합니다.
$ oc create cm acm-simple-kmod-chart --from-file=cm/index.yaml --from-file=cm/acm-simple-kmod-0.0.1.tgz -n acm-simple-kmod
다음
SpecialResourceModule매니페스트를 사용하여 구성 맵에서 만든 Helm 차트를 사용하여simple-kmod오브젝트를 배포합니다. 이 YAML 파일을acm-simple-kmod.yaml로 저장합니다.apiVersion: sro.openshift.io/v1beta1 kind: SpecialResourceModule metadata: name: acm-simple-kmod spec: namespace: acm-simple-kmod chart: name: acm-simple-kmod version: 0.0.1 repository: name: acm-simple-kmod url: cm://acm-simple-kmod/acm-simple-kmod-chart set: kind: Values apiVersion: sro.openshift.io/v1beta1 buildArgs: - name: "KMODVER" value: "SRO" registry: <your_registry>1 git: ref: master uri: https://github.com/openshift-psap/kvc-simple-kmod.git watch: - path: "$.metadata.labels.openshiftVersion" apiVersion: cluster.open-cluster-management.io/v1 kind: ManagedCluster name: spoke1- 1
- 구성한 레지스트리의 URL을 지정합니다.
다음 명령을 실행하여 특수 리소스 모듈을 생성합니다.
$ oc apply -f charts/examples/acm-simple-kmod.yaml
검증
다음 명령을 실행하여 빌드 Pod의 상태를 확인합니다.
$ KUBECONFIG=~/hub/auth/kubeconfig oc get pod -n acm-simple-kmod출력 예
NAME READY STATUS RESTARTS AGE acm-simple-kmod-4-18-0-305-34-2-el8-4-x86-64-1-build 0/1 Completed 0 42m다음 명령을 실행하여 정책이 생성되었는지 확인합니다.
$ KUBECONFIG=~/hub/auth/kubeconfig oc get placementrules,placementbindings,policies -n acm-simple-kmod출력 예
NAME AGE REPLICAS placementrule.apps.open-cluster-management.io/acm-simple-kmod-placement 40m NAME AGE placementbinding.policy.open-cluster-management.io/acm-simple-kmod-binding 40m NAME REMEDIATION ACTION COMPLIANCE STATE AGE policy.policy.open-cluster-management.io/policy-acm-simple-kmod-ds enforce Compliant 40m다음 명령을 실행하여 리소스가 조정되었는지 확인합니다.
$ KUBECONFIG=~/hub/auth/kubeconfig oc get specialresourcemodule acm-simple-kmod -o json | jq -r '.status'출력 예
{ "versions": { "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:6a3330ef5a178435721ff4efdde762261a9c55212e9b4534385e04037693fbe4": { "complete": true } } }다음 명령을 실행하여 리소스가 스포크에서 실행되고 있는지 확인합니다.
$ KUBECONFIG=~/spoke1/kubeconfig oc get ds,pod -n acm-simple-kmod출력 예
AME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/acm-simple-kmod-4-18-0-305-45-1-el8-4-x86-64 3 3 3 3 3 <none> 26m NAME READY STATUS RESTARTS AGE pod/acm-simple-kmod-4-18-0-305-45-1-el8-4-x86-64-brw78 1/1 Running 0 26m pod/acm-simple-kmod-4-18-0-305-45-1-el8-4-x86-64-fqh5h 1/1 Running 0 26m pod/acm-simple-kmod-4-18-0-305-45-1-el8-4-x86-64-m9sfd 1/1 Running 0 26m