Home > Back-end >  Kubernetes Nginx container unable to access php-fpm container
Kubernetes Nginx container unable to access php-fpm container

Time:07-19

I've created 2 Kubernetes deployments for nginx and a php-fpm laravel container. But for some reason, traffic from nginx seems unable to successfully get to the php-fpm containers generating the following error

172.18.0.1 - - [18/Jul/2022:16:51:10  0000] "GET / HTTP/1.1" 404 555 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"

This is my deployment file

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-server-config
  namespace: dev-api
data:
  nginx.conf: |
    server {
        listen 80;
        index index.php index.html;
        error_log  /var/log/nginx/error.log;
        access_log /var/log/nginx/access.log;
        root /var/www/html/public;

        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(. \.php)(/. )$;

            fastcgi_pass api-web-svc:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location / {
            try_files $uri $uri/ /index.php?$query_string;
                gzip_static on;
        }
    }
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: php-config
  namespace: dev-api
data:
  laravel.ini: |
    upload_max_filesize: 80M
    post_max_size: 80M
---
apiVersion: v1
kind: Secret
metadata:
  name: api-web-secret
  namespace: dev-api
type: Opaque
data:
 ...
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-web
  namespace: dev-api
spec:
  selector:
    matchLabels:
      app: api-web
  replicas: 1
  template:
    metadata:
      labels:
        app: api-web
    spec:
      containers:
      - name: api-web
        image: XXX.dkr.ecr.us-east-1.amazonaws.com/api-web:0.9.4-alpha
        volumeMounts:
         - name: php-config
           mountPath: /usr/local/etc/php/conf.d/laravel.ini
         - name: env-config
           mountPath: /var/www/html/.env
        ports:
        - containerPort: 9000
      volumes:
        - name: php-config
          configMap:
            name: php-config
        - name: env-config
          secret:
            secretName: api-web-secret
      imagePullSecrets:
      - name: regcred  
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: dev-api
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        volumeMounts:
         - name: web-server-config
           mountPath: /etc/nginx/conf.d/
        ports:
        - containerPort: 80
      volumes:
        - name: web-server-config
          configMap:
            name: web-server-config 
---
apiVersion: v1
kind: Service
metadata:
  name:  web-server-svc
  namespace: dev-api
spec:
  type: NodePort
  selector:
    app:  nginx
  ports:
  - protocol: TCP
    port:  80
    targetPort:  80
    nodePort: 32420
---
apiVersion: v1
kind: Service
metadata:
  name:  api-web-svc
  namespace: dev-api
  labels:
    app: api-web
spec:
  type: ClusterIP
  selector:
    app:  api-web
  ports:
  - protocol: TCP
    port:  9000

The namespace is declared separately. The two containers in each of the deployments run successfully.

k logs deployment/nginx-deployment  -n dev-api
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/07/18 16:18:50 [notice] 1#1: using the "epoll" event method
2022/07/18 16:18:50 [notice] 1#1: nginx/1.21.6
2022/07/18 16:18:50 [notice] 1#1: built by gcc 10.3.1 20211027 (Alpine 10.3.1_git20211027) 
2022/07/18 16:18:50 [notice] 1#1: OS: Linux 5.4.0-109-generic
2022/07/18 16:18:50 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/07/18 16:18:50 [notice] 1#1: start worker processes
2022/07/18 16:18:50 [notice] 1#1: start worker process 21
2022/07/18 16:18:50 [notice] 1#1: start worker process 22
2022/07/18 16:18:50 [notice] 1#1: start worker process 23
2022/07/18 16:18:50 [notice] 1#1: start worker process 24
2022/07/18 16:18:50 [notice] 1#1: start worker process 25
2022/07/18 16:18:50 [notice] 1#1: start worker process 26
2022/07/18 16:18:50 [notice] 1#1: start worker process 27
2022/07/18 16:18:50 [notice] 1#1: start worker process 28
 k logs deployment/api-web -n dev-api
[18-Jul-2022 16:18:51] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
[18-Jul-2022 16:18:51] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
[18-Jul-2022 16:18:51] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
[18-Jul-2022 16:18:51] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
[18-Jul-2022 16:18:51] NOTICE: fpm is running, pid 1
[18-Jul-2022 16:18:51] NOTICE: ready to handle connections

And the Dockerfile used to generate the image api-web:0.9.4-alpha in the api-web deployment is as shown below

FROM php:7.2-fpm

# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/html/

# Set working directory
WORKDIR /var/www/html

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl \
    nodejs \
    npm

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory contents
COPY . /var/www/html/

# Copy existing application directory permissions
COPY --chown=www:www . /var/www/html/

# Change current user to www
USER www

## Run composer dependencies
RUN composer update
RUN composer install

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

This Dockerfile runs fine too, with no issues. A docker-compose file using this image also works with no issues.

Any ideas why traffic from the nginx-deployment container fails to reach the api-web php-fpm container with the error

172.18.0.1 - - [18/Jul/2022:16:51:10  0000] "GET / HTTP/1.1" 404 555 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"

CodePudding user response:

As far as I know both pods or at least the containers need the same source files. If the nginx doesn't know that this php files exists, it can not forward the request to the php-fpm container.

I'm saying container, while i wouldn't recommend to split the nginx and php-fpm into separate pods. More likely i would start those containers as one unit with the same source in one pod. Except you have some sort of Cron jobs or batch jobs.

CodePudding user response:

i would suggest maintaining both containers in a single POD if using the php-fpm

apiVersion: extensions/v1
kind: Deployment
metadata:
  labels:
    app: wordpress-site
  name: wordpress-site
  namespace: development
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: wordpress-site
      tier: frontend
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: wordpress-site
        tier: frontend
    spec:
      volumes:
      - configMap:
          defaultMode: 256
          name: nginxthroughpass
          optional: false
        name: nginxconf
      - name: shared-files
        emptyDir: {}
      containers:
        - name: app
          image: <REPLACE WITH DOCKER PHP-FPM IMAGE URL>
          imagePullPolicy : IfNotPresent
          volumeMounts:
            - name: shared-files
              mountPath: /var/www/html
          envFrom:
            - configMapRef:
                name: wordpress-configmap
        - name: nginx
          image: nginx
          imagePullPolicy : IfNotPresent
          volumeMounts:
          - name: shared-files
            mountPath: /var/www/html
          - mountPath: /etc/nginx/conf.d
            name: nginxconf
            readOnly: true

Repo for ref : https://github.com/harsh4870/Kubernetes-wordpress-php-fpm-nginx

If you don't want to run nginx controller you can also use the Nginx ingress to forward the traffic to php-fpm container

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "FCGI"
    nginx.ingress.kubernetes.io/fastcgi-index: "index.php"
    nginx.ingress.kubernetes.io/fastcgi-params-configmap: "configmap"
  name: example-app
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              name: fastcgi
  • Related