Anúncio

Scaleable PHP Applications in Kubernetes

Flownative CEO, Flow / Neos Project Founder em Flownative
27 de Oct de 2022
Anúncio

Mais conteúdo relacionado

Similar a Scaleable PHP Applications in Kubernetes(20)

Mais de Robert Lemke(20)

Anúncio

Scaleable PHP Applications in Kubernetes

  1. Scaleable PHP applications in Kubernetes Robert Lemke
  2. Robert Lemke Flownative Managing Partner Neos CMS Project Founder
  3. Robert Lemke Flownative Managing Partner Neos CMS Project Founder
  4. Intro | Discussion
  5. Should I use Kubernetes? it depends
  6. Automation and Developer Experience IaC GitOps agile DX UX
  7. Challenges security expertise complexity
  8. What does it take to run a PHP application in Kubernetes?
  9. Application Architecture
  10. Building Application Artifacts
  11. FROM scratch MAINTAINER Flownative <support@flownative.com> VOLUME /build COPY DistributionPackages /build/DistributionPackages COPY Packages/Framework /build/Packages/Framework COPY Packages/Libraries /build/Packages/Libraries COPY Packages/Application /build/Packages/Application COPY bin /build/bin COPY Web /build/Web COPY flow /build/flow COPY composer.json /build/composer.json COPY composer.lock /build/composer.lock COPY Configuration /build/Configuration COPY beach* /build/
  12. FROM scratch alpine:latest MAINTAINER Flownative <support@flownative.com> VOLUME /build COPY DistributionPackages /build/DistributionPackages COPY Packages/Framework /build/Packages/Framework COPY Packages/Libraries /build/Packages/Libraries COPY Packages/Application /build/Packages/Application COPY bin /build/bin COPY Web /build/Web COPY flow /build/flow COPY composer.json /build/composer.json COPY composer.lock /build/composer.lock COPY Configuration /build/Configuration COPY beach* /build/
  13. name: Build on: push: branches-ignore: - '**' tags: - 'v*.*.*' jobs: build: runs-on: ubuntu-latest steps: # see https: / / github.com/shivammathur/setup-php#bookmark-versioning) - uses: shivammathur/setup-php@v2 with: php-version: '8.1' - uses: actions/checkout@v2 with: ref: main fetch-depth: 100 - name: Determine latest version id: latest_version uses: flownative/action-git-latest-release@master
  14. - uses: actions/checkout@v2 with: ref: ${{ steps.latest_version.outputs.tag }} fetch-depth: 100 - name: Docker meta id: meta uses: docker/metadata-action@v3 with: flavor: | latest=true images: | europe-docker.pkg.dev/flownative/beach/beach-controlpanel labels: | org.opencontainers.image.title=Beach Control Panel org.opencontainers.image.description=Docker image providing the Beach Contro org.opencontainers.image.licenses=proprietary org.opencontainers.image.vendor=Flownative GmbH org.opencontainers.image.version=${{ steps.latest_version.outputs.version }} tags: | type=semver,pattern={{major}},value=${{ steps.latest_version.outputs.version type=semver,pattern={{major}}.{{minor}},value=${{ steps.latest_version.outpu type=semver,pattern={{version}},value=${{ steps.latest_version.outputs.versi - name: Set up QEMU id: qemu
  15. europe-docker.pkg.dev/flownative/beach/beach-controlpanel labels: | org.opencontainers.image.title=Beach Control Panel org.opencontainers.image.description=Docker image providing the Beach Contro org.opencontainers.image.licenses=proprietary org.opencontainers.image.vendor=Flownative GmbH org.opencontainers.image.version=${{ steps.latest_version.outputs.version }} tags: | type=semver,pattern={{major}},value=${{ steps.latest_version.outputs.version type=semver,pattern={{major}}.{{minor}},value=${{ steps.latest_version.outpu type=semver,pattern={{version}},value=${{ steps.latest_version.outputs.versi - name: Set up QEMU id: qemu uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v1 - name: Login to Google Artifacts Registry uses: docker/login-action@v1 with: registry: europe-docker.pkg.dev/flownative/beach username: '_json_key' password: ${{ secrets.GOOGLE_ARTIFACTS_PASSWORD_BEACH }}
  16. id: composer-cache uses: actions/cache@v2 with: path: Packages key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} restore-keys: | php- - name: Add SSH key uses: webfactory/ssh-agent@v0.5.4 with: ssh-private-key: ${{ secrets.FLOWNATIVE_BOT_SSH_PRIVATE_KEY }} - name: Install Dependencies env: COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH_JSON }} run: composer install -q - - no-ansi - - no-dev - - no-interaction - - no-progress - - opt - name: Build Docker image uses: docker/build-push-action@v2 with: context: . platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }}
  17. Google Cloud https://cloud.google.com/artifact-registry/
  18. Harbor https://goharbor.io
  19. Container Docker Images
  20. Pod Structure
  21. Base Image - standards and tooling for other images - common tools for application usage 👉 create your own base image 👉 reduce to a minimum, but not less
  22. Which OS? Alpine Linux - smaller fi lesystem footprint - more secure? - only relevant in container context - uses musl instead of glibc 🐛
  23. Which OS? Debian - larger fi lesystem footprint - well-established security team - wide-spread, therefore more fi rst-hand experience - high compatibility due to glibc
  24. Which OS? 👉 You need to feel comfortable working with the OS and it must support all the software you want to install
  25. 0 30 60 90 120 ubuntu:jammy debian:bullseye bitnami/minideb:bullseye alpine:latest 5,29 MB 72 MB 118 MB 69 MB
  26. Does the image size matter? Due to layering not so much if most containers use the same base image
  27. dive https://github.com/wagoodman/dive
  28. Nightly Rebuilds 🙄
  29. Nightly Rebuilds 😮
  30. Build Cascade announce: runs-on: ubuntu-latest needs: build steps: - name: Dispatch to beach-php uses: peter-evans/repository-dispatch@v1 with: token: ${{ secrets.FLOWNATIVE_BOT_TOKEN }} repository: flownative/docker-beach-php event-type: php-images-built client-payload: '{"image_name": "flownative/docker-php/php"}'
  31. Build Cascade name: Build Docker images on: repository_dispatch: types: [php-images-built] push: branches-ignore: - '**' tags: - 'v*.*.*' jobs: build: runs-on: ubuntu-latest strategy: matrix:
  32. fl ownative/docker-php https://github.com/flownative/?q=docker-
  33. More image security - don't run as root (use SecurityContext) - disable privilege escalation - automatically scan images - redeploy automatically, frequently - only include minimal amount of software – do you really need a shell?
  34. Deployment
  35. Deployment Strategies
  36. Recreate
  37. Recreate
  38. Rollout
  39. Rollout
  40. Rollout
  41. Rollout
  42. Rollout
  43. Blue / Green
  44. Blue / Green
  45. Blue / Green
  46. apiVersion: apps/v1 kind: Deployment metadata: name: podinfo-frontend namespace: podinfo spec: selector: matchLabels: app.kubernetes.io/name: podinfo-frontend template: metadata: labels: app.kubernetes.io/name: podinfo-frontend spec: containers: - name: podinfo image: ghcr.io/stefanprodan/podinfo:6.2.0 command: - ./podinfo - - - port=9898
  47. spec: containers: - name: podinfo image: ghcr.io/stefanprodan/podinfo:6.2.0 command: - ./podinfo - - - port=9898 env: - name: PODINFO_BACKEND_URL value: http: / / backend-podinfo:9898/echo ports: - containerPort: 9898 name: http protocol: TCP resources: requests: cpu: 50m memory: 16Mi limits: cpu: 1 memory: 100Mi
  48. Helm https://helm.sh
  49. Separate Pods Frontend, Backend, Worker, Cron, …
  50. Use Jobs for Warm Up Container start-up time can be critical. Helm hooks can be one solution.
  51. Scaling
  52. What to scale? What about sessions, database, queues? How quickly does your app start?
  53. Test Performance
  54. k6 https://k6.io/open-source
  55. Storage
  56. Object / Persistent Prefer object storage, key / value storage, database where possible. Avoid traditional fi les (persistent volumes).
  57. Persistent Volumes - vs. Ephemeral Volumes - Storage Classes - dynamic provisioning - Container Storage Interface drivers
  58. Persistent Volumes - vs. Ephemeral Volumes - Storage Classes - dynamic provisioning - Container Storage Interface drivers - ReadWriteOnce vs ReadWriteMany
  59. GlusterFS / Ceph - distributed persistent storage systems - GlusterFS: network fi le system - Ceph: object storage
  60. Databases
  61. Latencies and clusters
  62. Database in K8s? probably not (yet)
  63. Postgres Operator https://github.com/zalando/postgres-operator
  64. Monitoring and Logging
  65. Centralize logs or you won't have logs.
  66. Loki https://grafana.com/docs/loki/latest/clients/promtail
  67. Promtail https://grafana.com/docs/loki/latest/clients/promtail
  68. Prometheus https://prometheus.io
  69. Running Kubernetes
  70. Self-Managed Bare Matal Virtual Machine Managed Control Plane
  71. Rancher https://www.rancher.com/
  72. How do I …? Can I …? With K8s, how does …?
  73. robert@ fl ownative.com www. fl ownative.com @robertlemke @robert@ fl ownative.social Your thoughts?
  74. Bonus: Base Image
  75. FROM bitnami/minideb:bullseye LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>" ARG BUILD_DATE LABEL com.flownative.base-image-build-date=$BUILD_DATE ENV FLOWNATIVE_LIB_PATH="/opt/flownative/lib" FLOWNATIVE_INIT_PATH="/opt/flownative/init" FLOWNATIVE_LOG_PATH="/opt/flownative/log" FLOWNATIVE_LOG_PATH_AND_FILENAME="/dev/stdout" SYSLOG_BASE_PATH="/opt/flownative/syslog-ng" LOGROTATE_BASE_PATH="/opt/flownative/logrotate" SUPERVISOR_BASE_PATH="/opt/flownative/supervisor" LOG_DEBUG=true COPY - - from=europe-docker.pkg.dev/flownative/docker/bash-library:1.13.4 /lib $FLOWNATIVE_LIB_PATH COPY root-files / RUN /build.sh & & rm /build.sh USER 1000 ENTRYPOINT ["/entrypoint.sh"] CMD [ "run" ]
  76. FROM europe-docker.pkg.dev/flownative/docker/base:bullseye LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>" # ----------------------------------------------------------------------------- # PHP # Latest versions: https: / / www.php.net/downloads.php ARG PHP_VERSION ENV PHP_VERSION ${PHP_VERSION} ENV PHP_BASE_PATH="/opt/flownative/php" PATH="/opt/flownative/php/bin:$PATH" LOG_DEBUG="false" USER root COPY root-files / RUN export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout & & /build.sh init & & /build.sh prepare & & /build.sh build & & /build.sh build_extension vips & & /build.sh build_extension igbinary & & /build.sh disable_extension igbinary & & /build.sh build_extension imagick & & /build.sh build_extension yaml & & /build.sh build_extension phpredis & & /build.sh build_extension xdebug & & /build.sh disable_extension xdebug & & /build.sh build_extension ssh2 & & /build.sh clean USER 1000 EXPOSE 9000 9001 WORKDIR ${PHP_BASE_PATH} ENTRYPOINT [ "/entrypoint.sh" ] CMD [ "run" ]
  77. FROM europe-docker.pkg.dev/flownative/docker/base:bullseye LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>" # ----------------------------------------------------------------------------- # PHP # Latest versions: https: / / www.php.net/downloads.php ARG PHP_VERSION ENV PHP_VERSION ${PHP_VERSION} ENV PHP_BASE_PATH="/opt/flownative/php" PATH="/opt/flownative/php/bin:$PATH" LOG_DEBUG="false" USER root COPY root-files / RUN export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout & & /build.sh init & & /build.sh prepare & & /build.sh build & & /build.sh build_extension vips & & /build.sh build_extension igbinary & & /build.sh disable_extension igbinary & & /build.sh build_extension imagick & & /build.sh build_extension yaml & & /build.sh build_extension phpredis & & /build.sh build_extension xdebug & & /build.sh disable_extension xdebug & & /build.sh build_extension ssh2 & & /build.sh clean USER 1000 EXPOSE 9000 9001 WORKDIR ${PHP_BASE_PATH} ENTRYPOINT [ "/entrypoint.sh" ] CMD [ "run" ]
  78. # ! /bin/bash # Load helper libraries . "${FLOWNATIVE_LIB_PATH}/banner.sh" . "${FLOWNATIVE_LIB_PATH}/log.sh" . "${FLOWNATIVE_LIB_PATH}/packages.sh" set -o errexit set -o nounset set -o pipefail … # --------------------------------------------------------------------------------------- # Main routine case $1 in init) banner_flownative 'PHP' if [[ ! "${PHP_VERSION}" =~ ^7.[1-4]|^8.[0-2] ]]; then error "🛠 Unsupported PHP version '${PHP_VERSION}'" exit 1 fi build_create_directories ; ; prepare) packages_install $(build_get_runtime_packages) 1>$(debug_device) packages_install $(build_get_build_packages) 1>$(debug_device) ; ; build) build_compile_php ; ; build_extension) build_php_extension $2 ; ; disable_extension) build_disable_php_extension $2 ; ; clean) build_adjust_permissions packages_remove $(build_get_build_packages) 1>$(debug_device) packages_remove $(build_get_unnecessary_packages) 1>$(debug_device) packages_remove_docs_and_caches 1>$(debug_device) build_clean ; ; esac
  79. # --------------------------------------------------------------------------------------- # build_compile_php() - # # @global PHP_BASE_PATH # @return void # build_compile_php() { local php_source_url php_source_url="https: / / github.com/php/php-src/archive/php-${PHP_VERSION}.tar.gz" info "🛠 Downloading source code for PHP ${PHP_VERSION} from ${php_source_url} . . . " with_backoff "curl -sSL ${php_source_url} -o php.tar.gz" "15" | | ( error "Failed downloading PHP source from ${php_source_url}" exit 1 ) mkdir -p "${PHP_BASE_PATH}/src" tar -xf php.tar.gz -C "${PHP_BASE_PATH}/src" - - strip-components=1 rm php.tar.gz* cd "${PHP_BASE_PATH}/src" info "🛠 Generating build configuration . . . " ./buildconf - - force >$(debug_device) if [[ ! -f configure ]]; then error "🛠 Failed generating build configuration, 'configure' not found" # shellcheck disable=SC2012 ls | output exit 1 fi # For GCC warning options see: https: / / gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Warning-Options.html export CFLAGS='-Wno-deprecated-declarations -Wno-stringop-overflow -Wno-implicit-function-declaration' if [[ "${PHP_VERSION}" =~ ^7.4 ]]; then info "🛠 Running configure for PHP 7.4 . . . " ./configure - - prefix=${PHP_BASE_PATH} - - with-config-file-path="${PHP_BASE_PATH}/etc" - -
  80. if [[ ! -f configure ]]; then error "🛠 Failed generating build configuration, 'configure' not found" # shellcheck disable=SC2012 ls | output exit 1 fi # For GCC warning options see: https: / / gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Warning-Options.html export CFLAGS='-Wno-deprecated-declarations -Wno-stringop-overflow -Wno-implicit-function-declaration' if [[ "${PHP_VERSION}" =~ ^7.4 ]]; then info "🛠 Running configure for PHP 7.4 . . . " ./configure - - prefix=${PHP_BASE_PATH} - - with-config-file-path="${PHP_BASE_PATH}/etc" - - with-config-file-scan-dir="${PHP_BASE_PATH}/etc/conf.d" - - disable-cgi - - enable-calendar - - enable-exif - - enable-fpm - - enable-ftp - - enable-gd - - enable-intl - - enable-mbstring - - enable-pcntl - - enable-soap - - enable-sockets - - with-curl - - with-freetype - - with-gmp - - with-jpeg - - with-mysqli - - with-openssl - - with-pdo-pgsql - - with-pdo-mysql - - with-readline - - with-sodium - - with-system-ciphers - - with-webp - - with-zip - - with-zlib - - without-pear
Anúncio