Initial commit: Turbo Mothership bare metal management cluster
- k0s bootstrap with Cilium and OpenEBS - ArgoCD apps for infra, CAPI, Tinkerbell, and Netris - Ansible playbooks for virtual baremetal lab and Netris switches - CAPI provider manifests for k0smotron and Tinkerbell
This commit is contained in:
113
bootstrap/README.md
Normal file
113
bootstrap/README.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Bootstrap
|
||||
|
||||
Bootstrap chart for cluster initialization. Deploys all required infrastructure components in a single Helm release.
|
||||
|
||||
## Requirements
|
||||
|
||||
- 1-3 nodes
|
||||
- External DNS for ingress access
|
||||
- Internet access
|
||||
|
||||
## Components
|
||||
|
||||
The bootstrap umbrella chart (`charts/bootstrap/`) includes:
|
||||
|
||||
| Component | Description |
|
||||
|-----------|-------------|
|
||||
| Cilium | CNI for networking |
|
||||
| ingress-nginx | Ingress controller |
|
||||
| cert-manager | TLS certificate management |
|
||||
| sealed-secrets | Encrypted secrets for GitOps |
|
||||
| ArgoCD | GitOps continuous delivery |
|
||||
| OpenEBS | Container storage (hostpath) |
|
||||
|
||||
Additional resources created:
|
||||
- ClusterIssuer (Let's Encrypt)
|
||||
- StorageClass (local-storage)
|
||||
|
||||
## Kubernetes
|
||||
|
||||
Install [k0s](https://k0sproject.io/) as the Kubernetes distribution:
|
||||
|
||||
```sh
|
||||
curl -sSf https://get.k0s.sh | sudo sh
|
||||
sudo k0s install controller --enable-worker --no-taints --config ./k0s.yaml
|
||||
sudo k0s start
|
||||
```
|
||||
|
||||
Verify and get kubeconfig:
|
||||
|
||||
```sh
|
||||
sudo k0s status
|
||||
k0s kubeconfig admin create > ~/.kube/config
|
||||
```
|
||||
|
||||
## Bootstrap Installation
|
||||
|
||||
```sh
|
||||
cd charts/bootstrap
|
||||
|
||||
# Download dependencies
|
||||
helm dependency update
|
||||
|
||||
# Review what will be installed
|
||||
helm template bootstrap . --namespace bootstrap | less
|
||||
|
||||
# Install
|
||||
helm upgrade -i bootstrap . --namespace bootstrap --create-namespace
|
||||
```
|
||||
|
||||
## Sealed Secrets
|
||||
|
||||
[Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets) enables GitOps management of secrets using asymmetric encryption.
|
||||
|
||||
### Usage
|
||||
|
||||
```sh
|
||||
# Create a secret (do not commit)
|
||||
kubectl create secret generic my-secret \
|
||||
--from-literal=password=supersecret \
|
||||
--dry-run=client -o yaml > plaintext.yaml
|
||||
|
||||
# Seal it
|
||||
kubeseal < plaintext.yaml > sealed-secret.yaml
|
||||
|
||||
# Delete plaintext
|
||||
rm plaintext.yaml
|
||||
|
||||
# Apply sealed secret
|
||||
kubectl apply -f sealed-secret.yaml
|
||||
```
|
||||
|
||||
## ArgoCD
|
||||
|
||||
Available at https://argo.turbo.weystrom.dev
|
||||
|
||||
Get initial admin password:
|
||||
|
||||
```sh
|
||||
kubectl -n bootstrap get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `charts/bootstrap/values.yaml` to customize components. Each subchart is configured under its own key:
|
||||
|
||||
```yaml
|
||||
cilium:
|
||||
enabled: true
|
||||
|
||||
ingress-nginx:
|
||||
enabled: true
|
||||
controller:
|
||||
service:
|
||||
externalIPs:
|
||||
- 1.2.3.4
|
||||
|
||||
cert-manager:
|
||||
enabled: true
|
||||
|
||||
# ... etc
|
||||
```
|
||||
|
||||
To disable a component, set `enabled: false`.
|
||||
18
bootstrap/charts/turbo-mothership-bootstrap/.helmignore
Normal file
18
bootstrap/charts/turbo-mothership-bootstrap/.helmignore
Normal file
@@ -0,0 +1,18 @@
|
||||
# Patterns to ignore when building packages.
|
||||
.DS_Store
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
15
bootstrap/charts/turbo-mothership-bootstrap/Chart.lock
Normal file
15
bootstrap/charts/turbo-mothership-bootstrap/Chart.lock
Normal file
@@ -0,0 +1,15 @@
|
||||
dependencies:
|
||||
- name: ingress-nginx
|
||||
repository: https://kubernetes.github.io/ingress-nginx
|
||||
version: 4.14.1
|
||||
- name: cert-manager
|
||||
repository: https://charts.jetstack.io
|
||||
version: v1.19.2
|
||||
- name: sealed-secrets
|
||||
repository: https://bitnami-labs.github.io/sealed-secrets
|
||||
version: 2.17.9
|
||||
- name: argo-cd
|
||||
repository: https://argoproj.github.io/argo-helm
|
||||
version: 9.1.6
|
||||
digest: sha256:dae2d89a79210646255cfbd3d045717b9db40aaf0c9e180d64829b1306659cd0
|
||||
generated: "2025-12-15T17:29:55.279201521+01:00"
|
||||
27
bootstrap/charts/turbo-mothership-bootstrap/Chart.yaml
Normal file
27
bootstrap/charts/turbo-mothership-bootstrap/Chart.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: v2
|
||||
name: turbo-mothership-bootstrap
|
||||
description: Umbrella chart for cluster bootstrap components
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "1.0.0"
|
||||
|
||||
dependencies:
|
||||
- name: ingress-nginx
|
||||
version: "4.14.1"
|
||||
repository: https://kubernetes.github.io/ingress-nginx
|
||||
condition: ingress-nginx.enabled
|
||||
|
||||
- name: cert-manager
|
||||
version: "1.19.2"
|
||||
repository: https://charts.jetstack.io
|
||||
condition: cert-manager.enabled
|
||||
|
||||
- name: sealed-secrets
|
||||
version: "2.17.9"
|
||||
repository: https://bitnami-labs.github.io/sealed-secrets
|
||||
condition: sealed-secrets.enabled
|
||||
|
||||
- name: argo-cd
|
||||
version: "9.1.6"
|
||||
repository: https://argoproj.github.io/argo-helm
|
||||
condition: argo-cd.enabled
|
||||
@@ -0,0 +1,19 @@
|
||||
{{- if .Values.clusterIssuer.enabled }}
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: {{ .Values.clusterIssuer.name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,post-upgrade
|
||||
"helm.sh/hook-weight": "10"
|
||||
spec:
|
||||
acme:
|
||||
server: {{ .Values.clusterIssuer.server }}
|
||||
email: {{ .Values.clusterIssuer.email }}
|
||||
privateKeySecretRef:
|
||||
name: {{ .Values.clusterIssuer.name }}
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
ingressClassName: nginx
|
||||
{{- end }}
|
||||
@@ -0,0 +1,41 @@
|
||||
{{- if index .Values "ingress-nginx" "enabled" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ index .Values "ingress-nginx" "namespaceOverride" | default "ingress-nginx" }}
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
annotations:
|
||||
meta.helm.sh/release-name: {{ .Release.Name }}
|
||||
meta.helm.sh/release-namespace: {{ .Release.Namespace }}
|
||||
"helm.sh/resource-policy": keep
|
||||
{{- end }}
|
||||
|
||||
{{- if index .Values "cert-manager" "enabled" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ index .Values "cert-manager" "namespace" | default "cert-manager" }}
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
annotations:
|
||||
meta.helm.sh/release-name: {{ .Release.Name }}
|
||||
meta.helm.sh/release-namespace: {{ .Release.Namespace }}
|
||||
"helm.sh/resource-policy": keep
|
||||
{{- end }}
|
||||
|
||||
{{- if index .Values "argo-cd" "enabled" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ index .Values "argo-cd" "namespaceOverride" | default "argocd" }}
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
annotations:
|
||||
meta.helm.sh/release-name: {{ .Release.Name }}
|
||||
meta.helm.sh/release-namespace: {{ .Release.Namespace }}
|
||||
"helm.sh/resource-policy": keep
|
||||
{{- end }}
|
||||
87
bootstrap/charts/turbo-mothership-bootstrap/values.yaml
Normal file
87
bootstrap/charts/turbo-mothership-bootstrap/values.yaml
Normal file
@@ -0,0 +1,87 @@
|
||||
# Bootstrap umbrella chart values
|
||||
# Each subchart is configured under its own key
|
||||
# NOTE: Cilium CNI is installed via k0s config (k0s.yaml)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Ingress NGINX (ingress-nginx)
|
||||
# ------------------------------------------------------------------------------
|
||||
ingress-nginx:
|
||||
enabled: true
|
||||
fullnameOverride: turbo-ingress
|
||||
namespaceOverride: ingress-nginx
|
||||
controller:
|
||||
admissionWebhooks:
|
||||
enabled: false
|
||||
service:
|
||||
externalIPs:
|
||||
- 65.109.94.180
|
||||
type: ClusterIP
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Cert Manager (cert-manager)
|
||||
# ------------------------------------------------------------------------------
|
||||
cert-manager:
|
||||
enabled: true
|
||||
fullnameOverride: turbo-certmgr
|
||||
namespace: cert-manager
|
||||
crds:
|
||||
enabled: true
|
||||
ingressShim:
|
||||
defaultIssuerName: letsencrypt-prod
|
||||
defaultIssuerKind: ClusterIssuer
|
||||
defaultIssuerGroup: cert-manager.io
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Sealed Secrets (kube-system)
|
||||
# ------------------------------------------------------------------------------
|
||||
sealed-secrets:
|
||||
enabled: true
|
||||
fullnameOverride: turbo-sealedsecrets
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Argo CD (argocd)
|
||||
# ------------------------------------------------------------------------------
|
||||
argo-cd:
|
||||
enabled: true
|
||||
fullnameOverride: turbo-argocd
|
||||
global:
|
||||
domain: argo.turbo.weystrom.dev
|
||||
namespaceOverride: argocd
|
||||
configs:
|
||||
params:
|
||||
server.insecure: true
|
||||
cm:
|
||||
admin.enabled: true
|
||||
server:
|
||||
ingress:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
extraTls:
|
||||
- hosts:
|
||||
- argo.turbo.weystrom.dev
|
||||
secretName: argocd-ingress-http
|
||||
ingressGrpc:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
hostname: argo-grpc.turbo.weystrom.dev
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
extraTls:
|
||||
- hosts:
|
||||
- argo-grpc.turbo.weystrom.dev
|
||||
secretName: argocd-ingress-grpc
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Raw manifests configuration
|
||||
# ------------------------------------------------------------------------------
|
||||
# NOTE: OpenEBS is installed via k0s config (k0s.yaml)
|
||||
clusterIssuer:
|
||||
enabled: true
|
||||
name: letsencrypt-prod
|
||||
email: mail@weystrom.dev
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
101
bootstrap/k0s.yaml
Normal file
101
bootstrap/k0s.yaml
Normal file
@@ -0,0 +1,101 @@
|
||||
apiVersion: k0s.k0sproject.io/v1beta1
|
||||
kind: ClusterConfig
|
||||
metadata:
|
||||
name: k0s
|
||||
namespace: kube-system
|
||||
spec:
|
||||
api:
|
||||
address: 65.109.94.180
|
||||
ca:
|
||||
certificatesExpireAfter: 8760h0m0s
|
||||
expiresAfter: 87600h0m0s
|
||||
k0sApiPort: 9443
|
||||
port: 6443
|
||||
sans:
|
||||
- 65.109.94.180
|
||||
- 2a01:4f9:3051:48ca::2
|
||||
controllerManager: {}
|
||||
extensions:
|
||||
helm:
|
||||
concurrencyLevel: 5
|
||||
repositories:
|
||||
- name: cilium
|
||||
url: https://helm.cilium.io/
|
||||
- name: openebs
|
||||
url: https://openebs.github.io/openebs
|
||||
charts:
|
||||
- name: cilium
|
||||
chartname: cilium/cilium
|
||||
version: "1.18.4"
|
||||
namespace: kube-system
|
||||
order: 1
|
||||
values: |
|
||||
cluster:
|
||||
name: local
|
||||
k8sServiceHost: 65.109.94.180
|
||||
k8sServicePort: 6443
|
||||
kubeProxyReplacement: true
|
||||
operator:
|
||||
replicas: 1
|
||||
routingMode: tunnel
|
||||
tunnelProtocol: vxlan
|
||||
- name: openebs
|
||||
chartname: openebs/openebs
|
||||
version: "4.2.0"
|
||||
namespace: openebs
|
||||
order: 2
|
||||
values: |
|
||||
localpv-provisioner:
|
||||
localpv:
|
||||
basePath: /var/openebs/local
|
||||
engines:
|
||||
replicated:
|
||||
mayastor:
|
||||
enabled: false
|
||||
local:
|
||||
zfs:
|
||||
enabled: false
|
||||
rawfile:
|
||||
enabled: false
|
||||
lvm:
|
||||
enabled: false
|
||||
loki:
|
||||
enabled: false
|
||||
minio:
|
||||
enabled: false
|
||||
alloy:
|
||||
enabled: false
|
||||
installConfig:
|
||||
users:
|
||||
etcdUser: etcd
|
||||
kineUser: kube-apiserver
|
||||
konnectivityUser: konnectivity-server
|
||||
kubeAPIserverUser: kube-apiserver
|
||||
kubeSchedulerUser: kube-scheduler
|
||||
network:
|
||||
clusterDomain: cluster.local
|
||||
dualStack:
|
||||
enabled: true
|
||||
IPv6podCIDR: fd00::/108
|
||||
IPv6serviceCIDR: fd01::/108
|
||||
kubeProxy:
|
||||
disabled: true
|
||||
nodeLocalLoadBalancing:
|
||||
enabled: false
|
||||
envoyProxy:
|
||||
apiServerBindPort: 7443
|
||||
konnectivityServerBindPort: 7132
|
||||
type: EnvoyProxy
|
||||
podCIDR: 10.240.0.0/16
|
||||
provider: custom
|
||||
serviceCIDR: 10.99.0.0/12
|
||||
scheduler: {}
|
||||
storage:
|
||||
etcd:
|
||||
ca:
|
||||
certificatesExpireAfter: 8760h0m0s
|
||||
expiresAfter: 87600h0m0s
|
||||
peerAddress: 127.0.0.1
|
||||
type: etcd
|
||||
telemetry:
|
||||
enabled: false
|
||||
Reference in New Issue
Block a user