当前位置:网站首页>PHP application container deployment practice

PHP application container deployment practice

2022-06-24 15:36:00 Xiezhengwei

In the current market php There is still a place . This article will explore how to php Application containerization and migration deployment to TKE.

php Apply image preparation

The level of mirror image : The base depends on the image -> Operational framework -> application / Code image

Container based single process running concept , The following deployment process does not use a single nginx+php-fpm Integrated container operation mode , It's going to be php-fpm and nginx Unravel .

base image

The installation of the basic system depends on the package and the company php The expansion package used by all development teams in the application .

The following example is based on the official fpm, Common system level dependencies and are installed php Package manager .

If possible , It is recommended to use a more basic image from php Source code to compile .

# runtime.Dockerfile
FROM php:8.0.3-fpm

#  Custom class library example 
RUN apt-get update && \
    apt-get install -y git zlib1g-dev libpng-dev libicu-dev
RUN docker-php-ext-install \
    gd \
    intl
RUN docker-php-ext-configure intl


#  install  composer
RUN curl -sS https://getcomposer.org/installer | php -- \
    --install-dir=/usr/local/bin --filename=composer \
    && chmod +x /usr/local/bin/composer 

Compile the above file into an image , and push To the warehouse :

docker build -t cloudbeer/php-runtime:1.0 -f runtime.Dockerfile .
docker push cloudbeer/php-runtime:1.0

Application layer framework image

If the development framework is stable , It is recommended to package the framework directly into a basic image to avoid frequent installation of dependent packages during subsequent deployment , Accelerate the release packaging release process , Such as business development A Group used lumen frame , We can specialize in lumen Make a mirror image .

The following image , Installed lumen web frame .

# lumen.Dockerfile
FROM cloudbeer/php-runtime:1.0

RUN mkdir /app
WORKDIR /app

RUN echo '{\
    "require": {\
    "php": "^7.3|^8.0",\
    "laravel/lumen-framework": "^8.0"\
    }\
 }' > composer.json

RUN composer i

The above image is packaged as :cloudbeer/my-lumen:1.0

Application layer mirroring

Because we have put lumen The runtime is installed , So in this image , Just copy the pure source code . Remember to create .gitignore perhaps .dockerignore file , exclude vender,test Such as catalog .

# .dockerignore
/vendor
/tests
/.idea
/.git
.gitignore
Dockerfile
Homestead.json
Homestead.yaml
.env
.ent.example
.phpunit.result.cache

You only need to copy the script file in the application image . This image contains the complete php Runtime and business code , After startup, you can directly receive fastcgi call .

FROM cloudbeer/my-lumen:1.0
COPY ./ /app/

The above image is packaged as : cloudbeer/php-caculate:1.0

Another way to package code , We use pure containers to package the source code , It'll be later K8S During deployment, copy the file to the framework runtime container to run .

FROM debian:buster-slim
RUN mkdir /app
COPY ./ /app/

The above image is packaged as : cloudbeer/php-caculate-purecode:1.0

The code layer can also have more packaging methods , Such as uploading to the object store , Or use NFS Storage , Late binding to the container runtime runs .

Local testing

Start the mirror cloudbeer/php-caculate:1.0

docker run --rm -it cloudbeer/php-caculate:1.0 sh

#  Running in the container 
#  start-up  php  test 
php -S localhost:8000 -t public &
#  View results 
curl http://localhost:8000/cpu

Perfect operation .

At present, the application image packaging has been completed . The first two layers of images can be reused , Real business applications only need to copy the code .

The image in the above code , I have all been packaged and uploaded to docker hub Official website , You can ignore build and push The process , Test directly .

Deploy to K8S/TKE

php Application deployment to container environment , The most natural way is : Direct will php The operating environment and web server And the business source code is packaged and run in a container . This is the simplest way ,php The government also provided php:nginx This kind of image bottom package .

but php Runtime sum web server Is running in two processes , This does not conform to container best practices . It is generally recommended to run these two processes in different containers .

nginx As sidecar function

K8S In the same pod in , You can run multiple containers . We will php-fpm The business code of is deployed in a container , It is accompanied by a nginx Containers ,nginx As fastcgi The caller of , And can proxy some static resources , This pattern is similar to mesh Of sidecar Pattern . The architecture is as follows :

nginx As sidecar Deploy

nginx To configure

because nginx and php-fpm In a pod in , So just initiate localhost Call . nginx The configuration is as follows , We write this configuration to cm in , Back through volume Bind to container . There are a few things to note about this configuration :

  • The app uses lumen Of route system , So you need to route through try_files All point to ./public/index.php file .
  • fastcgi_param SCRIPT_FILENAME /app/public/index.php Here also point all scripts to this file .
# nginx config
apiVersion: v1
kind: ConfigMap
metadata:
    name: caculate-sidecar-config
    namespace: php-test
data:
    config: |-
      server {
          listen       8081;
          root   /app/public;
          index index.php
          charset utf-8;

          location / {
            try_files $uri $uri/ /index.php?$args;
          }

          location ~ \.php$  {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /app/public/index.php;
            include        fastcgi_params;
          }
      }

Application deployment script

In the deployment script below , There are several points worth paying attention to :

  • Used emptyDir:{} As the source code storage medium of the container , In this way, the application can be read into the temporary directory , Accelerated runtime php Loading of source code . If the script file is small , You can specify emptyDir Run in memory , This can speed up script loading .
  • pod Used when starting 2 individual Initialize container , The images used are : A mirror image of minimalist source code (php-caculate-purecode) And the framework runtime mirror (my-lumen), At start-up, respectively /app Copy your code to emptyDir In the volume , Copied separately lumen Of vendor Dependency and business source code . Here, the process of copying business source code can also use cfs perhaps cos To achieve . Due to the use of host storage source code , When the source code is too large , Please note the risk of exceeding the host storage capacity .
  • Because the source code and dependent packages are already in initContainers Organized , therefore , Just use php Start the application from the basic container .
apiVersion: apps/v1
kind: Deployment
metadata:
  name: caculate-nginx-sidecar
  namespace: php-test
  labels: 
    app: caculate-nginx-sidecar
spec:
  replicas: 1
  selector:
    matchLabels:
      app: caculate-nginx-sidecar
  template:
    metadata:
      labels:
        app: caculate-nginx-sidecar
    spec:
      volumes:
      # web app  Working directory of 
      - name: webapp-data
        emptyDir: {}
      # nginx  Configuration file for , from  cm  Bound to 
      - name: nginx-php-config
        configMap:
          name: caculate-sidecar-config
          items:
          - key: config
            path: caculate-sidecar.conf
      #  initialization , Copy the source file in the image to the temporary folder .
      initContainers:
      - name: copy-code
        image: cloudbeer/php-caculate-purecode:1.0
        volumeMounts:
        - name: webapp-data
          mountPath: /webapp
        command: [cp, -R, /app/, /webapp]
      - name: copy-lumen
        image: cloudbeer/my-lumen:1.0
        volumeMounts:
        - name: webapp-data
          mountPath: /webapp
        command: [cp, -R, /app/, /webapp]
      containers:
      # fpm  Application running environment 
      - name: caculate
        image: cloudbeer/php-runtime:1.0
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        ports:
        - containerPort: 9000
          protocol: TCP
        volumeMounts:
        - name: webapp-data
          mountPath: /app
          subPath: app
      # nginx sidecar
      - name: nginx-sidecar
        image: nginx:alpine
        volumeMounts:
        - name: nginx-php-config
          mountPath: /etc/nginx/conf.d/caculate-sidecar.conf
          subPath: caculate-sidecar.conf
        - name: webapp-data
          mountPath: /app
          subPath: app
---

Hang one LoadBalancer have a look .

apiVersion: v1
kind: Service
metadata:
    name: caculate-sidecar-service
    namespace: php-test
spec:
    type: LoadBalancer
    selector:
        app: caculate-nginx-sidecar
    ports:
        - protocol: TCP
          port: 8081
          targetPort: 8081

Access the corresponding external ip:8081, Perfect operation .

nginx Independent deployment

Usually , The operation and maintenance department hopes to web server Convergence and unified management , Development doesn't care much nginx Specific configuration of , Split the two, and everyone expects it , And in the horizontal expansion of microservices , This way is also more “ grace ”.

The deployment architecture is as follows :

nginx Independent deployment architecture

Deploy fpm Business applications

  • Deployed here php-caculate Mirror image , This image contains the source code ,Web Framework and php Runtime , Is a complete php-fpm Business applications .
  • adopt service Publish app , In order to nginx Can find fpm service , And solve me webserver and Business services . You can do pure php Horizontal expansion of business and nginx Centralized management of .
#  by  php-fpm  Deploy  service
apiVersion: v1
kind: Service
metadata:
  name: caculate-standalone
  namespace: php-test
  labels:
    app: caculate-standalone
spec:
  ports:
  - port: 9000
    name: tcp
  selector:
    app: caculate-standalone

---   
#  Deploy specific applications 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: caculate-standalone
  namespace: php-test
  labels: 
    app: caculate-standalone
spec:
  replicas: 1
  selector:
    matchLabels:
      app: caculate-standalone
  template:
    metadata:
      labels:
        app: caculate-standalone
    spec:
      containers:
      - image: cloudbeer/php-caculate:1.0
        name: caculate
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        ports:
        - containerPort: 9000
          protocol: TCP

nginx Deploy

This part of nginx The configuration is basically the same as above , The only difference is fastcgi_pass The target of the call becomes php Business service:caculate-standalone 了 .

apiVersion: v1
kind: ConfigMap
metadata:
    name: caculate-standalone-config
    namespace: php-test
data:
    config: |-
      server {
          listen       8081;
          root   /app/public;
          index index.php
          charset utf-8;

          location / {
            try_files $uri $uri/ /index.php?$args;
          }

          location ~ \.php$  {
            fastcgi_pass   caculate-standalone:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /app/public/index.php;
            include        fastcgi_params;
          }
      }

The following is nginx Configure individual pod start-up .

apiVersion:  apps/v1
kind: Deployment
metadata:
    name: caculate-standalone-nginx-deployment
    namespace: php-test
spec:
    selector:
        matchLabels:
          app: nginx
    template:
        metadata:
          labels:
              app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:alpine
            volumeMounts:
            - name: nginx-php-config
              mountPath: /etc/nginx/conf.d/caculate-standalone.conf
              subPath: caculate-standalone.conf
          volumes:
              - name: nginx-php-config
                configMap:
                  name: caculate-standalone-config
                  items:
                  - key: config
                    path: caculate-standalone.conf

Now? , to nginx The application hangs a LoadBalancer Test it , It also works perfectly .

Use nginx-ingress Deploy

In the deployment architecture diagram above ,ingress and nginx Deployed separately , but nginx-ingress In fact, the two parts have been merged , also TKE Provide ready-made nginx-ingress. Now? , Let's try nginx-ingress Deploy .

Use nginx-ingress Deploy

stay TKE Installation in cluster nginx-ingress, Refer to this article :

https://cloud.tencent.com/document/product/457/50503

Use the deployed... Above fpm Business service: caculate-standalone .

The deployment script is as follows :

  • ingress.class The value of is to create nginx-ingress Defined on the console when .
  • And pure nginx Different configurations ,nginx-ingress No need to configure try_files node , The following configuration has actually forwarded all requests to public/index.php.
apiVersion: v1
kind: ConfigMap
metadata:
  name: caculate-nginx-ingress-config
  namespace: php-test
data:
  SCRIPT_FILENAME: "/app/public/index.php"
---  
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "your-ingress-class"
    nginx.ingress.kubernetes.io/backend-protocol: "FCGI"
    nginx.ingress.kubernetes.io/fastcgi-index: "index.php"
    nginx.ingress.kubernetes.io/fastcgi-params-configmap: "caculate-nginx-ingress-config"
  name: caculate-nginx-ingress
  namespace: php-test
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: caculate-standalone
          servicePort: 9000

TKE Of nginx-ingress It directly provides an Internet address , Have a visit , Perfect operation .

MORE:mesh turn

stay php mesh In the process of transformation , The questions to consider are as follows :

  • fastcgi Use TCP agreement , And has its own serialization method , This feature does not exist in istio and envoy Chinese support , Fine flow control is not possible .
  • fpm + envoy sidecar Service level flow control can be realized . fpm + nginx-sidecar + envoy sidecar take fastcgi Call to http call , Can be implemented based on http Fine flow control of the protocol .
  • Realize call chain monitoring , Need to use http Make a remote call , It may be necessary to modify the code , stay header Middle package opentracing .

The present ,php mesh It is recommended to adopt the deployment mode of fpm The business layer ,nginx-sidecar, envoy-sidecar Three containers make one pod Deployment mode of .

The architecture is as follows :

php Applied mesh Deployment architecture

The deployment here is the same as that in part one - nginx As sidecar Similar operation , You need to open in Tencent cloud TCM, And injection envoy Of sidecar.


This article related source code description

Location :https://github.com/cloudbeer/php-best-practice

src/lumen-app/

php Business applications , Mapping 2 A path

  • /cpu: Two ways to calculate pi
  • /mem: String is inserted into the array in order to burst the memory

deployments/

Deployment code

  • app-caculate-fpm-separate.yaml: nginx and fpm It's in different pod Deployment in China
  • app-caculate-nginx-ingress.yaml: nginx-ingress Direct agency fpm service
  • app-caculate-nginx-sidecar.yaml: nginx and fpm Deployed in the same pod Two containers in

dockerfile/

  • lumen.Dockerfile: contain lumen Framework operating environment
  • runtime.Dockerfile:php Basic operating environment
  • Business code Dockerfile be located src/lumen-app/Dockerfile and src/lumen-app/purecode.Dockerfile
原网站

版权声明
本文为[Xiezhengwei]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/05/20210508183423813R.html