From c29e39dee4f58c0e812fb528f4c0f4739992df40 Mon Sep 17 00:00:00 2001 From: yylt Date: Mon, 6 Jul 2026 17:25:25 +0800 Subject: [PATCH] capi --- .github/workflows/capi.yml | 78 +++++++++++ Dockerfile-capi | 83 ++++++++++++ capi-examples/crd-install-job.yaml | 57 ++++++++ capi-examples/deployments.yaml | 200 +++++++++++++++++++++++++++++ 4 files changed, 418 insertions(+) create mode 100644 .github/workflows/capi.yml create mode 100644 Dockerfile-capi create mode 100644 capi-examples/crd-install-job.yaml create mode 100644 capi-examples/deployments.yaml diff --git a/.github/workflows/capi.yml b/.github/workflows/capi.yml new file mode 100644 index 0000000..e5d825c --- /dev/null +++ b/.github/workflows/capi.yml @@ -0,0 +1,78 @@ +name: capi +permissions: + contents: read + +on: + push: + branches: [ capi ] + workflow_dispatch: + +env: + REGISTRY_NAME: "${{ secrets.MY_HUB_NAME }}" + REGISTRY_USER: "${{ secrets.MY_HUB_USER }}" + REGISTRY_PASS: "${{ secrets.MY_HUB_PASSWORD }}" + BUILDX_NO_DEFAULT_ATTESTATIONS: 1 + REPO_EKS_PREFIX: ${{ secrets.REPO_EKS_PREFIX }} + REPO_EKS_USER: ${{ secrets.REPO_EKS_USER }} + REPO_EKS_TOKEN: ${{ secrets.REPO_EKS_TOKEN }} + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + + - name: Get image tag + id: tag + run: | + echo "tag=$(date +'%Y%m%d%H%M')" >> $GITHUB_ENV + + - uses: actions/checkout@v7 + + - name: Login to Registry + uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY_NAME }} + username: ${{ env.REGISTRY_USER }} + password: ${{ env.REGISTRY_PASS }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Clone eks-kubean + run: | + git clone --depth 1 \ + https://${{ env.REPO_EKS_USER }}:${{ env.REPO_EKS_TOKEN }}@${{ env.REPO_EKS_PREFIX }}/eks-kubean.git eks-kubean + env: + GIT_SSL_NO_VERIFY: 1 + + - name: Clone eks-cluster-api + run: | + git clone --depth 1 \ + https://${{ env.REPO_EKS_USER }}:${{ env.REPO_EKS_TOKEN }}@${{ env.REPO_EKS_PREFIX }}/eks-cluster-api.git eks-cluster-api + env: + GIT_SSL_NO_VERIFY: 1 + + - name: Clone eks-cluster-api-provider + run: | + git clone --depth 1 \ + https://${{ env.REPO_EKS_USER }}:${{ env.REPO_EKS_TOKEN }}@${{ env.REPO_EKS_PREFIX }}/eks-cluster-api-provider.git eks-cluster-api-provider + env: + GIT_SSL_NO_VERIFY: 1 + + - name: Clone captain + run: | + git clone --depth 1 \ + https://${{ env.REPO_EKS_USER }}:${{ env.REPO_EKS_TOKEN }}@${{ env.REPO_EKS_PREFIX }}/captain.git captain + env: + GIT_SSL_NO_VERIFY: 1 + + - name: Docker Buildx (multi-arch) + run: | + docker buildx build \ + --no-cache \ + --provenance false --sbom false \ + --platform linux/amd64,linux/arm64 \ + --output "type=image,push=true" \ + --tag ${{ env.REGISTRY_NAME }}/multiarch/capi:${{ env.tag }} \ + --file ./Dockerfile-capi . diff --git a/Dockerfile-capi b/Dockerfile-capi new file mode 100644 index 0000000..be41361 --- /dev/null +++ b/Dockerfile-capi @@ -0,0 +1,83 @@ +# syntax=docker/dockerfile:1.4 + +FROM --platform=$BUILDPLATFORM golang:1.26-bookworm AS build + +ARG TARGETOS +ARG TARGETARCH +ARG TARGETPLATFORM +ARG BUILDPLATFORM + +ENV GO111MODULE=on + +WORKDIR /build + +# ============================================================ +# 1. eks-kubean: CRD + 2 binaries +# ============================================================ +COPY eks-kubean /build/eks-kubean + +WORKDIR /build/eks-kubean +RUN curl -fsSLo /usr/local/bin/kubectl "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/${BUILDPLATFORM}/kubectl" \ + && chmod +x /usr/local/bin/kubectl + +RUN mkdir -p /crds/kubean \ + && cp api/charts/crds/*.yaml /crds/kubean/ \ + && CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go mod vendor \ + && CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -mod vendor -o /bins/kubean-operator ./cmd/kubean-operator/main.go \ + && CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -mod vendor -o /bins/kubean-admission ./cmd/kubean-admission/main.go + +# ============================================================ +# 2. eks-cluster-api: CRD + 1 binary (manager) +# ============================================================ +COPY eks-cluster-api /build/eks-cluster-api + +WORKDIR /build/eks-cluster-api +RUN kubectl kustomize config/crd > /crds/cluster-api.yaml \ + && CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -o /bins/cluster-api-manager . + +# ============================================================ +# 3. eks-cluster-api-provider: CRD + 2 binaries (manager + ansible-controller) +# ============================================================ +COPY eks-cluster-api-provider /build/eks-cluster-api-provider + +WORKDIR /build/eks-cluster-api-provider +RUN kubectl kustomize config/crd > /crds/capo.yaml \ + && CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -ldflags "-extldflags '-static'" -o /bins/capo-manager . \ + && CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -ldflags "-extldflags '-static'" -o /bins/ansible-controller ./cmd/ansible-controller + +# ============================================================ +# Runtime image +# ============================================================ +COPY captain /opt/captain + +FROM python:3.10-slim + +ARG TARGETOS +ARG TARGETARCH +ARG TARGETPLATFORM + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + && rm -rf /var/lib/apt/lists/* \ + && curl -fsSLo /usr/local/bin/kubectl "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/${TARGETARCH}/kubectl" \ + && chmod +x /usr/local/bin/kubectl + +RUN curl -LsSf https://astral.sh/uv/install.sh | sh \ + && /root/.local/bin/uv venv /opt/venv \ + && /root/.local/bin/uv pip install --python /opt/venv/bin/python \ + pbr>=1.6 \ + "ansible==2.10.6" \ + netaddr \ + "jinja2>=2.9.6" \ + && rm -rf /root/.local/bin/uv /root/.local/share/uv /root/.cache/uv \ + && find /opt/venv -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true \ + && find /opt/venv -name '*.pyc' -delete + +ENV PATH="/opt/venv/bin:/root/.local/bin:${PATH}" + +COPY --from=build /crds /crds +COPY --from=build /bins /bins +COPY --from=build /opt/captain /opt/captain + +CMD ["/bin/bash"] diff --git a/capi-examples/crd-install-job.yaml b/capi-examples/crd-install-job.yaml new file mode 100644 index 0000000..29de7e8 --- /dev/null +++ b/capi-examples/crd-install-job.yaml @@ -0,0 +1,57 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: install-crds + namespace: capi +spec: + ttlSecondsAfterFinished: 0 + template: + spec: + restartPolicy: OnFailure + serviceAccountName: crd-installer + containers: + - name: installer + image: your-registry/capi-controller:latest + command: + - /bin/bash + - -c + - | + set -e + for f in /crds/kubean/*.yaml; do + kubectl apply -f "$f" + done + for f in /crds/cluster-api/*.yaml; do + kubectl apply -f "$f" + done + for f in /crds/capo/*.yaml; do + kubectl apply -f "$f" + done + echo "All CRDs installed successfully." +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: crd-installer + namespace: capi +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: crd-installer +rules: +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "list", "create", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: crd-installer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: crd-installer +subjects: +- kind: ServiceAccount + name: crd-installer + namespace: capi diff --git a/capi-examples/deployments.yaml b/capi-examples/deployments.yaml new file mode 100644 index 0000000..736d79e --- /dev/null +++ b/capi-examples/deployments.yaml @@ -0,0 +1,200 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: capi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cluster-api-manager + namespace: capi + labels: + app: cluster-api-manager +spec: + replicas: 1 + selector: + matchLabels: + app: cluster-api-manager + template: + metadata: + labels: + app: cluster-api-manager + spec: + serviceAccountName: capi-manager + containers: + - name: manager + image: your-registry/capi-controller:latest + command: ["/bins/cluster-api-manager"] + args: + - --leader-elect + - --metrics-bind-addr=:8080 + - --health-probe-bind-addr=:8081 + ports: + - name: metrics + containerPort: 8080 + - name: health + containerPort: 8081 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + readinessProbe: + httpGet: + path: /readyz + port: 8081 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: capo-manager + namespace: capi + labels: + app: capo-manager +spec: + replicas: 1 + selector: + matchLabels: + app: capo-manager + template: + metadata: + labels: + app: capo-manager + spec: + serviceAccountName: capo-manager + containers: + - name: manager + image: your-registry/capi-controller:latest + command: ["/bins/capo-manager"] + args: + - --leader-elect + - --metrics-bind-addr=:8080 + - --health-probe-bind-addr=:8081 + ports: + - name: metrics + containerPort: 8080 + - name: health + containerPort: 8081 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + readinessProbe: + httpGet: + path: /readyz + port: 8081 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ansible-controller + namespace: capi + labels: + app: ansible-controller +spec: + replicas: 1 + selector: + matchLabels: + app: ansible-controller + template: + metadata: + labels: + app: ansible-controller + spec: + serviceAccountName: capo-manager + containers: + - name: controller + image: your-registry/capi-controller:latest + command: ["/bins/ansible-controller"] + args: + - --leader-elect + - --health-addr=:9440 + ports: + - name: health + containerPort: 9440 + livenessProbe: + httpGet: + path: /healthz + port: 9440 + readinessProbe: + httpGet: + path: /readyz + port: 9440 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kubean-operator + namespace: capi + labels: + app: kubean-operator +spec: + replicas: 1 + selector: + matchLabels: + app: kubean-operator + template: + metadata: + labels: + app: kubean-operator + spec: + serviceAccountName: kubean-operator + containers: + - name: operator + image: your-registry/capi-controller:latest + command: ["/bins/kubean-operator"] + args: + - --leader-elect + - --metrics-bind-addr=:8080 + - --health-probe-bind-addr=:8081 + ports: + - name: metrics + containerPort: 8080 + - name: health + containerPort: 8081 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + readinessProbe: + httpGet: + path: /readyz + port: 8081 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kubean-admission + namespace: capi + labels: + app: kubean-admission +spec: + replicas: 1 + selector: + matchLabels: + app: kubean-admission + template: + metadata: + labels: + app: kubean-admission + spec: + serviceAccountName: kubean-operator + containers: + - name: admission + image: your-registry/capi-controller:latest + command: ["/bins/kubean-admission"] + args: + - --metrics-bind-addr=:8080 + - --health-probe-bind-addr=:8081 + ports: + - name: metrics + containerPort: 8080 + - name: health + containerPort: 8081 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + readinessProbe: + httpGet: + path: /readyz + port: 8081