The procedure has been tested on a ubuntu 22.04LTS 64GB Ram.
1- RKE2 installation
RKE2 config
...
Install multus and calico or CNI
| Code Block |
|---|
| language | yaml |
|---|
| title | /etc/rancher/rke2/config.yaml |
|---|
|
cni:
- multus
- calico |
1- Install metallb (LoadBalancer)
This pass will be possible to expose some address to the external of the cluster.
1- Prepare metallb_config.yaml
copy the following content (by using free IP ranges where your cluster uses)
| Code Block |
|---|
| language | yaml |
|---|
| title | metallb_config.yaml |
|---|
|
...
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
namespace: metallb-system
name: default-pool-10-6
spec:
addresses:
- 10.10.6.240-10.10.6.250 # Adjust to your available range
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
namespace: metallb-system
name: l2
spec:
ipAddressPools:
- default-pool-10-6
nodeSelectors:
- matchLabels:
vlan: vlan-10-6
---
## if you have other network to expose
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
namespace: metallb-system
name: default-pool-109
spec:
addresses:
- 192.168.109.240-192.168.109.250 # Adjust to your available range
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
namespace: metallb-system
name: l2
spec:
ipAddressPools:
- default-pool-109
nodeSelectors:
- matchLabels:
vlan: vlan-109
|
2- Install metallb and configure
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
## metallb
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
kubectl apply -f metallb_config.yaml
|
2 Install local_path storage class
1. 🛠️ Apply the official manifests
Use this command to install the default local-path-provisioner:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
|
This deploys:
A StorageClass named local-path
A local-path-provisioner DaemonSet
The necessary RBAC and helper scripts
...
2. ☑️ Set it as the default (optional)
To make local-path the default StorageClass (so you don’t need to specify it in every PVC):
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' |
You can verify it with:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl get storageclass |
Look for (default) in the local-path row.
3 Install Install cert-manager
Install cert-manager using the official manifests:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.0/cert-manager.yaml |
📄 Create a ClusterIssuer for Let's Encrypt
Create a file named cluster-issuer.yaml:
| Code Block |
|---|
| language | yaml |
|---|
| title | YAML MANIFEST |
|---|
|
...
|
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: andrea.michelotti@infn.it # 📧 Required
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: "nginx" |
Install the Kubernetes Dashboard
Apply the official dashboard manifest:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml |
This will install the dashboard into the kubernetes-dashboard namespace.
...
1. 🌍 Expose the Dashboard with an Ingress
Option for NGINX
Create a file dashboard-ingress.yaml:
| Code Block |
|---|
| language | yaml |
|---|
| title | YAML MANIFEST |
|---|
|
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubernetes-dashboard
namespace: kubernetes-dashboard
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
cert-manager.io/cluster-issuer: letsencrypt-prod
#nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
# Traefik examples:
# traefik.ingress.kubernetes.io/router.entrypoints: websecure
# traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: dashboard.da # 🔁 Change to your domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
tls:
- hosts:
- dashboard.da
secretName: dashboard-cert |
Apply it:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl apply -f dashboard-ingress.yaml |
Check the address exposed and add in the /etc/hosts as dashboard.da
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl get ingress -n kubernetes-dashboard |
🧠 You must configure a DNS entry or /etc/hosts pointing dashboard.da to your ingress controller IP.
...
2. 🔐 Create a ServiceAccount + ClusterRoleBinding
Create an admin user:
| Code Block |
|---|
| language | yaml |
|---|
| title | YAML MANIFEST |
|---|
|
# dashboard-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard |
Apply it:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
...
|
kubectl apply -f dashboard-admin.yaml |
...
3. 🔑 Get the Login Token
More secure option is to make a token that expires.
The token will expire.
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl -n kubernetes-dashboard create token admin-user |
Copy the token and use it to log in at https://dashboard.da
Create a Secret Token (manually)
Create a ServiceAccount
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl create serviceaccount dashboard-sa -n kubernetes-dashboard |
Bind It to the Cluster Role (e.g. cluster-admin)
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl create clusterrolebinding dashboard-sa-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-sa |
Create a file dashboard-token.yaml:
| Code Block |
|---|
| language | yaml |
|---|
| title | YAML MANIFEST |
|---|
|
apiVersion: v1
kind: Secret
metadata:
name: dashboard-sa-token
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: dashboard-sa
type: kubernetes.io/service-account-token |
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl apply -f dashboard-token.yaml |
...
Wait & Retrieve the Token
It may take a few seconds for Kubernetes to populate the token. Then:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
...
kubectl -n kubernetes-dashboard describe secret dashboard-sa-token |
Install Argo CD
Install Argo CD in the argocd namespace:
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml |
Expose Argo CD with an Ingress
🔹 Ingress with NGINX
Create a file argocd-ingress.yaml:
prepare argocd_ingress.yaml
| Code Block |
|---|
| language | yaml |
|---|
| title | argocd_ingress.yaml |
|---|
|
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
cert-manager.io/cluster-issuer: "letsencrypt-prod" # Optional: if using TLS
spec:
rules:
- host: argocd.da # 🔁 Replace with your DNS name
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 443
tls:
- hosts:
- argocd.da
secretName: argocd-tls # Auto-created by cert-manager if using TLS |
Apply it:
| Code Block |
|---|
|
kubectl apply -f argocd-ingress.yaml
|
Retrieve initial password
| Code Block |
|---|
|
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d |
connect to UI (admin and password)
see the address
| Code Block |
|---|
| language | shell |
|---|
| title | Shell Command |
|---|
|
kubectl get ingress -n argocd |
🧠 You must configure a DNS entry or /etc/hosts pointing argocd.da (or whatever) with your ingress controller IP.
Change the password! the inital password wont work for long
Install EPIK8s backend services
...
...