Skip to content

Commit a4e6eca

Browse files
authored
Attach release manifests for clusterctl (#30)
1 parent 0b98cae commit a4e6eca

File tree

12 files changed

+372
-19
lines changed

12 files changed

+372
-19
lines changed

.github/workflows/docker.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ jobs:
4141
with:
4242
context: .
4343
push: true
44-
tags: ${{ env.REGISTRY }}/metal-stack/capms-controller:${{ env.tag }}
44+
tags: ${{ env.REGISTRY }}/metal-stack/cluster-api-metal-stack-controller:${{ env.tag }}

.github/workflows/release-drafter.yaml

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,42 @@ on:
55
push:
66
branches:
77
- main
8+
permissions:
9+
contents: write
810

911
jobs:
1012
build:
1113
runs-on: ubuntu-latest
1214
steps:
13-
- uses: release-drafter/release-drafter@v6
14-
env:
15-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15+
- uses: release-drafter/release-drafter@v6
16+
env:
17+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18+
19+
- name: Checkout
20+
uses: actions/checkout@v2
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Set up Go
25+
uses: actions/setup-go@v5
26+
with:
27+
go-version: "1.21"
28+
29+
- name: install kustomize
30+
run: |
31+
make kustomize
32+
- name: generate release artifacts
33+
env:
34+
IMG_TAG: ${{ github.ref_name }}
35+
RELEASE_DIR: .release
36+
run: |
37+
make release-manifests
38+
39+
- name: Attach release manifests
40+
uses: softprops/action-gh-release@v2
41+
if: startsWith(github.ref, 'refs/tags/')
42+
with:
43+
name: v${{ RESOLVED_VERSION }}
44+
draft: true
45+
fail_on_unmatched_files: true
46+
files: .release/*

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
bin/*
88
test/external-crds
99
Dockerfile.cross
10+
.release
1011

1112
infrastructure-components.yaml
1213
.capms-cluster-kubeconfig.yaml

Makefile

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Image URL to use all building/pushing image targets
2-
IMG ?= capms-controller:latest
2+
IMG_NAME ?= ghcr.io/metal-stack/cluster-api-metal-stack-controller
3+
IMG_TAG ?= latest
4+
IMG ?= ${IMG_NAME}:${IMG_TAG}
35
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
46
ENVTEST_K8S_VERSION = 1.31.0
7+
RELEASE_DIR ?= .release
58

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

4649
.PHONY: release-manifests
47-
release-manifests: $(KUSTOMIZE) ## Builds the manifests to publish with a release
48-
$(KUSTOMIZE) build config/default > infrastructure-components.yaml
49-
# cp metadata.yaml $(RELEASE_DIR)/metadata.yaml
50-
# cp examples/clusterctl-templates/clusterctl-cluster.yaml $(RELEASE_DIR)/cluster-template.yaml
51-
# cp examples/clusterctl-templates/example_variables.rc $(RELEASE_DIR)/example_variables.rc
50+
release-manifests: $(KUSTOMIZE) build-installer ## Builds the manifests to publish with a release
51+
mkdir -p $(RELEASE_DIR)
52+
$(KUSTOMIZE) build config/default > $(RELEASE_DIR)/infrastructure-components.yaml
53+
sed -i 's!image: $(IMG_NAME):latest!image: $(IMG_NAME):$(IMG_TAG)!' $(RELEASE_DIR)/infrastructure-components.yaml
54+
cp metadata.yaml $(RELEASE_DIR)/metadata.yaml
55+
cp config/clusterctl-templates/cluster-template.yaml $(RELEASE_DIR)/cluster-template.yaml
56+
cp config/clusterctl-templates/example_variables.rc $(RELEASE_DIR)/example_variables.rc
5257

5358
##@ Development
5459

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

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

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

159164
##@ Deployment
160165

README.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The Cluster API provider for metal-stack (CAPMS) implements the declarative mana
44

55
> [!CAUTION]
66
> This project is currently under heavy development and is not advised to be used in production any time soon.
7-
> Please use or stack on top of [Gardener](https://docs.metal-stack.io/stable/installation/deployment/#Gardener-with-metal-stack) instead.
7+
> Please use our stack on top of [Gardener](https://docs.metal-stack.io/stable/installation/deployment/#Gardener-with-metal-stack) instead.
88
> User documentation will follow as soon. Until then head to our [CONTRIBUTING.md](/CONTRIBUTING.md)
99
1010
Currently we provide the following custom resources:
@@ -15,3 +15,51 @@ Currently we provide the following custom resources:
1515
> [!note]
1616
> 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).
1717
> While other providers might work, there is no guarantee nor the goal to reach compatibility.
18+
19+
## Getting started
20+
21+
**Prerequisites:**
22+
23+
- a running metal-stack installation
24+
- CRDs for Prometheus
25+
- CRDs for the Firewall Controller Manager
26+
27+
First add the metal-stack infrastructure provider to your `clusterctl.yaml`:
28+
29+
```yaml
30+
# ~/.config/cluster-api/clusterctl.yaml
31+
providers:
32+
- name: "metal-stack"
33+
url: "https://github.com/metal-stack/cluster-api-provider-metal-stack/releases/latest/infrastructure-components.yaml"
34+
type: InfrastructureProvider
35+
```
36+
37+
Now you are able to install the CAPMS into your cluster:
38+
39+
```bash
40+
export METALCTL_API_URL=http://metal.172.17.0.1.nip.io:8080
41+
export METALCTL_API_HMAC=metal-admin
42+
export EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true
43+
44+
clusterctl init --infrastructure metal-stack
45+
```
46+
47+
Now you should be able to create Clusters on top of metal-stack.
48+
For your first cluster it is advised to start with our generated template.
49+
50+
```bash
51+
# to display all env variables that need to be set
52+
clusterctl generate cluster example --kubernetes-version v1.30.6 --infrastructure metal-stack --list-variables
53+
```
54+
55+
> [!CAUTION]
56+
> **Manual steps needed:**
57+
> Due to the early development stage the following manual actions are needed for the cluster to operate.
58+
59+
1. The firewall needs to be created manually.
60+
2. You need to install your CNI of choice. This is required due to CAPI.
61+
3. Control plane and worker nodes need to be patched.
62+
63+
```bash
64+
kubectl patch node <worker-node-name> --patch='{"spec":{"providerID": "metal://<machine-id>"}}'
65+
```

capi-lab/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.DEFAULT_GOAL := up
22

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

66
.PHONY: up
77
up: bake deploy-capi
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
---
2+
apiVersion: cluster.x-k8s.io/v1beta1
3+
kind: Cluster
4+
metadata:
5+
name: ${CLUSTER_NAME}
6+
namespace: ${NAMESPACE}
7+
spec:
8+
clusterNetwork:
9+
pods:
10+
cidrBlocks: ${POD_CIDR:=["10.240.0.0/12"]}
11+
controlPlaneRef:
12+
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
13+
kind: KubeadmControlPlane
14+
name: ${CLUSTER_NAME}-controlplane
15+
namespace: ${NAMESPACE}
16+
infrastructureRef:
17+
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
18+
kind: MetalStackCluster
19+
name: ${CLUSTER_NAME}
20+
namespace: ${NAMESPACE}
21+
---
22+
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
23+
kind: MetalStackCluster
24+
metadata:
25+
name: ${CLUSTER_NAME}
26+
namespace: ${NAMESPACE}
27+
spec:
28+
projectID: ${METAL_PROJECT_ID}
29+
partition: ${METAL_PARTITION}
30+
firewall:
31+
size: ${FIREWALL_MACHINE_SIZE}
32+
image: ${FIREWALL_MACHINE_IMAGE}
33+
networks: ${FIREWALL_NETWORKS:=[internet]}
34+
---
35+
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
36+
kind: MetalStackMachineTemplate
37+
metadata:
38+
name: ${CLUSTER_NAME}-controlplane
39+
namespace: ${NAMESPACE}
40+
spec:
41+
template:
42+
spec:
43+
size: ${CONTROL_PLANE_MACHINE_SIZE}
44+
image: ${CONTROL_PLANE_MACHINE_IMAGE}
45+
---
46+
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
47+
kind: MetalStackMachineTemplate
48+
metadata:
49+
name: ${CLUSTER_NAME}-worker
50+
spec:
51+
template:
52+
spec:
53+
size: ${WORKER_MACHINE_SIZE}
54+
image: ${WORKER_MACHINE_IMAGE}
55+
---
56+
kind: KubeadmControlPlane
57+
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
58+
metadata:
59+
name: ${CLUSTER_NAME}-controlplane
60+
spec:
61+
replicas: ${CONTROL_PLANE_MACHINE_COUNT}
62+
version: ${KUBERNETES_VERSION}
63+
machineTemplate:
64+
nodeDrainTimeout: 10m
65+
infrastructureRef:
66+
kind: MetalStackMachineTemplate
67+
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
68+
name: ${CLUSTER_NAME}-controlplane
69+
kubeadmConfigSpec:
70+
format: ignition
71+
clusterConfiguration:
72+
controlPlaneEndpoint: ${CONTROL_PLANE_ENDPOINT}
73+
initConfiguration:
74+
localAPIEndpoint:
75+
bindPort: ${CONTROL_PLANE_PORT:=443}
76+
nodeRegistration: {}
77+
joinConfiguration:
78+
controlPlane: {}
79+
nodeRegistration: {}
80+
ignition:
81+
containerLinuxConfig:
82+
additionalConfig: |
83+
systemd:
84+
units:
85+
- name: cluster-api-init.service
86+
enable: true
87+
contents: |-
88+
[Unit]
89+
Description=Prepares the node for bootstrapping with cluster-api kubeadm
90+
Before=kubeadm.service
91+
After=network-online.target
92+
Wants=network-online.target
93+
[Service]
94+
Type=oneshot
95+
Restart=on-failure
96+
RestartSec=5
97+
StartLimitBurst=0
98+
EnvironmentFile=/etc/environment
99+
ExecStart=/var/lib/cluster-api-init/bootstrap.sh
100+
[Install]
101+
WantedBy=multi-user.target
102+
files:
103+
- path: /var/lib/cluster-api-init/bootstrap.sh
104+
owner: "root:root"
105+
permissions: "0744"
106+
content: ${BOOTSTRAP_SCRIPT:="
107+
#!/usr/bin/env bash
108+
set -eo pipefail
109+
set +x
110+
111+
apt update
112+
apt install conntrack
113+
114+
CNI_PLUGINS_VERSION="v1.3.0"
115+
DEST="/opt/cni/bin"
116+
mkdir -p "$DEST"
117+
curl -L "https://github.com/containernetworking/plugins/releases/download/$CNI_PLUGINS_VERSION/cni-plugins-linux-amd64-$CNI_PLUGINS_VERSION.tgz" | tar -C "$DEST" -xz
118+
119+
RELEASE="${KUBERNETES_VERSION}"
120+
cd /usr/local/bin
121+
curl -L --remote-name-all https://dl.k8s.io/release/${RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
122+
chmod +x {kubeadm,kubelet,kubectl}
123+
124+
RELEASE_VERSION="v0.16.2"
125+
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
126+
mkdir -p /usr/lib/systemd/system/kubelet.service.d
127+
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
128+
129+
systemctl enable kubelet.service
130+
"}
131+
- path: /etc/containerd/config.toml
132+
owner: "root:root"
133+
permissions: "0644"
134+
content: |
135+
disabled_plugins = []
136+
---
137+
apiVersion: cluster.x-k8s.io/v1beta1
138+
kind: MachineDeployment
139+
metadata:
140+
name: ${CLUSTER_NAME}-md-0
141+
labels:
142+
cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME}
143+
nodepool: nodepool-0
144+
spec:
145+
clusterName: ${CLUSTER_NAME}
146+
replicas: ${WORKER_MACHINE_COUNT}
147+
selector:
148+
matchLabels:
149+
cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME}
150+
nodepool: nodepool-0
151+
template:
152+
metadata:
153+
labels:
154+
cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME}
155+
nodepool: nodepool-0
156+
spec:
157+
nodeDrainTimeout: 120s
158+
clusterName: ${CLUSTER_NAME}
159+
version: "${KUBERNETES_VERSION}"
160+
bootstrap:
161+
configRef:
162+
name: ${CLUSTER_NAME}-md-0
163+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
164+
kind: KubeadmConfigTemplate
165+
infrastructureRef:
166+
name: ${CLUSTER_NAME}-worker
167+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
168+
kind: MetalStackMachineTemplate
169+
---
170+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
171+
kind: KubeadmConfigTemplate
172+
metadata:
173+
name: ${CLUSTER_NAME}-md-0
174+
spec:
175+
template:
176+
spec:
177+
format: ignition
178+
clusterConfiguration:
179+
controlPlaneEndpoint: ${CONTROL_PLANE_ENDPOINT}
180+
joinConfiguration:
181+
nodeRegistration: {}
182+
ignition:
183+
containerLinuxConfig:
184+
additionalConfig: |
185+
systemd:
186+
units:
187+
- name: cluster-api-init.service
188+
enable: true
189+
contents: |-
190+
[Unit]
191+
Description=Prepares the node for bootstrapping with cluster-api kubeadm
192+
Before=kubeadm.service
193+
After=network-online.target
194+
Wants=network-online.target
195+
[Service]
196+
Type=oneshot
197+
Restart=on-failure
198+
RestartSec=5
199+
StartLimitBurst=0
200+
EnvironmentFile=/etc/environment
201+
ExecStart=/var/lib/cluster-api-init/bootstrap.sh
202+
[Install]
203+
WantedBy=multi-user.target
204+
files:
205+
- path: /var/lib/cluster-api-init/bootstrap.sh
206+
owner: "root:root"
207+
permissions: "0744"
208+
content: ${BOOTSTRAP_SCRIPT}
209+
- path: /etc/containerd/config.toml
210+
owner: "root:root"
211+
permissions: "0644"
212+
content: |
213+
disabled_plugins = []

0 commit comments

Comments
 (0)