Skip to content

Commit

Permalink
Attach release manifests for clusterctl (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
vknabel authored Jan 21, 2025
1 parent 0b98cae commit a4e6eca
Show file tree
Hide file tree
Showing 12 changed files with 372 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ jobs:
with:
context: .
push: true
tags: ${{ env.REGISTRY }}/metal-stack/capms-controller:${{ env.tag }}
tags: ${{ env.REGISTRY }}/metal-stack/cluster-api-metal-stack-controller:${{ env.tag }}
37 changes: 34 additions & 3 deletions .github/workflows/release-drafter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,42 @@ on:
push:
branches:
- main
permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.21"

- name: install kustomize
run: |
make kustomize
- name: generate release artifacts
env:
IMG_TAG: ${{ github.ref_name }}
RELEASE_DIR: .release
run: |
make release-manifests
- name: Attach release manifests
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
name: v${{ RESOLVED_VERSION }}
draft: true
fail_on_unmatched_files: true
files: .release/*
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
bin/*
test/external-crds
Dockerfile.cross
.release

infrastructure-components.yaml
.capms-cluster-kubeconfig.yaml
Expand Down
25 changes: 15 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Image URL to use all building/pushing image targets
IMG ?= capms-controller:latest
IMG_NAME ?= ghcr.io/metal-stack/cluster-api-metal-stack-controller
IMG_TAG ?= latest
IMG ?= ${IMG_NAME}:${IMG_TAG}
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.31.0
RELEASE_DIR ?= .release

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
Expand Down Expand Up @@ -44,18 +47,20 @@ help: ## Display this help.
##@ Releases

.PHONY: release-manifests
release-manifests: $(KUSTOMIZE) ## Builds the manifests to publish with a release
$(KUSTOMIZE) build config/default > infrastructure-components.yaml
# cp metadata.yaml $(RELEASE_DIR)/metadata.yaml
# cp examples/clusterctl-templates/clusterctl-cluster.yaml $(RELEASE_DIR)/cluster-template.yaml
# cp examples/clusterctl-templates/example_variables.rc $(RELEASE_DIR)/example_variables.rc
release-manifests: $(KUSTOMIZE) build-installer ## Builds the manifests to publish with a release
mkdir -p $(RELEASE_DIR)
$(KUSTOMIZE) build config/default > $(RELEASE_DIR)/infrastructure-components.yaml
sed -i 's!image: $(IMG_NAME):latest!image: $(IMG_NAME):$(IMG_TAG)!' $(RELEASE_DIR)/infrastructure-components.yaml
cp metadata.yaml $(RELEASE_DIR)/metadata.yaml
cp config/clusterctl-templates/cluster-template.yaml $(RELEASE_DIR)/cluster-template.yaml
cp config/clusterctl-templates/example_variables.rc $(RELEASE_DIR)/example_variables.rc

##@ Development

.PHONY: push-to-capi-lab
push-to-capi-lab: generate manifests build install deploy
docker build -t $(IMG) -f Dockerfile.dev .
kind --name metal-control-plane load docker-image capms-controller:latest
kind --name metal-control-plane load docker-image $(IMG)
kubectl --kubeconfig=$(KUBECONFIG) patch deployments.apps -n capms-system capms-controller-manager --patch='{"spec":{"template":{"spec":{"containers":[{"name": "manager","imagePullPolicy":"IfNotPresent","image":"$(IMG)"}]}}}}'
kubectl --kubeconfig=$(KUBECONFIG) delete pod -n capms-system -l control-plane=controller-manager

Expand Down Expand Up @@ -152,9 +157,9 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform

.PHONY: build-installer
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
mkdir -p dist
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default > dist/install.yaml
mkdir -p $(RELEASE_DIR)
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG_NAME}:${IMG_TAG}
$(KUSTOMIZE) build config/default > $(RELEASE_DIR)/install.yaml

##@ Deployment

Expand Down
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The Cluster API provider for metal-stack (CAPMS) implements the declarative mana

> [!CAUTION]
> This project is currently under heavy development and is not advised to be used in production any time soon.
> Please use or stack on top of [Gardener](https://docs.metal-stack.io/stable/installation/deployment/#Gardener-with-metal-stack) instead.
> Please use our stack on top of [Gardener](https://docs.metal-stack.io/stable/installation/deployment/#Gardener-with-metal-stack) instead.
> User documentation will follow as soon. Until then head to our [CONTRIBUTING.md](/CONTRIBUTING.md)
Currently we provide the following custom resources:
Expand All @@ -15,3 +15,51 @@ Currently we provide the following custom resources:
> [!note]
> Currently our infrastructure provider is only tested against the [Cluster API bootstrap provider Kubeadm (CABPK)](https://cluster-api.sigs.k8s.io/tasks/bootstrap/kubeadm-bootstrap/index.html?highlight=kubeadm#cluster-api-bootstrap-provider-kubeadm).
> While other providers might work, there is no guarantee nor the goal to reach compatibility.
## Getting started

**Prerequisites:**

- a running metal-stack installation
- CRDs for Prometheus
- CRDs for the Firewall Controller Manager

First add the metal-stack infrastructure provider to your `clusterctl.yaml`:

```yaml
# ~/.config/cluster-api/clusterctl.yaml
providers:
- name: "metal-stack"
url: "https://github.com/metal-stack/cluster-api-provider-metal-stack/releases/latest/infrastructure-components.yaml"
type: InfrastructureProvider
```
Now you are able to install the CAPMS into your cluster:
```bash
export METALCTL_API_URL=http://metal.172.17.0.1.nip.io:8080
export METALCTL_API_HMAC=metal-admin
export EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true

clusterctl init --infrastructure metal-stack
```

Now you should be able to create Clusters on top of metal-stack.
For your first cluster it is advised to start with our generated template.

```bash
# to display all env variables that need to be set
clusterctl generate cluster example --kubernetes-version v1.30.6 --infrastructure metal-stack --list-variables
```

> [!CAUTION]
> **Manual steps needed:**
> Due to the early development stage the following manual actions are needed for the cluster to operate.
1. The firewall needs to be created manually.
2. You need to install your CNI of choice. This is required due to CAPI.
3. Control plane and worker nodes need to be patched.

```bash
kubectl patch node <worker-node-name> --patch='{"spec":{"providerID": "metal://<machine-id>"}}'
```
2 changes: 1 addition & 1 deletion capi-lab/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.DEFAULT_GOAL := up

KUBECONFIG := $(shell pwd)/mini-lab/.kubeconfig
IMG ?= capms-controller:latest
IMG ?= ghcr.io/metal-stack/cluster-api-metal-stack-controller:latest

.PHONY: up
up: bake deploy-capi
Expand Down
213 changes: 213 additions & 0 deletions config/clusterctl-templates/cluster-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: ${CLUSTER_NAME}
namespace: ${NAMESPACE}
spec:
clusterNetwork:
pods:
cidrBlocks: ${POD_CIDR:=["10.240.0.0/12"]}
controlPlaneRef:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
name: ${CLUSTER_NAME}-controlplane
namespace: ${NAMESPACE}
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: MetalStackCluster
name: ${CLUSTER_NAME}
namespace: ${NAMESPACE}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: MetalStackCluster
metadata:
name: ${CLUSTER_NAME}
namespace: ${NAMESPACE}
spec:
projectID: ${METAL_PROJECT_ID}
partition: ${METAL_PARTITION}
firewall:
size: ${FIREWALL_MACHINE_SIZE}
image: ${FIREWALL_MACHINE_IMAGE}
networks: ${FIREWALL_NETWORKS:=[internet]}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: MetalStackMachineTemplate
metadata:
name: ${CLUSTER_NAME}-controlplane
namespace: ${NAMESPACE}
spec:
template:
spec:
size: ${CONTROL_PLANE_MACHINE_SIZE}
image: ${CONTROL_PLANE_MACHINE_IMAGE}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: MetalStackMachineTemplate
metadata:
name: ${CLUSTER_NAME}-worker
spec:
template:
spec:
size: ${WORKER_MACHINE_SIZE}
image: ${WORKER_MACHINE_IMAGE}
---
kind: KubeadmControlPlane
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
metadata:
name: ${CLUSTER_NAME}-controlplane
spec:
replicas: ${CONTROL_PLANE_MACHINE_COUNT}
version: ${KUBERNETES_VERSION}
machineTemplate:
nodeDrainTimeout: 10m
infrastructureRef:
kind: MetalStackMachineTemplate
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
name: ${CLUSTER_NAME}-controlplane
kubeadmConfigSpec:
format: ignition
clusterConfiguration:
controlPlaneEndpoint: ${CONTROL_PLANE_ENDPOINT}
initConfiguration:
localAPIEndpoint:
bindPort: ${CONTROL_PLANE_PORT:=443}
nodeRegistration: {}
joinConfiguration:
controlPlane: {}
nodeRegistration: {}
ignition:
containerLinuxConfig:
additionalConfig: |
systemd:
units:
- name: cluster-api-init.service
enable: true
contents: |-
[Unit]
Description=Prepares the node for bootstrapping with cluster-api kubeadm
Before=kubeadm.service
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
Restart=on-failure
RestartSec=5
StartLimitBurst=0
EnvironmentFile=/etc/environment
ExecStart=/var/lib/cluster-api-init/bootstrap.sh
[Install]
WantedBy=multi-user.target
files:
- path: /var/lib/cluster-api-init/bootstrap.sh
owner: "root:root"
permissions: "0744"
content: ${BOOTSTRAP_SCRIPT:="
#!/usr/bin/env bash
set -eo pipefail
set +x

apt update
apt install conntrack

CNI_PLUGINS_VERSION="v1.3.0"
DEST="/opt/cni/bin"
mkdir -p "$DEST"
curl -L "https://github.com/containernetworking/plugins/releases/download/$CNI_PLUGINS_VERSION/cni-plugins-linux-amd64-$CNI_PLUGINS_VERSION.tgz" | tar -C "$DEST" -xz

RELEASE="${KUBERNETES_VERSION}"
cd /usr/local/bin
curl -L --remote-name-all https://dl.k8s.io/release/${RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
chmod +x {kubeadm,kubelet,kubectl}

RELEASE_VERSION="v0.16.2"
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/$RELEASE_VERSION/cmd/krel/templates/latest/kubelet/kubelet.service" | sed "s:/usr/bin:/usr/local/bin:g" | tee /usr/lib/systemd/system/kubelet.service
mkdir -p /usr/lib/systemd/system/kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/$RELEASE_VERSION/cmd/krel/templates/latest/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:/usr/local/bin:g" | tee /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

systemctl enable kubelet.service
"}
- path: /etc/containerd/config.toml
owner: "root:root"
permissions: "0644"
content: |
disabled_plugins = []
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
name: ${CLUSTER_NAME}-md-0
labels:
cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME}
nodepool: nodepool-0
spec:
clusterName: ${CLUSTER_NAME}
replicas: ${WORKER_MACHINE_COUNT}
selector:
matchLabels:
cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME}
nodepool: nodepool-0
template:
metadata:
labels:
cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME}
nodepool: nodepool-0
spec:
nodeDrainTimeout: 120s
clusterName: ${CLUSTER_NAME}
version: "${KUBERNETES_VERSION}"
bootstrap:
configRef:
name: ${CLUSTER_NAME}-md-0
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
infrastructureRef:
name: ${CLUSTER_NAME}-worker
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: MetalStackMachineTemplate
---
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
metadata:
name: ${CLUSTER_NAME}-md-0
spec:
template:
spec:
format: ignition
clusterConfiguration:
controlPlaneEndpoint: ${CONTROL_PLANE_ENDPOINT}
joinConfiguration:
nodeRegistration: {}
ignition:
containerLinuxConfig:
additionalConfig: |
systemd:
units:
- name: cluster-api-init.service
enable: true
contents: |-
[Unit]
Description=Prepares the node for bootstrapping with cluster-api kubeadm
Before=kubeadm.service
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
Restart=on-failure
RestartSec=5
StartLimitBurst=0
EnvironmentFile=/etc/environment
ExecStart=/var/lib/cluster-api-init/bootstrap.sh
[Install]
WantedBy=multi-user.target
files:
- path: /var/lib/cluster-api-init/bootstrap.sh
owner: "root:root"
permissions: "0744"
content: ${BOOTSTRAP_SCRIPT}
- path: /etc/containerd/config.toml
owner: "root:root"
permissions: "0644"
content: |
disabled_plugins = []
Loading

0 comments on commit a4e6eca

Please sign in to comment.