User Tools

Site Tools


informatica:linux:docker:kubernetes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
informatica:linux:docker:kubernetes [2022/06/25 08:14] – [Cluster externo Glusterfs] javiinformatica:linux:docker:kubernetes [2022/07/09 17:52] – [Nginx NodePort daemonset (usar este)] javi
Line 529: Line 529:
 Resumen de máquinas, nombres, IPs, etc. (las IPs públicas están cambiadas) Resumen de máquinas, nombres, IPs, etc. (las IPs públicas están cambiadas)
  
-^ DNS ^ IP privada ^ IP pública ^ Comentario ^+^ DNS ^ IP pública ^ IP privada ^ Comentario ^
 | k8s.legido.com  | 1.2.3.4 | 10.0.0.194 | Balanceador de carga. Escucha (listener) puerto 6443 | | k8s.legido.com  | 1.2.3.4 | 10.0.0.194 | Balanceador de carga. Escucha (listener) puerto 6443 |
 | k8s1 | 1.2.3.5 | 10.0.0.2 | Primer control plane | | k8s1 | 1.2.3.5 | 10.0.0.2 | Primer control plane |
-| k8s2 | 1.2.3.6 | 10.0.0.| Segundo control plane | +| k8s2 | 1.2.3.6 | 10.0.0.| Segundo control plane | 
-| k8s3 | 1.2.3.7 | 10.0.0.| Tercer control plane |+| k8s3 | 1.2.3.7 | 10.0.0.| Tercer control plane |
  
 ==== Load balancer ==== ==== Load balancer ====
Line 1269: Line 1269:
  
   * IPs privadas de los workers del clúster   * IPs privadas de los workers del clúster
-  * Puertos en los que escuchan los Nodeport tanto HTTP como HTTPS. Ver paso 8 de [[informatica:linux:docker:kubernetes#nginx_nodeport_con_afinitty_usar_este|Nginx ingress Nodeport con affinity]]+  * Puertos en los que escuchan los Nodeport tanto HTTP como HTTPS. Ver paso 8 de [[informatica:linux:docker:kubernetes#nginx_nodeport_daemonset_usar_este|Nginx ingress Nodeport daemonset]]
   * [[https://docs.docker.com/engine/install/debian|Docker]]   * [[https://docs.docker.com/engine/install/debian|Docker]]
  
Line 1585: Line 1585:
 [[https://kubernetes.github.io/ingress-nginx|Ingress nginx]] [[https://kubernetes.github.io/ingress-nginx|Ingress nginx]]
  
-==== Nginx NodePort con afinitty (usar este) ====+==== Nginx NodePort daemonset (usar este) ====
  
 Con este procedimiento podremos obtener la IP de origen en los pods, con las otras aproximaciones todavía no lo he conseguido. Con este procedimiento podremos obtener la IP de origen en los pods, con las otras aproximaciones todavía no lo he conseguido.
Line 1591: Line 1591:
 Características: Características:
  
-  * Usaremos [[https://kubernetes.io/docs/concepts/services-networking/service/#nodeport|NodePort]], de forma que todos los nodos, incluidos el master, expondrán a la DMZ un puerto para HTTP (el mismo en todos los nodos), y otro para HTTPS +  * Usaremos [[https://kubernetes.io/docs/concepts/services-networking/service/#nodeport|NodePort]], de forma que todos los nodos, incluidos el master, expondrán a la DMZ un puerto para HTTP (el mismo en todos los nodos), y otro para HTTPS. 
-  * Usaremos "replicas" para crear al menos un servicio (ingress control) por cada nodo worker, en este ejemplo 3+  * Usaremos daemonset, de forma que por cada nodo worker, en este ejemplo 3, se creará un pod.
   * Usaremos "externalTrafficPolicy: Local" para preservar la IP origen. La explicación detallada se puede encontrar [[https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/|aquí]] y [[https://kubernetes.io/docs/tutorials/services/source-ip/|aquí]]   * Usaremos "externalTrafficPolicy: Local" para preservar la IP origen. La explicación detallada se puede encontrar [[https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/|aquí]] y [[https://kubernetes.io/docs/tutorials/services/source-ip/|aquí]]
-  * La contrapartida a la regla anterior es que usaremos [[https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity|Affinity]] para que en la medida de lo posible haya un pod de tipo nginx ingress controller corriendo en cada node worker que esté vivo 
  
 1. Conectarse al master 1. Conectarse al master
Line 1600: Line 1599:
   ssh k8s2   ssh k8s2
  
-2. Obtener el [[https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal|archivo]]:+2. Obtener el [[https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters|archivo]]:
  
-  wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.46.0/deploy/static/provider/baremetal/deploy.yaml +  wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml
- +
-3. Añadir réplicas, tantas como worker nodes, en este ejemplo 3. Editar: +
- +
-  vim deploy.yaml +
-   +
-Y añadir 'spec.replicas: 3', cambiando: +
- +
-<code> +
-# Source: ingress-nginx/templates/controller-deployment.yaml +
-apiVersion: apps/v1 +
-kind: Deployment +
-metadata: +
-  labels: +
-    helm.sh/chart: ingress-nginx-3.30.0 +
-    app.kubernetes.io/name: ingress-nginx +
-    app.kubernetes.io/instance: ingress-nginx +
-    app.kubernetes.io/version: 0.46.0 +
-    app.kubernetes.io/managed-by: Helm +
-    app.kubernetes.io/component: controller +
-  name: ingress-nginx-controller +
-  namespace: ingress-nginx +
-spec: +
-</code> +
- +
-Por: +
- +
-<code> +
-# Source: ingress-nginx/templates/controller-deployment.yaml +
-apiVersion: apps/v1 +
-kind: Deployment +
-metadata: +
-  labels: +
-    helm.sh/chart: ingress-nginx-3.30.0 +
-    app.kubernetes.io/name: ingress-nginx +
-    app.kubernetes.io/instance: ingress-nginx +
-    app.kubernetes.io/version: 0.46.0 +
-    app.kubernetes.io/managed-by: Helm +
-    app.kubernetes.io/component: controller +
-  name: ingress-nginx-controller +
-  namespace: ingress-nginx +
-spec: +
-  # Tantas replicas como node worker +
-  replicas: 3 +
-</code>+
      
-4. Forzar que los pods solo envien tráfico a los deployments, según su ingress route, que estén corriendo en el mismo worker node. Añadir 'spec.externalTrafficPolicy: Local'. Editar:+3. Forzar que los pods solo envien tráfico a los deployments, según su ingress route, que estén corriendo en el mismo worker node. Añadir 'spec.externalTrafficPolicy: Local'. Editar:
  
   vim deploy.yaml   vim deploy.yaml
Line 1694: Line 1649:
 </code> </code>
  
-5Forzar que solo haya un pod de tipo nginx ingress controller corriendo en cada worker nodey que no levante ninguno de esos pods en los control plane. Lo hacemos añadiendo la clave 'spec.template.spec.affinity'. Editar: +4**AVISO** En la última versión ya es "NodePort"pero dejo esto documentado por si Ascaso
- +
-  vim deploy.yml +
-   +
-Y cambiar: +
- +
-<code> +
-# Source: ingress-nginx/templates/controller-deployment.yaml +
-apiVersion: apps/v1 +
-kind: Deployment +
-metadata: +
-  labels: +
-    helm.sh/chart: ingress-nginx-3.30.0 +
-    app.kubernetes.io/name: ingress-nginx +
-    app.kubernetes.io/instance: ingress-nginx +
-    app.kubernetes.io/version: 0.46.0 +
-    app.kubernetes.io/managed-by: Helm +
-    app.kubernetes.io/component: controller +
-  name: ingress-nginx-controller +
-  namespace: ingress-nginx +
-spec: +
-  # We need one pod running on each node +
-  replicas: 3 +
-  selector: +
-    matchLabels: +
-      app.kubernetes.io/name: ingress-nginx +
-      app.kubernetes.io/instance: ingress-nginx +
-      app.kubernetes.io/component: controller +
-  revisionHistoryLimit: 10 +
-  minReadySeconds:+
-  template: +
-    metadata: +
-      labels: +
-        app.kubernetes.io/name: ingress-nginx +
-        app.kubernetes.io/instance: ingress-nginx +
-        app.kubernetes.io/component: controller +
-    spec: +
-</code> +
- +
-Por: +
- +
-<code> +
-# Source: ingress-nginx/templates/controller-deployment.yaml +
-apiVersion: apps/v1 +
-kind: Deployment +
-metadata: +
-  labels: +
-    helm.sh/chart: ingress-nginx-3.30.0 +
-    app.kubernetes.io/name: ingress-nginx +
-    app.kubernetes.io/instance: ingress-nginx +
-    app.kubernetes.io/version: 0.46.0 +
-    app.kubernetes.io/managed-by: Helm +
-    app.kubernetes.io/component: controller +
-  name: ingress-nginx-controller +
-  namespace: ingress-nginx +
-spec: +
-  # We need one pod running on each node +
-  replicas: 3 +
-  selector: +
-    matchLabels: +
-      app.kubernetes.io/name: ingress-nginx +
-      app.kubernetes.io/instance: ingress-nginx +
-      app.kubernetes.io/component: controller +
-  revisionHistoryLimit: 10 +
-  minReadySeconds:+
-  template: +
-    metadata: +
-      labels: +
-        app.kubernetes.io/name: ingress-nginx +
-        app.kubernetes.io/instance: ingress-nginx +
-        app.kubernetes.io/component: controller +
-    spec: +
-      affinity: +
-        # Prevent starting pod in a node which already have one pod started +
-        podAntiAffinity: +
-          requiredDuringSchedulingIgnoredDuringExecution: +
-          - labelSelector: +
-              matchExpressions: +
-              - key: app.kubernetes.io/component +
-                operator: In +
-                values: +
-                - controller +
-            topologyKey: kubernetes.io/hostname +
-        # Prevent starting pod in the master node +
-        nodeAffinity: +
-          requiredDuringSchedulingIgnoredDuringExecution: +
-            nodeSelectorTerms: +
-            - matchExpressions: +
-              - key: node-role.kubernetes.io/control-plane +
-                operator: DoesNotExist +
-</code>+
  
-6. Reemplazar para el tipo de balanceo para el servicio+Reemplazar para el tipo de balanceo para el servicio
  
   vim deploy.yml   vim deploy.yml
Line 1860: Line 1725:
 </code> </code>
  
-7. Instalar. Ejecutar:+5. Instalar. Ejecutar:
  
   kubectl apply -f deploy.yaml   kubectl apply -f deploy.yaml
  
-8. Probar+6. Probar
  
-8.1. Ejecutar:+6.1. Ejecutar:
  
   kubectl get pods \   kubectl get pods \
Line 1885: Line 1750:
 **IMPORTANTE**: debe haber al menos una réplica por cada node worker. **IMPORTANTE**: debe haber al menos una réplica por cada node worker.
  
-8.2. Verificar que efectivamente cada servicio (ingress controller) corre en un node worker distinto. Ejecutar:+6.2. Verificar que efectivamente cada servicio (ingress controller) corre en un node worker distinto. Ejecutar:
  
   kubectl get nodes   kubectl get nodes
Line 1909: Line 1774:
 Todo correcto, cada worker tiene al menos un pod corriendo. Todo correcto, cada worker tiene al menos un pod corriendo.
  
-8.3. Comprobar la versión. Ejecutar:+6.3. Comprobar la versión. Ejecutar:
  
 <code>   <code>  
Line 1930: Line 1795:
 </code> </code>
  
-9. Obtener los puertos expuestos. Esto es necesario para instalar y configura el edge router. Ejecutar:+7. Obtener los puertos expuestos. Esto es necesario para instalar y configura el edge router. Ejecutar:
  
   kubectl get services -n ingress-nginx --field-selector metadata.name=ingress-nginx-controller   kubectl get services -n ingress-nginx --field-selector metadata.name=ingress-nginx-controller
Line 1946: Line 1811:
   * HTTPS => 30893   * HTTPS => 30893
  
-10[[informatica:linux:docker:kubernetes#editar_configmaps_para_habilitar_use-proxy-protocol|Editar ConfigMaps para habilitar 'use-proxy-protocol']]+8**AVISO** Este paso está deprecated. Solo hay que hacerlo si se va a usar un edge router con balanceador capa 7. NO hay que hacerlo, eso lo hice en un primer intento. El balanceador que hay que poner en el edge router tiene que ser capa 4, por tanto NO hay que habilitar proxy protocol.
  
 +[[informatica:linux:docker:kubernetes#editar_configmaps_para_habilitar_use-proxy-protocol|Editar ConfigMaps para habilitar 'use-proxy-protocol']]
 +
 +==== Actualizar nginx ingress controller ====
 +
 +1. Comprobar si es posible una actualización
 +
 +1.1. Obtemer la versión actual del nginx ingress controller
 +
 +  kubectl describe daemonsets.apps -n ingress-nginx ingress-nginx-controller  | grep vers
 +
 +Resultado esperado similar a:
 +
 +<code>
 +                        app.kubernetes.io/version=1.2.0
 +</code>
 +
 +Por tanto la versión actual es "1.2.0"
 +
 +1.2. Determinar si hay una nueva versión:
 +
 +https://github.com/kubernetes/ingress-nginx#changelog
 +
 +La hay, "v1.2.1", compatible con las siguientes versiones de kubectl:
 +
 +<code
 +1.23, 1.22, 1.21, 1.20, 1.19
 +</code>
 +
 +1.3. Determinar la versión actual de kubectl:
 +
 +  kubectl version --short
 +
 +Resultado esperado similar a:
 +
 +<code>
 +Client Version: v1.24.2
 +Kustomize Version: v4.5.4
 +Server Version: v1.24.2
 +</code>
 +
 +Tenemos kubectl versión "1.24.x", que está por encima de "1.23", asumo que podemos ir hacia delante.
 +
 +2. Actualizar la versión de la imagen del daemonset (recordad que cambiamos el "Deployment" por "Daemonset")
 +
 +2.1. Comprobar que la imagen de docker (tag) existe, y obtener el SHA256, todo esto desde la máquina local
 +
 +  docker pull registry.k8s.io/ingress-nginx/controller:v1.2.1
 +
 +Resultado esperado similar a:
 +
 +<code>
 +v1.2.1: Pulling from ingress-nginx/controller
 +8663204ce13b: Pull complete 
 +897a18b2d257: Pull complete 
 +3cb02f360cf3: Pull complete 
 +2b63816a7692: Pull complete 
 +d61ce16aa3b6: Pull complete 
 +4391833fbf2c: Pull complete 
 +4f4fb700ef54: Pull complete 
 +bb397308bcd5: Pull complete 
 +803395581751: Pull complete 
 +153d402a7263: Pull complete 
 +c815f058cf7b: Pull complete 
 +a872540e4aca: Pull complete 
 +4972574251d0: Pull complete 
 +30197fe775a6: Pull complete 
 +b059831ea274: Pull complete 
 +Digest: sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8
 +Status: Downloaded newer image for registry.k8s.io/ingress-nginx/controller:v1.2.1
 +registry.k8s.io/ingress-nginx/controller:v1.2.1
 +</code>
 +
 +La imagen existe, y el SHA256 es:
 +
 +  sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8
 +
 +2.2. Limpieza
 +
 +  docker image rm registry.k8s.io/ingress-nginx/controller:v1.2.1
 +
 +3. (k8s server) Actualizar la versión de la imagen del daemonset (paso 1.2.) y el SHA256 (paso 2.1.)
 +
 +3.1. Actualizar el daemonset:
 +
 +<code>
 +kubectl set image daemonsets/ingress-nginx-controller \
 +  controller=registry.k8s.io/ingress-nginx/controller:v1.2.1@sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8 \
 +  -n ingress-nginx
 +</code>
 +
 +3.2. Verificar:
 +
 +  kubectl get pods -n ingress-nginx -o wide
 +
 +ETA: 3'
 +
 +Resultado esperado similar a:
 +
 +<code>
 +NAME                                   READY   STATUS      RESTARTS   AGE    IP            NODE
 +   NOMINATED NODE   READINESS GATES
 +ingress-nginx-admission-create-zxqvn   0/    Completed            139m   10.244.0.75   k8s1
 +   <none>           <none>
 +ingress-nginx-admission-patch-c9t4w    0/1     Completed            139m   10.244.0.74   k8s1
 +   <none>           <none>
 +ingress-nginx-controller-6thbj         1/    Running              2m8s   10.244.0.77   k8s1
 +   <none>           <none>
 +ingress-nginx-controller-tv9zd         1/    Running              63s    10.244.1.16   k8s3
 +   <none>           <none>
 +ingress-nginx-controller-zgfw5         1/    Running              95s    10.244.2.21   k8s2
 +   <none>           <none>
 +</code>
 ==== Nginx LoadBalancer ==== ==== Nginx LoadBalancer ====
  
Line 3242: Line 3219:
 ===== Persistentes ===== ===== Persistentes =====
  
-TODO+==== kadalu (usar este) ==== 
 + 
 +[[https://kadalu.io/docs/k8s-storage/devel/quick-start|Fuente]] 
 + 
 +1. Instalar cliente glusterfs. 
 + 
 +**TODO**: igual solo con el cliente mejor, pero así funciona 
 + 
 +  sudo apt install -y glusterfs-server 
 + 
 +2. Instalar kadalu 
 + 
 +  curl -fsSL https://github.com/kadalu/kadalu/releases/latest/download/install.sh | sudo bash -x 
 + 
 +Comprobar: 
 + 
 +  kubectl kadalu version 
 + 
 +Salida esperada similar a: 
 + 
 +<code> 
 +kubectl-kadalu plugin: 0.8.15 
 +</code> 
 + 
 +Listar pods: 
 + 
 +  kubectl get pods -n kadalu 
 + 
 +Salida esperada similar a: 
 + 
 +<code> 
 +NAME                          READY   STATUS    RESTARTS   AGE 
 +kadalu-csi-nodeplugin-h8nm8   3/    Running            74s 
 +kadalu-csi-nodeplugin-kfp5c   3/    Running            74s 
 +kadalu-csi-nodeplugin-sfgn9   3/    Running            74s 
 +kadalu-csi-provisioner-0      5/5     Running            63s 
 +operator-57b47b555f-h6gdm     1/    Running            75s 
 +</code> 
 + 
 +3. (En cada uno de los nodos de kubernetes) Crear directorio donde se almacenará el cluster de glusterfs 
 + 
 + sudo mkdir -p /opt/kadalu/brick1/gv1 
 + 
 +4. Crear el volumen del cluster de glusterfs 
 + 
 +<code> 
 +kubectl kadalu storage-add \ 
 +  storage-pool1 \ 
 +  --verbose \ 
 +  --type=Disperse \ 
 +  --data 2 \ 
 +  --redundancy 1 \ 
 +  --path k8s1:/opt/kadalu/brick1/gv1 \ 
 +  --path k8s2:/opt/kadalu/brick1/gv1 \ 
 +  --path k8s3:/opt/kadalu/brick1/gv1 
 +</code> 
 + 
 +Salida esperada similar a: 
 + 
 +<code> 
 +The following nodes are available: 
 +  k8s1, k8s2, k8s3 
 + 
 +Storage Yaml file for your reference: 
 + 
 +apiVersion: "kadalu-operator.storage/v1alpha1" 
 +kind: "KadaluStorage" 
 +metadata: 
 +  name: "storage-pool1" 
 +spec: 
 +  type: "Disperse" 
 +  storage: 
 +    - node: "k8s1" 
 +      path: "/opt/kadalu/brick1/gv1" 
 +    - node: "k8s2" 
 +      path: "/opt/kadalu/brick1/gv1" 
 +    - node: "k8s3" 
 +      path: "/opt/kadalu/brick1/gv1" 
 +  disperse: 
 +    data: 2 
 +    redundancy: 1 
 + 
 +Is this correct?(Yes/No): 
 +</code> 
 + 
 +Teclear "Yes" y pulsar "Enter" 
 + 
 +Salida esperada similar a: 
 + 
 +<code> 
 +Storage add request sent successfully 
 +kadalustorage.kadalu-operator.storage/storage-pool1 created 
 +</code> 
 + 
 +Listar pods: 
 + 
 +  kubectl get pods -n kadalu -o wide 
 + 
 +Salida esperada similar a: 
 + 
 +<code> 
 +NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE   READINESS GATES 
 +kadalu-csi-nodeplugin-h8nm8   3/    Running            15m   10.244.2.13   k8s2   <none>           <none> 
 +kadalu-csi-nodeplugin-kfp5c   3/    Running            15m   10.244.0.26   k8s1   <none>           <none> 
 +kadalu-csi-nodeplugin-sfgn9   3/    Running            15m   10.244.1.6    k8s3   <none>           <none> 
 +kadalu-csi-provisioner-0      5/5     Running            15m   10.244.0.25   k8s1   <none>           <none> 
 +operator-57b47b555f-h6gdm     1/    Running            15m   10.244.0.24   k8s1   <none>           <none> 
 +server-storage-pool1-0-0      1/1     Running            83s   10.244.0.27   k8s1   <none>           <none> 
 +server-storage-pool1-1-0      1/1     Running            82s   10.244.2.14   k8s2   <none>           <none> 
 +server-storage-pool1-2-0      1/1     Running            82s   10.244.1.7    k8s3   <none>           <none> 
 +</code> 
 + 
 +5. Repetir para cada pod: 
 + 
 +5.1. Crear PVC (Persistent Volume Claim): 
 + 
 +**IMPORTANTE**: la documentación dice que "storageClassName:" debe ser "kadalu.disperse", pero no, tiene que ser el nombre del volumen de glusterfs creado anteriormente. 
 + 
 +<code> 
 +cat <<EOF | kubectl apply -f - 
 +kind: PersistentVolumeClaim 
 +apiVersion: v1 
 +metadata: 
 +  name: persistent-volume-claim-1 
 +spec: 
 +  storageClassName: kadalu.storage-pool1 
 +  accessModes: 
 +    - ReadWriteMany 
 +  resources: 
 +    requests: 
 +      storage: 1Gi 
 +EOF 
 +</code> 
 + 
 +Un nuevo volumen persistente se ha creado: 
 + 
 +  kubectl get persistentvolume 
 + 
 +Salida esperada similar a: 
 + 
 +<code> 
 +NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                               STORAGECLASS           REASON   AGE 
 +pvc-5df9ed7d-e77d-4910-b73b-a6145efb9c96   1Gi        RWX            Delete           Bound    default/persistent-volume-claim-1   kadalu.storage-pool1            52s 
 +</code> 
 + 
 +Una nueva reclamación de volumen persistente se ha creado: 
 + 
 +  kubectl get persistentvolumeclaims 
 + 
 +Salida esperada similar a: 
 + 
 +<code> 
 +NAME                        STATUS   VOLUME                                     CAPACITY   ACCE 
 +SS MODES   STORAGECLASS           AGE 
 +persistent-volume-claim-1   Bound    pvc-5df9ed7d-e77d-4910-b73b-a6145efb9c96   1Gi        RWX 
 +           kadalu.storage-pool1   22s 
 +</code> 
 + 
 +5.2. Crear el pod referenciando la reclamación de volumen persistente: 
 + 
 +<code> 
 +cat <<EOF | kubectl apply -f - 
 +apiVersion: v1 
 +kind: Pod 
 +metadata: 
 +  name: nginx-test 
 +spec: 
 +  containers: 
 +    - name: nginx-test 
 +      image: nginx 
 +      volumeMounts: 
 +        - mountPath: "/usr/share/nginx/html" 
 +          name: nginx-test-volume 
 +  volumes: 
 +    - name: nginx-test-volume 
 +      persistentVolumeClaim: 
 +        claimName: persistent-volume-claim-1 
 +EOF 
 +</code> 
 + 
 +==== Usando glusterfs externo ==== 
 + 
 +Requisitos: 
 + 
 +  * Un [[informatica:linux:docker:kubernetes#cluster_externo_glusterfs|Cluster glusterfs]] funcionando. En este ejemplo los 3 nodos serán a la vez: 
 +    * Control Plane 
 +    * Workers 
 +    * Nodos del cluster glusterfs 
 + 
 + 
 +[[https://github.com/kubernetes/examples/tree/master/volumes/glusterfs|Fuente]] 
 + 
 +1. Crear endpoints 
 + 
 +  * "ip" es la IP de cada nodo. En nuestro caso es el mismo que los nodos de kubernetes 
 +  * "port" un número arbitrario, "1" es suficiente 
 + 
 +<code> 
 +cat <<EOF | kubectl apply -f - 
 +apiVersion: v1 
 +kind: Endpoints 
 +metadata: 
 +  name: glusterfs-cluster 
 +subsets: 
 +- addresses: 
 +  - ip: 10.0.0.2 
 +  ports: 
 +  - port: 1 
 +- addresses: 
 +  - ip: 10.0.0.3 
 +  ports: 
 +  - port: 1 
 +- addresses: 
 +  - ip: 10.0.0.4 
 +  ports: 
 +  - port: 1 
 +EOF 
 +</code> 
 + 
 +Comprobar: 
 + 
 +  kubectl get endpoints 
 + 
 +Resultado esperado similar a: 
 + 
 +<code> 
 +NAME                ENDPOINTS                          AGE 
 +glusterfs-cluster   10.0.0.2:1,10.0.0.3:1,10.0.0.4:  22s 
 +</code> 
 + 
 +2. Crear servicio 
 + 
 +<code> 
 +cat <<EOF | kubectl apply -f - 
 +apiVersion: v1 
 +kind: Service 
 +metadata: 
 +  name: glusterfs-cluster 
 +spec: 
 +  ports: 
 +  - port: 1 
 +EOF 
 +</code> 
 + 
 +Comprobar: 
 + 
 +  kubectl get services 
 + 
 +Resultado esperado similar a: 
 + 
 +<code> 
 +NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE 
 +glusterfs-cluster   ClusterIP   10.105.75.133    <none>        1/TCP     51s 
 +</code> 
 + 
 +3. Crear pod 
 + 
 +  * Campo "path" debe ser el nombre de un volumen de glusterfs **previamente** creado 
 + 
 +<code> 
 +cat <<EOF | kubectl apply -f - 
 +apiVersion: v1 
 +kind: Pod 
 +metadata: 
 +  name: glusterfs 
 +spec: 
 +  containers: 
 +  - name: glusterfs 
 +    image: nginx 
 +    volumeMounts: 
 +    - mountPath: "/usr/share/nginx/html" 
 +      name: glusterfsvol 
 +  volumes: 
 +  - name: glusterfsvol 
 +    glusterfs: 
 +      endpoints: glusterfs-cluster 
 +      path: gv1 
 +      readOnly: false 
 +EOF 
 +</code> 
 + 
 +Comprobar (puede tardar 1 minuto): 
 + 
 +  kubectl get pods 
 +   
 +Resultado esperado similar a: 
 + 
 +<code> 
 +NAME                                 READY   STATUS    RESTARTS   AGE 
 +glusterfs                            1/1     Running            13s 
 +</code> 
 +     
 +**Resumen**: 
 + 
 +  * El pod "glusterfs" tiene montado localmente un directorio, "/usr/share/nginx/html" 
 +  * En este directorio puede escribir 
 +  * Lo que escriba se escribirá en el volumen "gv1" del cluster glusterfs, que a su vez se escribirá en el brick "/opt/brick1/gv1" de cada uno de los nodos del cluster de glusterfs 
 +  * Se pueden montar más pods, o este mismo si se tiene que recrear (porque se arrancla con "replica 1" o similar), que escriban en ese volumen de glusterfs 
 + 
 +**TODO**: 
 + 
 +  * Nótese que la provisión de volúmenes de glusterfs NO es dinámica. Primero se crea manualmente el volumen de glusterfs y luego se referencia, manualmente, en el pod de kubernetes 
 +  * Parece ser que para que se pueda provisionar dinámicamente parece ser que se requiere Heketi, que es un proyecto que está de capa caída
  
-==== Cluster externo Glusterfs ====+=== Cluster externo Glusterfs ===
  
 Vamos a instalar un cluster de Glusterfs "externo", o como servicio, en lugar de montarlo como daemonset, que parece que requiere de un servicio (heketi) que no parece tener mucho futuro. Vamos a instalar un cluster de Glusterfs "externo", o como servicio, en lugar de montarlo como daemonset, que parece que requiere de un servicio (heketi) que no parece tener mucho futuro.