먼저 operator-sdk에서 기본적으로 제공해주는 Dockerfile에서는 우리의 operator를 빌드한 뒤에, container image로 만들어준다.
# Build the manager binary
FROM golang:1.20 AS builder
ARG TARGETOS
ARG TARGETARCH
WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
# RUN rm ./go.sum
go mod download;
# Copy the go source
COPY cmd/main.go cmd/main.go
COPY api/ api/
COPY internal/controller/ internal/controller/
COPY assets/ assets
# Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go;
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532
ENTRYPOINT ["/manager"]
딱히 특별한 부분은 없다. golang 이미지에서 빌드한 뒤에 빌드한 binary를 실행하는 것이 전부이다.
operator-sdk는 docker image 빌드를 간단하게 make docker-build
makefile 명령어로 제공하고 있다. 기본 image명이 controller:latest
이기 때문에 IMG
환경변수를 설정하여 원하는 image이름으로 바꾸어 빌드할 수 있다.
IMG=docker.io/sample/nginx-operator:v0.1 make docker-build
...
=> => naming to docker.io/sample/nginx-operator:v0.1
종료된 이후에 image가 잘 빌드되었는 지 확인해보도록 하자.
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sample/nginx-operator v0.1 89c69ad45a52 52 seconds ago 54.4MB
성공한 것을 볼 수 있다.
operator의 container image가 준비되었다면 make deploy
명령어를 통해서 간단하게 배포가 가능하다. 먼저 make deploy
명령어의 구성을 보도록 하자.
...
.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -
...
kustomize
를 사용하여 deploy를 진행하는 것을 볼 수 있는데, 여기서 config/manager
에 어떤 파일이 있는 지 확인해보도록 하자.
apiVersion: v1
kind: Namespace
metadata:
labels:
control-plane: controller-manager
app.kubernetes.io/name: namespace
app.kubernetes.io/instance: system
app.kubernetes.io/component: manager
app.kubernetes.io/created-by: nginx-operator
app.kubernetes.io/part-of: nginx-operator
app.kubernetes.io/managed-by: kustomize
name: system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
labels:
control-plane: controller-manager
app.kubernetes.io/name: deployment
...
바로 우리의 operator가 있는 것을 확인할 수 있다. 즉, config/manager.yaml
에 있는 우리의 operator를 kustomize
를 통해 수정하여 배포하는 것이다.
make deploy
...
configmap/nginx-operator-manager-config created
service/nginx-operator-controller-manager-metrics-service created
deployment.apps/nginx-operator-controller-manager created
잘 배포되었다면 확인해보도록 하자.
kubectl get ns
NAME STATUS AGE
nginx-operator-system Active 24h
...
nginx-operator-system
이 잘 설치된 것을 볼 수 있다. 해당 namespace로 어떤 것들이 설치되었는 지 확인해보도록 하자.
kubectl get all -n nginx-operator-system
NAME READY STATUS RESTARTS AGE
pod/nginx-operator-controller-manager-86f64ff54c-ll9zt 2/2 Running 0 24h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-operator-controller-manager-metrics-service ClusterIP 10.106.170.206 <none> 8443/TCP 24h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-operator-controller-manager 1/1 1 1 24h
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-operator-controller-manager-86f64ff54c 1 1 1 24h
operator가 잘 설치된 것을 확인하였다. 이제 operator에 대한 operand를 만들어보도록 하자.
apiVersion: operator.example.com/v1alpha1
kind: NginxOperator
metadata:
name: cluster
namespace: nginx-operator-system
spec:
replicas: 3
kubectl create -f
명령어로 위의 operand manifest를 실행시켜보도록 하자.
kubectl get pods -n nginx-operator-system
NAME READY STATUS RESTARTS AGE
nginx-operator-controller-manager-86f64ff54c-ll9zt 2/2 Running 0 24h
nginxoperator-sample-6f69c8cf95-95tr9 1/1 Running 0 24h
nginxoperator-sample-6f69c8cf95-fl8nz 1/1 Running 0 24h
nginxoperator-sample-6f69c8cf95-lhcp6 1/1 Running 0 24h
문제없이 operand pod들이 올라온 것을 볼 수 있다.
다음으로 우리가 설정한 operator의 상태를 확인해보도록 하자.
kubectl describe -n nginx-operator-system nginxoperators.operator.example.com nginxoperator-sample
Name: nginxoperator-sample
Namespace: nginx-operator-system
Labels: app.kubernetes.io/created-by=nginx-operator
app.kubernetes.io/instance=nginxoperator-sample
app.kubernetes.io/managed-by=kustomize
app.kubernetes.io/name=nginxoperator
app.kubernetes.io/part-of=nginx-operator
Annotations: <none>
API Version: operator.example.com/v1alpha1
Kind: NginxOperator
Metadata:
Creation Timestamp: 2024-07-17T08:46:35Z
Generation: 1
Resource Version: 159315
UID: c021d411-8a21-45a8-abcd-38d6deb264d1
Spec:
Port: 8082
Replicas: 3
Status:
Conditions:
Last Transition Time: 2024-07-17T08:46:35Z
Message: operator successfully reconciling
Reason: OperatorSucceeded
Status: False
Type: OperatorDegraded
Events: <none>
OperatorDegraded
status가 False
인 것을 볼 수 있다. 여기서 user는 False
를 보고 잘못된 상태가 아닌가 생각 할 수도 있는데, OperatorDegraded
가 안되었다는 것을 알려주는 것이다. 즉, Operator가 성공했다는 것이다.
prometheus와 연동하여 확인하면 metrics이 잘 올라간 것을 볼 수 있을 것이다.