first commit
This commit is contained in:
30
Clusterkey.txt
Normal file
30
Clusterkey.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
Your Kubernetes control-plane has initialized successfully!
|
||||||
|
|
||||||
|
To start using your cluster, you need to run the following as a regular user:
|
||||||
|
|
||||||
|
mkdir -p $HOME/.kube
|
||||||
|
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
||||||
|
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||||
|
|
||||||
|
Alternatively, if you are the root user, you can run:
|
||||||
|
|
||||||
|
export KUBECONFIG=/etc/kubernetes/admin.conf
|
||||||
|
|
||||||
|
You should now deploy a pod network to the cluster.
|
||||||
|
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
|
||||||
|
https://kubernetes.io/docs/concepts/cluster-administration/addons/
|
||||||
|
|
||||||
|
You can now join any number of control-plane nodes running the following command on each as root:
|
||||||
|
|
||||||
|
kubeadm join 192.168.0.20:6443 --token iksja1.azpmfyakfg3j8q98 \
|
||||||
|
--discovery-token-ca-cert-hash sha256:d41f0edb90c66c0555bdf4feca55f1e69019764be0fcd649a254e99ff124568f \
|
||||||
|
--control-plane --certificate-key 06034ca8efb33004a3ee5eedbe887488db9819ede85394e8fb173361b16d4022
|
||||||
|
|
||||||
|
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
|
||||||
|
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
|
||||||
|
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
|
||||||
|
|
||||||
|
Then you can join any number of worker nodes by running the following on each as root:
|
||||||
|
|
||||||
|
kubeadm join 192.168.0.20:6443 --token iksja1.azpmfyakfg3j8q98 \
|
||||||
|
--discovery-token-ca-cert-hash sha256:d41f0edb90c66c0555bdf4feca55f1e69019764be0fcd649a254e99ff124568f
|
||||||
206
cephrook.md
Normal file
206
cephrook.md
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
# Despliegue de Rook-Ceph en clúster K3s (SUSE) con discos locales (Bluestore)
|
||||||
|
|
||||||
|
Esta guía describe cómo desplegar un clúster Rook-Ceph sobre K3s en servidores SUSE con **discos locales** estándar (sin iSCSI). Se adapta a la arquitectura de 4 servidores: `srvfkvm1`, `srvfkvm2`, `srvfkvm3`, `srvfkvm4`, cada uno con 6 discos de \~900GB.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Requisitos previos
|
||||||
|
|
||||||
|
* 4 nodos K3s funcionando: `SRVFKVM01`, `SRVFKVM02`, `SRVFKVM03`, `SRVFKVM04`
|
||||||
|
* Cada nodo con 6 discos locales dedicados para Ceph (`/dev/sdj` a `/dev/sdo` en cada servidor)
|
||||||
|
* K3s y `kubectl` funcionando y configurado
|
||||||
|
* Acceso completo a Internet desde todos los nodos
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Preparar los nodos SUSE (sólo discos locales)
|
||||||
|
|
||||||
|
No es necesario configurar iSCSI ni multipath. **Asegúrate de que los discos están vacíos y sin particionar,** o bien elimina las particiones creadas (Ceph las sobreescribirá).
|
||||||
|
|
||||||
|
Verifica los discos en cada nodo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lsblk | grep sd[j-o]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Crear namespace y CRDs de Rook-Ceph
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl create namespace rook-ceph
|
||||||
|
|
||||||
|
# Clona el repositorio oficial de Rook
|
||||||
|
git clone https://github.com/rook/rook.git
|
||||||
|
cd rook/deploy/examples
|
||||||
|
|
||||||
|
# Aplica CRDs y recursos comunes
|
||||||
|
kubectl apply -f crds.yaml
|
||||||
|
kubectl apply -f common.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Desplegar el operador Rook-Ceph
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f operator.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Crear el clúster Ceph con discos locales
|
||||||
|
|
||||||
|
Crea un archivo `ceph-cluster.yaml` con el siguiente contenido (ajusta nombres/discos según corresponda):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: ceph.rook.io/v1
|
||||||
|
kind: CephCluster
|
||||||
|
metadata:
|
||||||
|
name: rook-ceph
|
||||||
|
namespace: rook-ceph
|
||||||
|
spec:
|
||||||
|
cephVersion:
|
||||||
|
image: quay.io/ceph/ceph:v18
|
||||||
|
dataDirHostPath: /var/lib/rook
|
||||||
|
mon:
|
||||||
|
count: 3
|
||||||
|
allowMultiplePerNode: false
|
||||||
|
dashboard:
|
||||||
|
enabled: true
|
||||||
|
storage:
|
||||||
|
useAllNodes: false
|
||||||
|
useAllDevices: false
|
||||||
|
nodes:
|
||||||
|
- name: SRVFKVM01
|
||||||
|
devices:
|
||||||
|
- name: /dev/sdj
|
||||||
|
- name: /dev/sdk
|
||||||
|
- name: /dev/sdl
|
||||||
|
- name: /dev/sdm
|
||||||
|
- name: /dev/sdn
|
||||||
|
- name: /dev/sdo
|
||||||
|
- name: SRVFKVM02
|
||||||
|
devices:
|
||||||
|
- name: /dev/sdj
|
||||||
|
- name: /dev/sdk
|
||||||
|
- name: /dev/sdl
|
||||||
|
- name: /dev/sdm
|
||||||
|
- name: /dev/sdn
|
||||||
|
- name: /dev/sdo
|
||||||
|
- name: SRVFKVM03
|
||||||
|
devices:
|
||||||
|
- name: /dev/sdj
|
||||||
|
- name: /dev/sdk
|
||||||
|
- name: /dev/sdl
|
||||||
|
- name: /dev/sdm
|
||||||
|
- name: /dev/sdn
|
||||||
|
- name: /dev/sdo
|
||||||
|
- name: SRVFKVM04
|
||||||
|
devices:
|
||||||
|
- name: /dev/sdj
|
||||||
|
- name: /dev/sdk
|
||||||
|
- name: /dev/sdl
|
||||||
|
- name: /dev/sdm
|
||||||
|
- name: /dev/sdn
|
||||||
|
- name: /dev/sdo
|
||||||
|
```
|
||||||
|
|
||||||
|
> \*\*Asegúrate de que los nombres de los nodos (`name:`) coinciden con el valor mostrado por `kubectl get nodes`.
|
||||||
|
|
||||||
|
Aplica el manifiesto:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f ceph-cluster.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Verifica el despliegue de Ceph
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl -n rook-ceph get pods
|
||||||
|
```
|
||||||
|
|
||||||
|
* Espera a que los pods estén en estado `Running`.
|
||||||
|
|
||||||
|
Para comprobar el estado de Ceph:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Primero espera a que el pod rook-ceph-tools esté disponible
|
||||||
|
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph status
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Crear CephBlockPool y StorageClass (replica:2)
|
||||||
|
|
||||||
|
**ceph-blockpool.yaml:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: ceph.rook.io/v1
|
||||||
|
kind: CephBlockPool
|
||||||
|
metadata:
|
||||||
|
name: replicado-2x
|
||||||
|
namespace: rook-ceph
|
||||||
|
spec:
|
||||||
|
failureDomain: host
|
||||||
|
replicated:
|
||||||
|
size: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
**ceph-storageclass.yaml:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: ceph-rbd-replica2
|
||||||
|
provisioner: rook-ceph.rbd.csi.ceph.com
|
||||||
|
parameters:
|
||||||
|
clusterID: rook-ceph
|
||||||
|
pool: replicado-2x
|
||||||
|
imageFormat: "2"
|
||||||
|
imageFeatures: layering
|
||||||
|
csi.storage.k8s.io/fstype: ext4
|
||||||
|
reclaimPolicy: Delete
|
||||||
|
allowVolumeExpansion: true
|
||||||
|
mountOptions:
|
||||||
|
- discard
|
||||||
|
```
|
||||||
|
|
||||||
|
Aplica ambos:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f ceph-blockpool.yaml
|
||||||
|
kubectl apply -f ceph-storageclass.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Accede al Ceph Dashboard
|
||||||
|
|
||||||
|
Obtén el puerto del dashboard:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl -n rook-ceph get svc | grep dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
Obtén la contraseña:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{.data.password}" | base64 -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Accede en tu navegador a:
|
||||||
|
|
||||||
|
```
|
||||||
|
https://<IP_nodo>:<NodePort>
|
||||||
|
```
|
||||||
|
|
||||||
|
Usuario: `admin`
|
||||||
|
Contraseña: (la anterior)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Clúster Rook-Ceph listo para producción con discos locales y réplica cruzada en 4 nodos.
|
||||||
14
cert-manager/clusterissuer-prod.yaml
Normal file
14
cert-manager/clusterissuer-prod.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
email: xavor@hotmail.es
|
||||||
|
server: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
solvers:
|
||||||
|
- http01:
|
||||||
|
ingress:
|
||||||
|
ingressClassName: traefik
|
||||||
14
cert-manager/clusterissuer-staging.yaml
Normal file
14
cert-manager/clusterissuer-staging.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-staging
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
email: xavor@hotmail.es
|
||||||
|
server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-staging
|
||||||
|
solvers:
|
||||||
|
- http01:
|
||||||
|
ingress:
|
||||||
|
ingressClassName: traefik
|
||||||
6
cert-manager/kustomization.yaml
Normal file
6
cert-manager/kustomization.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace: cert-manager
|
||||||
|
resources:
|
||||||
|
- clusterissuer-prod.yaml
|
||||||
|
- clusterissuer-staging.yaml
|
||||||
|
|
||||||
|
|
||||||
4
cert-manager/namespace.yaml
Normal file
4
cert-manager/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: cert-manager
|
||||||
15
cert-manager/readme.md
Normal file
15
cert-manager/readme.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Cert Manager para Kubernetes
|
||||||
|
|
||||||
|
Este repositorio contiene los manifiestos necesarios para desplegar [cert-manager](https://cert-manager.io), una herramienta que automatiza la gestión y renovación de certificados TLS en Kubernetes.
|
||||||
|
|
||||||
|
Cert-manager se encarga de emitir y renovar automáticamente certificados mediante ACME (por ejemplo, Let's Encrypt), y es compatible con `Ingress` para habilitar TLS en tus servicios expuestos.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Despliegue
|
||||||
|
|
||||||
|
kubectl apply -f namespace.yaml
|
||||||
|
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
|
||||||
|
kubectl apply -f clusterissuer-staging.yaml
|
||||||
|
kubectl apply -f clusterissuer-prod.yaml
|
||||||
|
|
||||||
72
comprobaciones.md
Normal file
72
comprobaciones.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# **Comprobaciones y diagnóstico habitual**
|
||||||
|
|
||||||
|
### Estado de pods y despliegues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get pods -A # Todos los pods de todos los namespaces
|
||||||
|
kubectl get pods -n traefik # Sólo los pods de Traefik
|
||||||
|
kubectl get pods -n cert-manager # Sólo cert-manager
|
||||||
|
kubectl get deployments -A # Todos los deployments
|
||||||
|
```
|
||||||
|
|
||||||
|
*Todos los pods deben estar en estado `Running` o `Completed`. Si alguno está en `CrashLoopBackOff` o `Error`, inspecciona con:*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl describe pod <nombre-pod> -n <namespace>
|
||||||
|
kubectl logs <nombre-pod> -n <namespace>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Servicios, IPs y estado MetalLB
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get svc -A # Todos los servicios, revisa columna EXTERNAL-IP
|
||||||
|
kubectl get svc -n traefik # Servicio LoadBalancer de Traefik debe tener IP de MetalLB
|
||||||
|
```
|
||||||
|
|
||||||
|
### Certificados, secrets y recursos cert-manager
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get secrets -n traefik # Verifica el Secret TLS (ej: wildcard-cert)
|
||||||
|
kubectl describe secret wildcard-cert -n traefik
|
||||||
|
kubectl get certificate -A # (cert-manager) lista los recursos Certificate gestionados
|
||||||
|
kubectl describe certificate <name> -n <ns> # Ver detalle y posibles errores
|
||||||
|
kubectl get clusterissuer,issuer -A # Ver emisores de cert-manager (staging, prod, etc.)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ingress, dominios y rutas
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get ingress -A
|
||||||
|
kubectl describe ingress <name> -n <ns>
|
||||||
|
```
|
||||||
|
|
||||||
|
*Revisa que los hosts, paths y el campo `secretName` están correctos.*
|
||||||
|
|
||||||
|
### Comprobar acceso SSL/TLS desde fuera
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl s_client -connect <IP_MetalLB>:443 -servername app1.miempresa.com
|
||||||
|
```
|
||||||
|
|
||||||
|
*Verifica el certificado servido y el SNI.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## g) **Comprobaciones útiles entre pasos**
|
||||||
|
|
||||||
|
* Tras instalar Traefik y MetalLB:
|
||||||
|
Comprueba que el servicio Traefik tiene una IP del pool y responde en el puerto 80/443.
|
||||||
|
|
||||||
|
* Tras instalar cert-manager y crear issuers:
|
||||||
|
Haz `kubectl get pods -n cert-manager` y revisa los logs si algún pod falla.
|
||||||
|
|
||||||
|
* Tras crear un Secret TLS:
|
||||||
|
Haz `kubectl describe secret <nombre> -n <namespace>` y asegúrate de que el tipo es `kubernetes.io/tls`.
|
||||||
|
|
||||||
|
* Tras crear Ingress:
|
||||||
|
Comprueba con `kubectl get ingress -A` y revisa que los hosts y secrets estén bien referenciados.
|
||||||
|
|
||||||
|
* Si accedes por navegador y hay error SSL:
|
||||||
|
Usa `openssl s_client` para ver qué certificado se está presentando realmente.
|
||||||
|
|
||||||
|
---
|
||||||
24
kubevirt-manager/deployments/deployment.yaml
Normal file
24
kubevirt-manager/deployments/deployment.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: kubevirt-manager
|
||||||
|
namespace: kubevirt-manager
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: kubevirt-manager
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: kubevirt-manager
|
||||||
|
spec:
|
||||||
|
serviceAccountName: kubevirt-manager
|
||||||
|
containers:
|
||||||
|
- name: kubevirt-manager
|
||||||
|
image: kubevirtmanager/kubevirt-manager:1.4.0
|
||||||
|
ports:
|
||||||
|
- containerPort: 8001
|
||||||
|
env:
|
||||||
|
- name: BACKEND_URL
|
||||||
|
value: "http://localhost:8080"
|
||||||
26
kubevirt-manager/ingress/ingress.yaml
Normal file
26
kubevirt-manager/ingress/ingress.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: kubevirt-manager
|
||||||
|
namespace: kubevirt-manager
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- kubevirt.manabo.org
|
||||||
|
secretName: kubevirt-manager-tls
|
||||||
|
rules:
|
||||||
|
- host: kubevirt.manabo.org
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: kubevirt-manager
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
7
kubevirt-manager/kustomization.yaml
Normal file
7
kubevirt-manager/kustomization.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- deployments/deployment.yaml
|
||||||
|
- services/service.yaml
|
||||||
|
# - ingress/ingress.yaml
|
||||||
|
- rbac/serviceaccount.yaml
|
||||||
|
- rbac/clusterrolebinding.yaml
|
||||||
4
kubevirt-manager/namespace.yaml
Normal file
4
kubevirt-manager/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: kubevirt-manager
|
||||||
12
kubevirt-manager/rbac/clusterrolebinding.yaml
Normal file
12
kubevirt-manager/rbac/clusterrolebinding.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: kubevirt-manager
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: cluster-admin
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: kubevirt-manager
|
||||||
|
namespace: kubevirt-manager
|
||||||
6
kubevirt-manager/rbac/serviceaccount.yaml
Normal file
6
kubevirt-manager/rbac/serviceaccount.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: kubevirt-manager
|
||||||
|
namespace: kubevirt-manager
|
||||||
|
|
||||||
14
kubevirt-manager/services/service.yaml
Normal file
14
kubevirt-manager/services/service.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: kubevirt-manager
|
||||||
|
namespace: kubevirt-manager
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: kubevirt-manager
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 8001
|
||||||
|
protocol: TCP
|
||||||
|
nodePort: 30081 # <--- puedes elegir el puerto, debe estar entre 30000-32767
|
||||||
|
type: NodePort
|
||||||
65
kubevirt.md
Normal file
65
kubevirt.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# Instalación de KubeVirt y CDI en Kubernetes (Ubuntu/SUSE)
|
||||||
|
|
||||||
|
## 1. Instala KubeVirt y CDI
|
||||||
|
|
||||||
|
KubeVirt permite crear y gestionar máquinas virtuales dentro de Kubernetes, integrando cargas virtualizadas junto a contenedores. CDI (Containerized Data Importer) facilita la gestión y carga de discos e ISOs para esas VMs.
|
||||||
|
|
||||||
|
> **Nota:** Puedes usar manifiestos oficiales, o crear tu carpeta `kubevirt/` si deseas versionar los YAML personalizados.
|
||||||
|
|
||||||
|
### Instala KubeVirt (recomendado hacerlo tras tener la red y almacenamiento)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)
|
||||||
|
kubectl create namespace kubevirt
|
||||||
|
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml
|
||||||
|
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Instala CDI (para gestión de discos/ISOs)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export CDI_VERSION=$(curl -s https://api.github.com/repos/kubevirt/containerized-data-importer/releases/latest | grep tag_name | cut -d '"' -f 4)
|
||||||
|
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-operator.yaml
|
||||||
|
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-cr.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Instala virtctl (CLI de KubeVirt)
|
||||||
|
|
||||||
|
`virtctl` es una herramienta de línea de comandos para interactuar fácilmente con las máquinas virtuales de KubeVirt: arranque, apagado, consola, etc.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/virtctl-${KUBEVIRT_VERSION}-linux-amd64
|
||||||
|
chmod +x virtctl
|
||||||
|
sudo mv virtctl /usr/local/bin/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Habilita KVM para tu usuario
|
||||||
|
|
||||||
|
Para poder crear y gestionar máquinas virtuales, tu usuario debe pertenecer al grupo `kvm` (acceso al hardware de virtualización).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo usermod -aG kvm $(whoami)
|
||||||
|
# Reinicia sesión o ejecuta 'newgrp kvm' para aplicar
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Despliega kubevirt-manager
|
||||||
|
|
||||||
|
`kubevirt-manager` es una interfaz web sencilla para gestionar tus máquinas virtuales desde el navegador. Esta sección aplica sus manifiestos en Kubernetes.
|
||||||
|
|
||||||
|
La carpeta `kubevirt-manager/` contiene todos los manifiestos organizados por tipo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -k kubevirt-manager/
|
||||||
|
```
|
||||||
|
|
||||||
|
Puedes comprobar el estado:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get pods -n kubevirt-manager
|
||||||
|
```
|
||||||
7
metallb/ipaddresspool.yaml
Normal file
7
metallb/ipaddresspool.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: IPAddressPool
|
||||||
|
metadata:
|
||||||
|
name: single-ip
|
||||||
|
spec:
|
||||||
|
addresses:
|
||||||
|
- 192.168.1.100/32
|
||||||
4
metallb/kustomization.yaml
Normal file
4
metallb/kustomization.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
namespace: metallb-system
|
||||||
|
resources:
|
||||||
|
- ipaddresspool.yaml
|
||||||
|
- l2advertisement.yaml
|
||||||
5
metallb/l2advertisement.yaml
Normal file
5
metallb/l2advertisement.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: L2Advertisement
|
||||||
|
metadata:
|
||||||
|
name: l2adv
|
||||||
|
spec: {}
|
||||||
19
multus/nad-br-servicios.yaml
Normal file
19
multus/nad-br-servicios.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: "k8s.cni.cncf.io/v1"
|
||||||
|
kind: NetworkAttachmentDefinition
|
||||||
|
metadata:
|
||||||
|
name: br-servicios
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
config: '{
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"type": "bridge",
|
||||||
|
"bridge": "br-servicios",
|
||||||
|
"ipam": {
|
||||||
|
"type": "host-local",
|
||||||
|
"subnet": "192.168.200.0/22",
|
||||||
|
"rangeStart": "192.168.200.100",
|
||||||
|
"rangeEnd": "192.168.200.200",
|
||||||
|
"routes": [{"dst": "0.0.0.0/0"}],
|
||||||
|
"gateway": "192.168.200.1"
|
||||||
|
}
|
||||||
|
}'
|
||||||
14
multus/test-multus-pod.yaml
Normal file
14
multus/test-multus-pod.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: multus-test
|
||||||
|
annotations:
|
||||||
|
k8s.v1.cni.cncf.io/networks: br-servicios
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: alpine
|
||||||
|
image: alpine
|
||||||
|
command: ["sleep", "infinity"]
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add: ["NET_ADMIN"]
|
||||||
696
readme-suse.md
Normal file
696
readme-suse.md
Normal file
@@ -0,0 +1,696 @@
|
|||||||
|
# 0. Ejemplo de configuración de red en SUSE con NetworkManager
|
||||||
|
|
||||||
|
Aquí defines cómo se conectará tu servidor físicamente a la red en openSUSE/SLES: enlaces redundantes (bonding), VLANs para segmentar el tráfico, y bridges para conectar máquinas virtuales y pods a distintas redes. Esta configuración es la base para un clúster flexible y segmentado.
|
||||||
|
|
||||||
|
> **Pre-requisitos:**
|
||||||
|
>
|
||||||
|
> * openSUSE/SLES con NetworkManager activo.
|
||||||
|
> * Interfaces físicas: `em1` y `em2` (ajusta según tu hardware).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Crear el bond (LACP 802.3ad, rápido, hash layer3+4)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli con add type bond ifname bond0 mode 802.3ad
|
||||||
|
nmcli con mod bond0 bond.options "mode=802.3ad,miimon=100,updelay=200,downdelay=200,lacp_rate=fast,xmit_hash_policy=layer3+4"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Añadir interfaces físicas al bond
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli con add type ethernet ifname em1 master bond0
|
||||||
|
nmcli con add type ethernet ifname em2 master bond0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Crear VLANs sobre el bond
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli con add type vlan ifname vlan10 dev bond0 id 10
|
||||||
|
nmcli con add type vlan ifname vlan20 dev bond0 id 20
|
||||||
|
nmcli con add type vlan ifname vlan30 dev bond0 id 30 ip4 192.168.3.2/24
|
||||||
|
nmcli con add type vlan ifname vlan40 dev bond0 id 40 ip4 192.168.4.2/24
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Crear bridges y unirlos a las VLANs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Bridge de administración (br-admin) sobre vlan10
|
||||||
|
nmcli con add type bridge ifname br-admin
|
||||||
|
nmcli con add type bridge-slave ifname vlan10 master br-admin
|
||||||
|
nmcli con mod br-admin ipv4.addresses 192.168.0.42/24
|
||||||
|
nmcli con mod br-admin ipv4.method manual
|
||||||
|
nmcli con mod br-admin ipv4.gateway 192.168.0.1
|
||||||
|
nmcli con mod br-admin ipv4.dns "192.168.0.1 1.1.1.1 8.8.8.8"
|
||||||
|
|
||||||
|
# Bridge de servicios (br-srv) sobre vlan20
|
||||||
|
nmcli con add type bridge ifname br-srv
|
||||||
|
nmcli con add type bridge-slave ifname vlan20 master br-srv
|
||||||
|
nmcli con mod br-srv ipv4.addresses 192.168.200.2/22
|
||||||
|
nmcli con mod br-srv ipv4.method manual
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Sube todas las conexiones (en orden: bond, VLANs, bridges)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli con up bond0
|
||||||
|
nmcli con up vlan10
|
||||||
|
nmcli con up vlan20
|
||||||
|
nmcli con up vlan30
|
||||||
|
nmcli con up vlan40
|
||||||
|
nmcli con up br-admin
|
||||||
|
nmcli con up br-srv
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Guía rápida: Instalar Kubernetes en openSUSE/SLES
|
||||||
|
|
||||||
|
Esta guía cubre todos los pasos necesarios para instalar Kubernetes en openSUSE Leap, Tumbleweed o SLES, usando containerd como runtime y gestionando todo con zypper. Sigue el orden de los pasos para evitar problemas.
|
||||||
|
|
||||||
|
# Guía definitiva de despliegue Kubernetes (openSUSE/SLES)
|
||||||
|
|
||||||
|
> **Revisión y correcciones basadas en el history real de despliegue**
|
||||||
|
|
||||||
|
## 1. Prerrequisitos del sistema (SUSE)
|
||||||
|
|
||||||
|
Este paso parte de una instalación limpia de openSUSE/SLES actualizada y con permisos de administrador. Instala utilidades básicas, configura el repositorio oficial de Kubernetes y desactiva SWAP, igual que harías en Ubuntu, pero con comandos adaptados a zypper y la gestión de repositorios en SUSE.
|
||||||
|
|
||||||
|
### a) Actualiza el sistema y paquetes básicos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo zypper refresh
|
||||||
|
sudo zypper update
|
||||||
|
sudo zypper install -y curl ca-certificates keepalived chrony
|
||||||
|
```
|
||||||
|
|
||||||
|
### b) Añade el repositorio oficial de Kubernetes
|
||||||
|
|
||||||
|
Crea el archivo de repositorio para Kubernetes (v1.33):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<EOF | sudo tee /etc/zypp/repos.d/kubernetes.repo
|
||||||
|
[kubernetes]
|
||||||
|
name=Kubernetes
|
||||||
|
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
|
||||||
|
enabled=1
|
||||||
|
gpgcheck=1
|
||||||
|
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Actualiza la caché de repositorios y acepta la clave GPG cuando se te pida:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo zypper refresh
|
||||||
|
sudo zypper update
|
||||||
|
```
|
||||||
|
|
||||||
|
> Cuando veas el aviso sobre la clave GPG, pulsa 'a' para aceptar siempre.
|
||||||
|
|
||||||
|
### c) Configuración de Keepalived
|
||||||
|
|
||||||
|
En SRVFKVM01 (MASTER):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<EOF | sudo tee /etc/keepalived/keepalived.conf
|
||||||
|
vrrp_instance VI_1 {
|
||||||
|
state MASTER
|
||||||
|
interface br-admin
|
||||||
|
virtual_router_id 51
|
||||||
|
priority 150
|
||||||
|
advert_int 1
|
||||||
|
authentication {
|
||||||
|
auth_type PASS
|
||||||
|
auth_pass 42manabo42
|
||||||
|
}
|
||||||
|
virtual_ipaddress {
|
||||||
|
192.168.0.20/24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
En los demás (BACKUP):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<EOF | sudo tee /etc/keepalived/keepalived.conf
|
||||||
|
vrrp_instance VI_1 {
|
||||||
|
state BACKUP
|
||||||
|
interface br-admin
|
||||||
|
virtual_router_id 51
|
||||||
|
priority 100
|
||||||
|
advert_int 1
|
||||||
|
authentication {
|
||||||
|
auth_type PASS
|
||||||
|
auth_pass 42manabo42
|
||||||
|
}
|
||||||
|
virtual_ipaddress {
|
||||||
|
192.168.0.20/24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Después en todos:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo systemctl enable keepalived
|
||||||
|
sudo systemctl start keepalived
|
||||||
|
```
|
||||||
|
|
||||||
|
### d) Sincronización horaria
|
||||||
|
|
||||||
|
En todos los servidores del cluster:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable chronyd
|
||||||
|
sudo systemctl start chronyd
|
||||||
|
sudo chronyc makestep # Fuerza la sincronización inicial
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Instala containerd (runtime recomendado)
|
||||||
|
|
||||||
|
`containerd` es el motor que gestiona los contenedores en el clúster. Kubernetes necesita un “runtime” para crear y controlar los pods, y containerd es la opción oficial y más estable.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo zypper install -y containerd
|
||||||
|
sudo mkdir -p /etc/containerd
|
||||||
|
sudo containerd config default | sudo tee /etc/containerd/config.toml
|
||||||
|
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
|
||||||
|
sudo systemctl restart containerd
|
||||||
|
sudo systemctl enable containerd
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Desactiva SWAP (requisito para Kubernetes)
|
||||||
|
|
||||||
|
Kubernetes requiere que el intercambio de memoria (swap) esté desactivado. Esto evita problemas de rendimiento y estabilidad.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo swapoff -a
|
||||||
|
sudo sed -i '/ swap / s/^/#/' /etc/fstab
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Prepara el kernel y sysctl y abre puertos
|
||||||
|
|
||||||
|
En este paso se habilitan módulos y parámetros de red necesarios para que Kubernetes gestione correctamente el tráfico entre pods y nodos.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo modprobe overlay
|
||||||
|
sudo modprobe br_netfilter
|
||||||
|
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
|
||||||
|
net.bridge.bridge-nf-call-iptables = 1
|
||||||
|
net.ipv4.ip_forward = 1
|
||||||
|
net.bridge.bridge-nf-call-ip6tables = 1
|
||||||
|
EOF
|
||||||
|
sudo sysctl --system
|
||||||
|
```
|
||||||
|
|
||||||
|
el trafico basico que se debe permitir es:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Básico Kubernetes
|
||||||
|
# Asocia la interfaz de red interna del clúster a la zona trusted (típicamente br-admin)
|
||||||
|
sudo firewall-cmd --zone=trusted --add-interface=br-admin --permanent
|
||||||
|
sudo firewall-cmd --zone=trusted --add-interface=vlan40 --permanent
|
||||||
|
|
||||||
|
# Abre solo en zona trusted los puertos necesarios para el clúster:
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=6443/tcp --permanent # API Server
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=10250/tcp --permanent # Kubelet API
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=2379/tcp --permanent # etcd client (solo control-plane)
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=2380/tcp --permanent # etcd peer (solo control-plane)
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=8472/udp --permanent # Flannel VXLAN (si usas Flannel)
|
||||||
|
|
||||||
|
# Si vas a exponer servicios (Traefik, MetalLB), abre HTTP/HTTPS solo si lo necesitas en todos los nodos
|
||||||
|
# (mejor hacerlo en los nodos donde se expone tráfico externo, no en todos)
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=80/tcp --permanent
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=443/tcp --permanent
|
||||||
|
|
||||||
|
# (Opcional) Si usas NodePort, abre el rango solo si usas ese tipo de servicio:
|
||||||
|
sudo firewall-cmd --zone=trusted --add-port=30000-32767/tcp --permanent
|
||||||
|
|
||||||
|
# Recarga las reglas
|
||||||
|
sudo firewall-cmd --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Instala los componentes de Kubernetes (kubectl, kubelet, kubeadm)
|
||||||
|
|
||||||
|
Instala en un solo paso las utilidades principales:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo zypper install -y kubectl kubelet kubeadm
|
||||||
|
```
|
||||||
|
|
||||||
|
Edita `/etc/sysconfig/kubelet` para poner la dirección IP que tendrá el nodo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
KUBELET_EXTRA_ARGS=--node-ip=192.168.4.1 # <-- Dirección ip de cada nodo en la Vlan interna del cluster
|
||||||
|
```
|
||||||
|
|
||||||
|
Activa kubelet para que se inicie automáticamente:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable kubelet
|
||||||
|
sudo systemctl start kubelet
|
||||||
|
```
|
||||||
|
|
||||||
|
> Es **normal** que el servicio kubelet falle en bucle hasta que inicialices el clúster con `kubeadm init`.
|
||||||
|
> El error más frecuente es:
|
||||||
|
>
|
||||||
|
> * "failed to load Kubelet config file, path: /var/lib/kubelet/config.yaml"
|
||||||
|
>
|
||||||
|
> Tras ejecutar `kubeadm init`, kubelet arrancará correctamente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5b. (Opcional) Habilita cgroup v2 (solo SLES si necesario)
|
||||||
|
|
||||||
|
Si necesitas cgroup v2 en SLES, añade esto al arranque del kernel (edita `/etc/default/grub`):
|
||||||
|
|
||||||
|
```
|
||||||
|
GRUB_CMDLINE_LINUX_DEFAULT="systemd.unified_cgroup_hierarchy=1 ..."
|
||||||
|
```
|
||||||
|
|
||||||
|
Y regenera el grub:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
Reinicia para aplicar los cambios.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 6. Inicializa el clúster (openSUSE/SLES)
|
||||||
|
|
||||||
|
Este paso crea el clúster de Kubernetes en el nodo principal (control-plane) sobre openSUSE/SLES. Aquí defines la red interna para los pods y la interfaz/VLAN física para el tráfico overlay del clúster, según tu diseño.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## a) Inicializa el clúster especificando red de pods, la IP interna y la VIP
|
||||||
|
|
||||||
|
> **Importante:**
|
||||||
|
>
|
||||||
|
> * Usa la opción `--apiserver-advertise-address` para forzar que el nodo control-plane escuche en la IP de la VLAN interna de clúster (ejemplo: `192.168.4.x` en tu VLAN 40).
|
||||||
|
> * Usa `--control-plane-endpoint` para indicar la IP virtual compartida (VIP) gestionada por Keepalived. Debe ser una IP accesible por todos los nodos control-plane (ejemplo: `192.168.0.20`).
|
||||||
|
> * Usa `--apiserver-cert-extra-sans` para añadir la VIP (y/o el FQDN) como SAN en el certificado TLS del API server, así todos los nodos confían en esa IP/nombre.
|
||||||
|
> * Usa `--pod-network-cidr=10.244.0.0/16` si vas a usar Flannel como CNI (ajusta si usas otro CNI).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo kubeadm init \
|
||||||
|
--apiserver-advertise-address=192.168.4.1 \
|
||||||
|
--control-plane-endpoint="192.168.0.20:6443" \
|
||||||
|
--apiserver-cert-extra-sans="192.168.0.20" \
|
||||||
|
--pod-network-cidr=10.244.0.0/16 \
|
||||||
|
--upload-certs
|
||||||
|
```
|
||||||
|
|
||||||
|
Cambia `192.168.4.1` por la IP interna del nodo donde ejecutas el comando (en la VLAN de clúster) y `192.168.0.20` por la IP VIP gestionada por Keepalived.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## c) Configura kubectl para tu usuario
|
||||||
|
|
||||||
|
Permite usar el comando `kubectl` como usuario normal copiando la configuración de administración del clúster a tu carpeta personal.
|
||||||
|
|
||||||
|
En el nodo master (SRVFKVM01)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p $HOME/.kube
|
||||||
|
cd /etc/kubernetes
|
||||||
|
sudo cp -i admin.conf $HOME/.kube/config
|
||||||
|
sudo scp config admin.c3s@192.168.0.4X:/home/admin.c3s/admin.conf #a todos los nodos
|
||||||
|
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||||
|
```
|
||||||
|
|
||||||
|
## d) Instala la red de pods (Flannel) usando la VLAN interna del clúster
|
||||||
|
|
||||||
|
Kubernetes solo define la infraestructura; necesitas un complemento de red (CNI) para que los pods puedan comunicarse entre sí. Flannel es la opción más sencilla y compatible, y puedes configurarla para usar una interfaz/VLAN específica para el tráfico overlay (muy recomendable si segmentas redes en tu clúster).
|
||||||
|
|
||||||
|
### **¡ATENCIÓN! CNI Y PLUGINS:**
|
||||||
|
|
||||||
|
Antes de aplicar Flannel, **asegúrate de tener los plugins CNI instalados en `/opt/cni/bin/`** (en SUSE esto NO siempre lo hace el paquete de Flannel):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CNI_VERSION="v1.4.1"
|
||||||
|
ARCH="amd64"
|
||||||
|
curl -Lo cni-plugins.tgz https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-${ARCH}-${CNI_VERSION}.tgz
|
||||||
|
sudo mkdir -p /opt/cni/bin
|
||||||
|
sudo tar -C /opt/cni/bin -xzf cni-plugins.tgz
|
||||||
|
```
|
||||||
|
|
||||||
|
Verifica que existen al menos:
|
||||||
|
|
||||||
|
* `/opt/cni/bin/loopback`
|
||||||
|
* `/opt/cni/bin/flannel`
|
||||||
|
* `/opt/cni/bin/bridge` y otros
|
||||||
|
|
||||||
|
Corrige permisos si hace falta:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo chmod +x /opt/cni/bin/*
|
||||||
|
sudo chown root:root /opt/cni/bin/*
|
||||||
|
```
|
||||||
|
|
||||||
|
**Luego sí aplica Flannel:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## e) Comprueba que Flannel funciona
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl -n kube-flannel get pods -o wide
|
||||||
|
```
|
||||||
|
|
||||||
|
> Todos los pods deben estar en estado `Running`.
|
||||||
|
|
||||||
|
Si no levanta, **verifica logs y revisa `/opt/cni/bin/`**:
|
||||||
|
|
||||||
|
* Los binarios deben ser para la arquitectura correcta (x86\_64/amd64).
|
||||||
|
* Deben tener permisos de ejecución y ser propiedad de root.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## f) Une el resto de nodos control-plane
|
||||||
|
|
||||||
|
En los demás nodos control-plane (tras configurar Keepalived y tener la VIP activa):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo kubeadm join 192.168.0.20:6443 \
|
||||||
|
--token <TOKEN> \
|
||||||
|
--discovery-token-ca-cert-hash <HASH> \
|
||||||
|
--control-plane \
|
||||||
|
--certificate-key <CERTIFICATE_KEY> \
|
||||||
|
--apiserver-advertise-address=192.168.4.2
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Importante:** Cambia la IP `192.168.4.2` por la correspondiente a cada servidor control-plane que estés uniendo.
|
||||||
|
|
||||||
|
Recuerda usar los valores correctos de token, hash y certificate-key que te dará el comando `kubeadm init` o puedes volver a consultar desde el nodo principal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubeadm token create --print-join-command --control-plane
|
||||||
|
```
|
||||||
|
|
||||||
|
Credenciales para todos (lo que le gusta al jefe):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p $HOME/.kube
|
||||||
|
cd
|
||||||
|
sudo cp -i admin.conf $HOME/.kube/config
|
||||||
|
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## EXTRA: Si te ha caducado el TOKEN, o no lo guardaste
|
||||||
|
|
||||||
|
Cuando el token de unión (`kubeadm join`) ha caducado, sigue estos pasos en el **nodo principal (control-plane)** para generar un nuevo token y el comando actualizado:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 1. Sube los certificados y obtén la nueva clave de certificado (certificate-key)
|
||||||
|
sudo kubeadm init phase upload-certs --upload-certs
|
||||||
|
```
|
||||||
|
|
||||||
|
> La salida mostrará la nueva `certificate key`, necesaria para añadir un nuevo nodo de control-plane.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 2. Genera un nuevo token y muestra el comando kubeadm join listo para usar
|
||||||
|
sudo kubeadm token create --print-join-command
|
||||||
|
```
|
||||||
|
|
||||||
|
> La salida mostrará el comando `kubeadm join` con el nuevo token y el hash actual del CA.
|
||||||
|
|
||||||
|
### Ejemplo de salidas:
|
||||||
|
|
||||||
|
```
|
||||||
|
[upload-certs] Using certificate key:
|
||||||
|
588ee9d0441c0aea36b2a2a638beae4cfa81dd3498eb61205c8496f344f6c55d
|
||||||
|
|
||||||
|
kubeadm join 192.168.0.20:6443 --token s9nlsp.gasv66tkc43zpiok --discovery-token-ca-cert-hash sha256:d41f0edb90c66c0555bdf4feca55f1e69019764be0fcd649a254e99ff124568f
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Comando completo para unir un nodo **como control-plane**
|
||||||
|
|
||||||
|
Añade los parámetros `--control-plane --certificate-key <certificate-key> --apiserver-advertise-address=192.168.4.2` al final del comando `kubeadm join` generado. Usando el ejemplo anterior, el comando final sería:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo kubeadm join 192.168.0.20:6443 \
|
||||||
|
--token s9nlsp.gasv66tkc43zpiok \
|
||||||
|
--discovery-token-ca-cert-hash sha256:d41f0edb90c66c0555bdf4feca55f1e69019764be0fcd649a254e99ff124568f \
|
||||||
|
--control-plane \
|
||||||
|
--certificate-key 588ee9d0441c0aea36b2a2a638beae4cfa81dd3498eb61205c8496f344f6c55d \
|
||||||
|
--apiserver-advertise-address=192.168.4.2
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Recuerda**: Cambia `192.168.4.2` por la IP real del nodo que se está uniendo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Con esto podrás unir cualquier nodo extra como nuevo control-plane, incluso cuando el token original haya caducado.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Troubleshooting y buenas prácticas extra**
|
||||||
|
|
||||||
|
* Si ves errores con el loopback CNI (`exec format error`, `permission denied`, etc.), **borra el contenido de `/opt/cni/bin/` y vuelve a instalar los plugins**.
|
||||||
|
* Siempre revisa que el módulo `br_netfilter` está cargado y los sysctl activos (`lsmod | grep br_netfilter`).
|
||||||
|
* Si el nodo aparece como NotReady, revisa `/etc/cni/net.d/`, los logs de kubelet, y repite la reinstalación del CNI.
|
||||||
|
* **Si limpias todo y reinicias, repite estos pasos:**
|
||||||
|
|
||||||
|
* Reinstala CNI plugins
|
||||||
|
* Aplica Flannel
|
||||||
|
* Reinicia kubelet
|
||||||
|
|
||||||
|
|
||||||
|
# 8. Instala Multus (opcional, para múltiples redes)
|
||||||
|
|
||||||
|
Multus permite que un pod tenga más de una interfaz de red (multi-homed), útil para appliances, firewalls, balanceadores, gateways, etc. Instálalo si necesitas conectar pods a varias redes físicas o VLANs (por ejemplo, mediante bridges y NADs).
|
||||||
|
|
||||||
|
**Instalación:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verifica:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get pods -n kube-system | grep multus
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 9. (Opcional) Quita el taint del nodo master para poder programar pods en él
|
||||||
|
|
||||||
|
Por defecto, Kubernetes no programa pods de usuario en el nodo principal (control-plane). Elimina este bloqueo para poder desplegar aplicaciones ahí.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
|
||||||
|
kubectl taint nodes --all node-role.kubernetes.io/master-
|
||||||
|
```
|
||||||
|
## Nota: Uso de taints en nodos control-plane (alta disponibilidad y ejecución de cargas)
|
||||||
|
|
||||||
|
### ¿Qué es un taint?
|
||||||
|
|
||||||
|
* Un **taint** en Kubernetes es una marca especial que se pone a un nodo para **evitar que los pods se programen ahí**, salvo que declaren una “toleration” explícita.
|
||||||
|
* Se usa para reservar nodos solo para tareas especiales (por ejemplo, el control-plane).
|
||||||
|
* Por defecto, los nodos control-plane llevan un taint:
|
||||||
|
|
||||||
|
* `node-role.kubernetes.io/control-plane:NoSchedule`
|
||||||
|
|
||||||
|
### ¿Por qué quitar el taint?
|
||||||
|
|
||||||
|
* Si quieres que **los nodos control-plane puedan ejecutar pods de usuario** (además del plano de control), necesitas **quitar el taint**.
|
||||||
|
* Esto es común en clústeres pequeños o medianos, donde **todos los nodos cumplen doble función** (alta disponibilidad y ejecución de cargas).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **Comandos para quitar el taint de todos los nodos control-plane:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
|
||||||
|
kubectl taint nodes --all node-role.kubernetes.io/master-
|
||||||
|
```
|
||||||
|
|
||||||
|
* El `-` final indica “quitar”.
|
||||||
|
* Ejecuta ambos para máxima compatibilidad entre versiones.
|
||||||
|
|
||||||
|
### **Comando para añadir el taint (dejar el nodo solo como control-plane):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl taint nodes NOMBRE_DEL_NODO node-role.kubernetes.io/control-plane=:NoSchedule
|
||||||
|
```
|
||||||
|
|
||||||
|
* Así, ese nodo **solo ejecuta el plano de control** (salvo pods con toleration específica).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 10. Test rápido de Multus (NAD + pod con 2 interfaces)
|
||||||
|
|
||||||
|
Puedes comprobar que Multus funciona creando una red secundaria y un pod de prueba con dos interfaces (una por defecto, una secundaria).
|
||||||
|
|
||||||
|
En la carpeta `multus/` de tu repositorio, debes tener:
|
||||||
|
|
||||||
|
* `multus/nad-br-servicios.yaml` (NetworkAttachmentDefinition)
|
||||||
|
* `multus/test-multus-pod.yaml` (pod Alpine multi-homed)
|
||||||
|
|
||||||
|
**Despliega la NAD:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f multus/nad-br-servicios.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Despliega el pod de test:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f multus/test-multus-pod.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Comprueba las interfaces:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl exec -it multus-test -- sh
|
||||||
|
ip a
|
||||||
|
```
|
||||||
|
|
||||||
|
* El pod debe mostrar una interfaz extra (además de la de Flannel), conectada a tu red secundaria (`br-servicios`, etc.).
|
||||||
|
|
||||||
|
**Para limpiar:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl delete pod multus-test
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **Nota:** Puedes crear tantas NADs (NetworkAttachmentDefinition) como bridges/VLANs quieras conectar a pods específicos (con Multus), ideal para appliances de red, gateways, SDN, pruebas de seguridad, etc.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 11. Instalación y configuración de MetalLB (LoadBalancer local)
|
||||||
|
|
||||||
|
MetalLB permite asignar IPs flotantes de tu red LAN a servicios `LoadBalancer`, igual que hacen los clústeres en la nube. Es fundamental si quieres exponer servicios como ingress, dashboards, etc., accesibles desde tu red local.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## a) Instala MetalLB
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Esto crea el namespace `metallb-system` y los pods necesarios.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## b) Declara múltiples pools de IP
|
||||||
|
|
||||||
|
Puedes crear varios pools (por ejemplo, uno para producción y otro para test, o para diferentes VLANs/segmentos). Los pools se definen en el objeto `IPAddressPool`.
|
||||||
|
|
||||||
|
**Ejemplo: `metallb/ipaddresspool.yaml`**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: IPAddressPool
|
||||||
|
metadata:
|
||||||
|
name: pool-produccion
|
||||||
|
namespace: metallb-system
|
||||||
|
spec:
|
||||||
|
addresses:
|
||||||
|
- 192.168.1.100-192.168.1.110
|
||||||
|
---
|
||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: IPAddressPool
|
||||||
|
metadata:
|
||||||
|
name: pool-lab
|
||||||
|
namespace: metallb-system
|
||||||
|
spec:
|
||||||
|
addresses:
|
||||||
|
- 192.168.2.100-192.168.2.110
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ejemplo: `metallb/l2advertisement.yaml`**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: L2Advertisement
|
||||||
|
metadata:
|
||||||
|
name: advert-all
|
||||||
|
namespace: metallb-system
|
||||||
|
spec: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Kustomization:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
resources:
|
||||||
|
- ipaddresspool.yaml
|
||||||
|
- l2advertisement.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Para aplicar:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -k metallb/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## c) Asigna un pool concreto a un Service (anotaciones)
|
||||||
|
|
||||||
|
Por defecto, los Services `LoadBalancer` usan cualquier pool disponible. Para forzar el uso de un pool específico, **añade esta anotación al Service**:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: ejemplo-prod
|
||||||
|
annotations:
|
||||||
|
metallb.universe.tf/address-pool: pool-produccion
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: ejemplo
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
type: LoadBalancer
|
||||||
|
```
|
||||||
|
|
||||||
|
* Cambia `pool-produccion` por el nombre de pool que quieras usar.
|
||||||
|
|
||||||
|
Al crear el Service, MetalLB le asignará una IP **solo de ese pool**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## d) Comprobar el resultado
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get svc
|
||||||
|
```
|
||||||
|
|
||||||
|
Verás la IP asignada en la columna `EXTERNAL-IP`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **Notas:**
|
||||||
|
>
|
||||||
|
> * Puedes definir tantos pools como necesites, uno por segmento/VLAN/uso.
|
||||||
|
> * Puedes versionar los manifiestos de MetalLB en una carpeta específica del repositorio (`metallb/`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
43
readme.md
Normal file
43
readme.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Guía Oficial de Instalación de Kubernetes en SUSE
|
||||||
|
|
||||||
|
Este repositorio contiene los **manifiestos, scripts y documentación oficial** para desplegar y gestionar un clúster Kubernetes basado en SUSE Linux.
|
||||||
|
|
||||||
|
> **NOTA:** Todo el proceso está documentado paso a paso, con comprobaciones, consideraciones y mejores prácticas.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Índice de documentos y referencias cruzadas
|
||||||
|
|
||||||
|
| Documento | Descripción | Referencia |
|
||||||
|
| ------------------- | ------------------------------------------ | ------------------------ |
|
||||||
|
| `readme.md` | Índice y presentación general | (Este documento) |
|
||||||
|
| `comprobaciones.md` | Checklist y pruebas tras cada paso crítico | [Ver](comprobaciones.md) |
|
||||||
|
| `cephrook.md` | Instalación e integración de Ceph/Rook | [Ver](cephrook.md) |
|
||||||
|
| `Clusterkey.txt` | Clave actual del clúster y certificate-key | [Ver](Clusterkey.txt) |
|
||||||
|
| `kubevirt.md` | Despliegue de KubeVirt y gestión de VMs | [Ver](kubevirt.md) |
|
||||||
|
| `readme-suse.md` | Proceso de instalación detallado en SUSE | [Ver](readme-suse.md) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado actual de los documentos
|
||||||
|
|
||||||
|
| Documento | Estado | Comentario |
|
||||||
|
| ------------------- | -------------- | ------------------------------------- |
|
||||||
|
| `readme.md` | ✅ Completado | Actualizado |
|
||||||
|
| `comprobaciones.md` | ⚠️ En revisión | Añadir más pruebas específicas |
|
||||||
|
| `cephrook.md` | ⚠️ En revisión | Integración Ceph pendiente de validar |
|
||||||
|
| `Clusterkey.txt` | ✅ Completado | Clave generada y aplicada |
|
||||||
|
| `kubevirt.md` | ⚠️ En revisión | Revisar últimas pruebas de VMs |
|
||||||
|
| `readme-suse.md` | ✅ Completado | Instalación básica validada |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ¿Cómo usar este repositorio?
|
||||||
|
|
||||||
|
1. Sigue el orden de los documentos desde `readme-suse.md`.
|
||||||
|
2. Comprueba cada paso con `comprobaciones.md`.
|
||||||
|
3. Consulta el resto de documentos según el despliegue requerido (Ceph, KubeVirt, etc).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
¿Dudas, mejoras o sugerencias? Haz un pull request o abre un issue.
|
||||||
41
storage/deployments/nfs-client-provisioner.yaml
Normal file
41
storage/deployments/nfs-client-provisioner.yaml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nfs-client-provisioner
|
||||||
|
namespace: nfs-provisioner
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nfs-client-provisioner
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nfs-client-provisioner
|
||||||
|
spec:
|
||||||
|
serviceAccountName: nfs-client-provisioner
|
||||||
|
containers:
|
||||||
|
- name: nfs-client-provisioner
|
||||||
|
image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
|
||||||
|
volumeMounts:
|
||||||
|
- name: nfs-client-root
|
||||||
|
mountPath: /persistentvolumes
|
||||||
|
env:
|
||||||
|
- name: PROVISIONER_NAME
|
||||||
|
value: k8s-sigs.io/nfs-subdir-external-provisioner
|
||||||
|
- name: NFS_SERVER
|
||||||
|
value: 192.168.3.3 # VLAN 30 IP de niflheim
|
||||||
|
- name: NFS_PATH
|
||||||
|
value: /
|
||||||
|
- name: LABELS
|
||||||
|
value: "namespace,pvcName"
|
||||||
|
volumes:
|
||||||
|
- name: nfs-client-root
|
||||||
|
nfs:
|
||||||
|
server: 192.168.3.3
|
||||||
|
path: /
|
||||||
|
tolerations:
|
||||||
|
- key: "storage"
|
||||||
|
operator: "Equal"
|
||||||
|
value: "only"
|
||||||
|
effect: "NoSchedule"
|
||||||
43
storage/deployments/nfs-server.yaml
Normal file
43
storage/deployments/nfs-server.yaml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nfs-server
|
||||||
|
namespace: nfs-provisioner
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nfs-server
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nfs-server
|
||||||
|
spec:
|
||||||
|
hostNetwork: true
|
||||||
|
containers:
|
||||||
|
- name: nfs-server
|
||||||
|
image: itsthenetwork/nfs-server-alpine:latest
|
||||||
|
ports:
|
||||||
|
- name: nfs
|
||||||
|
containerPort: 2049
|
||||||
|
protocol: TCP
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
|
env:
|
||||||
|
- name: SHARED_DIRECTORY
|
||||||
|
value: /nfsshare
|
||||||
|
volumeMounts:
|
||||||
|
- name: nfs-data
|
||||||
|
mountPath: /nfsshare
|
||||||
|
volumes:
|
||||||
|
- name: nfs-data
|
||||||
|
hostPath:
|
||||||
|
path: /mnt/storage/k8s/nfsshare
|
||||||
|
type: Directory
|
||||||
|
tolerations:
|
||||||
|
- key: "storage"
|
||||||
|
operator: "Equal"
|
||||||
|
value: "only"
|
||||||
|
effect: "NoSchedule"
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: niflheim
|
||||||
8
storage/kustomization.yaml
Normal file
8
storage/kustomization.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- rbac/clusterrolebinding.yaml
|
||||||
|
- rbac/clusterrole.yaml
|
||||||
|
- rbac/serviceaccount.yaml
|
||||||
|
# - deployments/nfs-server.yaml
|
||||||
|
- deployments/nfs-client-provisioner.yaml
|
||||||
|
- storageclass/storageclass.yaml
|
||||||
4
storage/namespace.yaml
Normal file
4
storage/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: nfs-provisioner
|
||||||
20
storage/rbac/clusterrole.yaml
Normal file
20
storage/rbac/clusterrole.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: nfs-client-provisioner-runner
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["persistentvolumes"]
|
||||||
|
verbs: ["get", "list", "watch", "create", "delete"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["persistentvolumeclaims"]
|
||||||
|
verbs: ["get", "list", "watch", "update"]
|
||||||
|
- apiGroups: ["storage.k8s.io"]
|
||||||
|
resources: ["storageclasses"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["events"]
|
||||||
|
verbs: ["create", "update", "patch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["endpoints"]
|
||||||
|
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||||
12
storage/rbac/clusterrolebinding.yaml
Normal file
12
storage/rbac/clusterrolebinding.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: run-nfs-client-provisioner
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: nfs-client-provisioner
|
||||||
|
namespace: nfs-provisioner
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: nfs-client-provisioner-runner
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
5
storage/rbac/serviceaccount.yaml
Normal file
5
storage/rbac/serviceaccount.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: nfs-client-provisioner
|
||||||
|
namespace: nfs-provisioner
|
||||||
17
storage/readme.md
Normal file
17
storage/readme.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# k8s-storage
|
||||||
|
|
||||||
|
Este m<>dulo despliega un driver de almacenamiento din<69>mico basado en NFS, apuntando a un servidor ZFS (`niflheim`, 192.168.1.10) con la ruta `/mnt/storage/k8s`.
|
||||||
|
|
||||||
|
## Componentes incluidos
|
||||||
|
|
||||||
|
- Namespace `nfs-provisioner`
|
||||||
|
- RBAC necesario
|
||||||
|
- Deployment del provisioner din<69>mico
|
||||||
|
- StorageClass predeterminado `nfs-manabo`
|
||||||
|
|
||||||
|
## C<>mo aplicar
|
||||||
|
|
||||||
|
kubectl apply -f namespace.yaml
|
||||||
|
kubectl apply -f rbac/
|
||||||
|
kubectl apply -f deployment/
|
||||||
|
kubectl apply -f storageclass/
|
||||||
9
storage/storageclass/storageclass.yaml
Normal file
9
storage/storageclass/storageclass.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: nfs-manabo
|
||||||
|
annotations:
|
||||||
|
storageclass.kubernetes.io/is-default-class: "true"
|
||||||
|
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
|
||||||
|
reclaimPolicy: Retain
|
||||||
|
volumeBindingMode: Immediate
|
||||||
16
traefik/configmaps/configmap.yaml
Normal file
16
traefik/configmaps/configmap.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: traefik-config
|
||||||
|
namespace: traefik
|
||||||
|
data:
|
||||||
|
traefik.yml: |
|
||||||
|
api:
|
||||||
|
dashboard: true
|
||||||
|
log:
|
||||||
|
level: DEBUG
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: ":80"
|
||||||
|
websecure:
|
||||||
|
address: ":443"
|
||||||
28
traefik/deployments/deployment.yaml
Normal file
28
traefik/deployments/deployment.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
namespace: traefik
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: traefik
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: traefik
|
||||||
|
spec:
|
||||||
|
serviceAccountName: traefik
|
||||||
|
containers:
|
||||||
|
- name: traefik
|
||||||
|
image: traefik:v3.0
|
||||||
|
args:
|
||||||
|
- --configFile=/config/traefik.yml
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /config
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: traefik-config
|
||||||
32
traefik/ingress/ingress.yaml
Normal file
32
traefik/ingress/ingress.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: traefik-dashboard
|
||||||
|
namespace: traefik
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
kubernetes.io/ingress.class: traefik
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- traefik.manabo.org
|
||||||
|
secretName: traefik-dashboard-tls
|
||||||
|
rules:
|
||||||
|
- host: traefik.manabo.org
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /dashboard
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: traefik
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- path: /api
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: traefik
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
6
traefik/ingressclass.yaml
Normal file
6
traefik/ingressclass.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: IngressClass
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/ingress-controller
|
||||||
11
traefik/kustomization.yaml
Normal file
11
traefik/kustomization.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace: traefik
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- rbac/serviceaccount.yaml
|
||||||
|
- rbac/clusterrole.yaml
|
||||||
|
- rbac/clusterrolebinding.yaml
|
||||||
|
- configmaps/configmap.yaml
|
||||||
|
- deployments/deployment.yaml
|
||||||
|
- services/service.yaml
|
||||||
|
- ingressclass.yaml
|
||||||
|
- ingress/ingress.yaml
|
||||||
4
traefik/namespace.yaml
Normal file
4
traefik/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
62
traefik/rbac/clusterrole.yaml
Normal file
62
traefik/rbac/clusterrole.yaml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- configmaps
|
||||||
|
- endpoints
|
||||||
|
- nodes
|
||||||
|
- pods
|
||||||
|
- secrets
|
||||||
|
verbs:
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- nodes
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- services
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- networking.k8s.io
|
||||||
|
resources:
|
||||||
|
- ingresses
|
||||||
|
- ingressclasses
|
||||||
|
- ingresses/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- coordination.k8s.io
|
||||||
|
resources:
|
||||||
|
- leases
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- create
|
||||||
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- pods
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- apiGroups:
|
||||||
|
- discovery.k8s.io
|
||||||
|
resources:
|
||||||
|
- endpointslices
|
||||||
|
verbs:
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
12
traefik/rbac/clusterrolebinding.yaml
Normal file
12
traefik/rbac/clusterrolebinding.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: traefik
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: traefik
|
||||||
|
namespace: traefik
|
||||||
5
traefik/rbac/serviceaccount.yaml
Normal file
5
traefik/rbac/serviceaccount.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
namespace: traefik
|
||||||
16
traefik/services/service.yaml
Normal file
16
traefik/services/service.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
namespace: traefik
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer # <-- ¡Esto es lo importante con MetalLB!
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
name: web
|
||||||
|
targetPort: 80
|
||||||
|
- port: 443
|
||||||
|
name: websecure
|
||||||
|
targetPort: 443
|
||||||
|
selector:
|
||||||
|
app: traefik
|
||||||
Reference in New Issue
Block a user