php-docker-template icon indicating copy to clipboard operation
php-docker-template copied to clipboard

Document Docker on k8s specifics

Open renatomefi opened this issue 6 years ago • 2 comments

Context

There are too many things to consider when deploying a PHP Docker setup in Kubernetes, many of them related to good practices and others due to how PHP is designed, the intent of this issue is to list all of them and match whether we have both solved the issue and documented it.

THE list

  • Starting with Docker best practices
    • [ ] Package a single app per container
    • [ ] Properly handle PID 1, signal handling, and zombie processes
      • [ ] PHP Cli doesn't come with pcntl by default. Which means SIGTERM and SIGINT will be ignored and the process will die non gracefully, also the application must know how to deal with the signal
      • [ ] PHP-FPM doesn't adhere to the standard posix signals IPC, where it'll terminate immediately upon SIGTERM and SIGINT
    • [ ] Optimize for the Docker build cache - Done in the official image
    • [ ] Remove unnecessary tools - I.e.: https://github.com/usabilla/php-docker-template/blob/7fd241a1f93c25eae3cf26f2d23d3a4b2d97e56f/Dockerfile-fpm#L20-L21
    • [ ] Build the smallest image possible - Same as above
    • [ ] Use vulnerability scanning in Container Registry
      • [ ] How to patch those images?
      • [ ] Patch older versions of the image
    • [ ] Properly tag your images
    • [ ] Carefully consider whether to use a public image
  • Nginx and PHP-FPM, after handling signals correctly, let's understand the relationship of those components.
    • [ ] Does the Nginx process finishes before the PHP-FPM one? I.e: A k8s preStop which checks if the Nginx is dead before PHP-FPM:
 # Considering you have a mount between the nginx and php-fpm containers on `/var/run`
          lifecycle:
            preStop:
              exec:
                command: ["/bin/sh","-c","while test -e /var/run/nginx.pid; do sleep 1; done"]
  • [ ] Does Nginx need access to the code? When serving static files, you could for instance have another deployment only for that, which doesn't have you php files
  • How do they communicate, advantages and disavantages of:
    • [ ] Via TCP connection
    • [ ] Via socket while running both in the same container
    • [ ] Via socket while running in different containers
  • [ ] Test the relationship between the services
  • On the best practices for operating containers, probing:
    • [ ] Should you warm up the cache of the application? I.e.: Opcode cache as file
    • [ ] Readiness probe for a non-interactive (CLI) container
    • [ ] Liveness probe for a non-interactive (CLI) container
    • [ ] Readiness probe for a PHP-FPM container - I.e.: https://github.com/renatomefi/php-fpm-healthcheck
    • [ ] Liveness probe for a PHP-FPM container - I.e.: https://github.com/renatomefi/php-fpm-healthcheck
  • Observability, logging and monitoring
    • [ ] Logging to stdout and stderr
    • [ ] Log format
    • [ ] PHP-FPM prefixes all stdout with WARNING: [pool www] child 12 said into stdout :. 7.3 has a fix for that, but what to do with 7.2? https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.fpm
    • [ ] Produce metrics
    • [ ] Make it possible to scrape or push metrics, is it non-blocking?
  • Containers
    • [ ] Avoid privileged containers
    • [ ] Avoid running as root
    • [ ] Stateless
  • Best practices for writing Dockerfiles
    • [ ] Lint the Dockerfile - I.e.: https://github.com/usabilla/php-docker-template/blob/436042eafea36d98aa8e2f86084266c34c61a33c/Makefile#L67-L68

renatomefi avatar Apr 17 '19 07:04 renatomefi

Regarding the communication between containers, perhaps also note that Unix socket communication does not need to be bound to the filesystem on Linux (search for "abstract" in http://man7.org/linux/man-pages/man7/unix.7.html). This will even work between containers in the same pod, because the abstract socket namespace is part of the network namespace. Sharing a volume between containers with a socket file is actually unnecessary for this case.

I'm not certain whether both nginx and PHP support using abstract socket names, however.

Also, contrasting "socket" with TCP here is misleading, as TCP sockets are also sockets. The appropriate terminology is "Unix domain socket", or just "Unix socket" for short.

stevenjm avatar Apr 17 '19 10:04 stevenjm

/cc @tomoki1337

azjezz avatar Apr 23 '19 15:04 azjezz