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