Tutoriales

Desplegar nginx en Kubernetes 

nginx es un servidor web/proxy inverso bastante ligero y de alto rendimiento de código abierto, que con el tiempo ha ido creciendo como caché de HTTP, balanceador de carga, y también como proxy de correo electrónico. Su potencial está en ser capaz de trabajar con gran cantidad de conexiones a gran velocidad, algo que hace que posea el 20% de la cuota de mercado de servidores web.

Su funcionamiento se basa en no crear procesos nuevos para cada solicitud web que recibe, sino que hace uso de un enfoque asincrónico basado en eventos, donde se trabaja con las solicitudes en un solo hilo.

Como podremos suponer, su interés es enorme, así que vamos a ver cómo podemos desplegar nginx mediante un contenedor de Kubernetes.

Elección de imagen Docker 

Existen varias opciones disponibles, pero las dos más extendidas son las siguientes: 

nginx

Esta imagen de Docker Hub es la genérica y principal. Si disponemos de un entorno con orquestación sobre Docker, ésta será la mejor opción para poder trabajar puesto que es la más sencilla de usar. En cambio, si usamos Kubernetes esta imagen puede darnos varios problemas, sobre todo por permisos trabajando en entornos Openshift. 

En este último caso, ninguna imagen puede ejecutarse sobre usuarios root, y por defecto la imagen nginx se ejecuta sobre root. Aparte, su fichero de configuración inicial utiliza el puerto 80, el cual ya no estará disponible puesto que necesitamos permisos de usuario para poder utilizarlo. 

bitnami/nginx 

Esta imagen viene preconfigurada para poder ejecutar sobre entornos Kubernetes y gracias a su configuración por defecto, es perfecta para entornos Openshift.

Para esta entrada, vamos a centrarnos en esta imagen.

Configuración de bitnami/nginx

Partiremos de la imagen «bitnami/nginx:latest». Podemos ejecutarla de manera sencilla con el siguiente comando: 

Docker run --name nginx -p 8080:8080 bitnami/nginx:latest 

Al acceder a la url «http://localhost:8080» veremos nuestra página de inicio de nginx: 

Para poder crear nuestras configuraciones, deberemos crear nuestro archivo «nginx.conf» y montarlo sobre nuestra contenedor. Tenemos varias opciones: 

Modificando la configuración por defecto (nginx.conf) 

Podemos modificar la configuración por defecto de nuestro servidor nginx modificando el fichero principal «nginx.conf» situado en «/opt/bitnami/nginx/conf/nginx.conf».

Este fichero por defecto tiene un contenido parecido a este: 

# Based on https://www.nginx.com/resources/wiki/start/topics/examples/full/#nginx-conf 

# user              www www;  ## Default: nobody 
 

worker_processes  auto; 
error_log         "/opt/bitnami/nginx/logs/error.log"; 
pid               "/opt/bitnami/nginx/tmp/nginx.pid"; 
 
events { 
    worker_connections  1024; 
} 
 
http { 
    include       mime.types; 
    default_type  application/octet-stream; 
    log_format    main '$remote_addr - $remote_user [$time_local] ' 
                       '"$request" $status  $body_bytes_sent "$http_referer" ' 
                       '"$http_user_agent" "$http_x_forwarded_for"'; 
    access_log    "/opt/bitnami/nginx/logs/access.log"; 
    add_header    X-Frame-Options SAMEORIGIN; 
 
    client_body_temp_path  "/opt/bitnami/nginx/tmp/client_body" 1 2; 
    proxy_temp_path        "/opt/bitnami/nginx/tmp/proxy" 1 2; 
    fastcgi_temp_path      "/opt/bitnami/nginx/tmp/fastcgi" 1 2; 
    scgi_temp_path         "/opt/bitnami/nginx/tmp/scgi" 1 2; 
    uwsgi_temp_path        "/opt/bitnami/nginx/tmp/uwsgi" 1 2; 
 
    sendfile           on; 
    tcp_nopush         on; 
    tcp_nodelay        off; 
    gzip               on; 
    gzip_http_version  1.0; 
    gzip_comp_level    2; 
    gzip_proxied       any; 
    gzip_types         text/plain text/css application/javascript text/xml application/xml+rss; 
    keepalive_timeout  65; 
    ssl_protocols      TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; 
    ssl_ciphers        HIGH:!aNULL:!MD5; 
    client_max_body_size 80M; 
    server_tokens off; 
 
    include  "/opt/bitnami/nginx/conf/server_blocks/*.conf"; 
 
    # HTTP Server 
    server { 
        # Port to listen on, can also be set in IP:PORT format 
        listen  8080; 
 
        include  "/opt/bitnami/nginx/conf/bitnami/*.conf"; 
 
        location /status { 
            stub_status on; 
            access_log   off; 
            allow 127.0.0.1; 
            deny all; 
        } 
    } 
} 

Como podemos observar en el archivo, dentro de http tenemos la instrucción «include» de todos los fichero localizados en el path «/opt/bitnami/nginx/conf/server_blocks/*.conf» y también podemos incluir diferentes location automáticamente al server principal localizado en el puerto 8080 añadiendo los ficheros sobre la ruta «/opt/bitnami/nginx/conf/bitnami/*.conf».

Añadiendo location al server por defecto 

Se pueden añadir diferentes location simplemente añadiendo ficheros a la ruta «/opt/bitnami/nginx/conf/bitnami/*.conf». Un ejemplo podría ser el siguiente: 

my_server.conf 
location /my-endpoint { 

proxy_pass http://my-service:8080; 

proxy_set_header X-request_uri "$request_uri"; 

proxy_set_header Host $http_host; 

proxy_read_timeout 120; 

} 

Este archivo se colocaría en «/opt/bitnami/nginx/conf/bitnami/my_server.conf» y automáticamente al inicio nos redirigirá al servicio seleccionado al acceder a la url:

http://localhost:8080/my-endpoint 

Añadiendo diferentes servidores (server_blocks

Para poder añadir diferentes «server_blocks», si mantenemos el fichero de configuración original «nginx.conf», podemos crear los diferentes servidores creando diferentes archivo en la ruta «/opt/bitnami/nginx/conf/server_blocks/*.conf». Un ejemplo sería el siguiente: 

my_server_block.conf  
server { 

  listen 8443; 
  server_name "dev-caregiver.cwbyminsait.com"; 
  add_header Strict-Transport-Security "max-age=31536000" always; 
  location /my-endpoint { 
    proxy_pass http://my-service:8080; 
    proxy_set_header X-request_uri "$request_uri"; 
    proxy_set_header Host $http_host; 
    proxy_read_timeout 120; 

  }
}

Este archivo se colocaría en «/opt/bitnami/nginx/conf/server_blocks/my_server_block.conf» y automáticamente al inicio creará un nuevo puerto vinculado a este nuevo server. Ahora podríamos acceder a este nuevo endpoint a través de la ruta:

http://localhost:8443/my-endpoint  

Como desplegar bitnami/nginx en Kubernetes 

Primero necesitaremos crear un nuevo deployment

kind: Deployment 
apiVersion: apps/v1 
metadata: 
  name: nginx-balancer 
  labels: 
    app: nginx-balancer 
    app.kubernetes.io/name: nginx-balancer 
    app.kubernetes.io/instance: nginx-balancer 
    app.kubernetes.io/component: nginx-proxy 
    app.kubernetes.io/part-of: nginx-balancer 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: nginx-balancer 
  template: 
    metadata: 
      labels: 
        app: nginx-balancer 
    spec: 
      containers: 
        - resources: 
            limits: 
              cpu: 100m 
              memory: 250Mi 
            requests: 
              cpu: 50m 
              memory: 50Mi 
          readinessProbe: 
            tcpSocket: 
              port: 8080 
            initialDelaySeconds: 20 
            timeoutSeconds: 5 
            periodSeconds: 10 
            successThreshold: 2 
            failureThreshold: 3 
          livenessProbe: 
            httpGet: 
              path: / 
              port: 8080 
              scheme: HTTP 
            initialDelaySeconds: 20 
            timeoutSeconds: 5 
            periodSeconds: 10 
            successThreshold: 1 
            failureThreshold: 5 
          name: nginx-balancer 
          ports: 
            - name: 8443tcp84432 
              containerPort: 8443 
              protocol: TCP 
            - name: 8080tcp8080 
              containerPort: 8080 
              protocol: TCP 
          imagePullPolicy: Always 
          image: 'bitnami/nginx:latest' 
      restartPolicy: Always

De esta manera ya tenemos creado nuestro deployment original y podemos empezar a añadir nuestros bloques servidor y los diferentes location que queramos. 

Para crear el bloque server debemos crear un volume y vincularlo hacia la ruta «/opt/bitnami/nginx/conf/server_blocks». Para ello, primero se creará un «Config Map» que después montaremos sobre el anterior deployment.

kind: ConfigMap 
apiVersion: v1 
metadata: 
  name: server-block-map 
data: 
  my_server_block.conf: | 
    ########################### SERVER BLOCK #################### 
 
    server { 
        listen 8443; 
        add_header Strict-Transport-Security "max-age=31536000" always; 
 
        location /my-endpoint { 
            proxy_pass http://my-service:8080; 
            proxy_set_header X-request_uri "$request_uri"; 
            proxy_set_header Host $http_host; 
            proxy_read_timeout 120; 
        } 
    } 
  other_server_block.conf: | 
    ######### OTHER SERVER #######....

Después deberemos realizar lo siguientes cambios sobre nuestro deployment original:

  1. Añadir nuestro volume desde el Config Map.
  2. Montar el volume sobre el directorio de servers.

... 
spec: 
  ... 
  template: 
    ... 
    spec: 
      volumes: 
        - name: config-servers 
          configMap: 
            name: server-block-map 
            defaultMode: 484 
      containers: 
        ... 
        volumeMounts: 
          - name: config-servers 
            mountPath: /opt/bitnami/nginx/conf/server_blocks 

De esta manera ya tendremos configurado nuestro servicio nginx. Podremos comprobarlo accediendo al contenedor nginx y realizando una petición a:

http://localhost:8443/my-endpoint 

Fácil y sencillo, ¿verdad? Si os surge alguna duda, dejadnos un comentario.

✍🏻 Author(s)

Deja una respuesta