前言

组织的容器支持docker-compose部署
组织的容器支持kubernets部署
以php框架thinkphp为示例,演示php项目的kubernets部署
多容器方式(3容器)分别为:appphp(php代码)、openresty(nginx webserver),php-fpm(php的运行环境)
dockerfile 和 yaml文件
docker iamges仓库

PHP项目在Docker中如何部署运行?

PHP应用的运行方式

PHP应用的运行方式一般有
Apache mod_php 模式、Nginx(FastCgi)+PHP-FPM模式、Swoole常驻内存Daemon模式

Docker单容器

Apache mod_php 模式和Swoole常驻内存Daemon模式本身就是单程序,那么在Docker中入口运行程序直接为应用程序即可

Nginx(FastCgi)+PHP-FPM模式需要nginx和php-fpm 2个程序
这样Docker中就需要运行多个程序,需要有进程守护类软件来运行多个程序,那么可以参考如何在一个Docker中运行多个程序进程
推荐使用s6-overlay

Docker Hub中PHP官方镜像包已经包括Apache mod_php 模式的镜像包,Kubernets官方PHP项目实例GuestBook中就是采用这种模式的镜像包

Docker多容器配合

Docker官方倡导容器单一职责,也就是一个容器只运行一个程序
那么Nginx(FastCgi)+PHP-FPM模式就需要2个容器配合编排工作,再加上如果把PHP代码再独立成一个Docker镜像,那么就是3容器配合编排工作
所以下面就是以PHP项目采用多个Docker镜像的方式再Kubernets平台部署的范例

kubernets(k8s)部署运行

思路说明
容器共有3个,① appphp(wwek/k8s-php-thinkphp-hello:app-v1)php代码容器、② php-fpm(wwek/k8s-php-thinkphp-hello:php-fpm-7.2) 、③ openresty(wwek/k8s-php-thinkphp-hello:openresty)
apphp、php-fpm、openresty三个容器都在一个Pod(8s-php-thinkphp-hello)中
appphp容器作为initContainers初始化容器使用
挂载了一个叫做wwwroot的volume,类型为emptyDir,临时卷
initContainers初始化容器的时候会把php代码复制到wwwroot(volume)中
php-fpm和openresty都挂载wwwroot(volume)
openresty的upstream php 使用域名php-fpm
使用hostAliases把域名php-fpm解析为127.0.0.1(在同一个Pod中网络是共享的,所以用127.0.0.1)

具体的yaml文件

# Service
apiVersion: v1
kind: Service
metadata:
  name: k8s-php-thinkphp-hello
  labels:
    app: k8s-php-thinkphp-hello
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: k8s-php-thinkphp-hello
---
# deployment
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: k8s-php-thinkphp-hello
  labels:
    app: k8s-php-thinkphp-hello
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8s-php-thinkphp-hello
  template:
    metadata:
      labels:
        app: k8s-php-thinkphp-hello
    spec:
    #做一个emptyDir类型,名为wwwroot的volume 用于多个容器共享同一个挂载
      volumes:
      - name: wwwroot
        emptyDir: {}
      # 私有docker 镜像仓库
      # imagePullSecrets:
      # - name: registrykey-qlcoud-1
      # 自定义设置POD的hosts
      hostAliases:
      - ip: "127.0.0.1"
        hostnames:
        - "php-fpm"
      initContainers:
       #php程序本身
        - name: appphp
          image: "wwek/k8s-php-thinkphp-hello:app-v1"
          imagePullPolicy: Always
          # 复制php程序文件到wwwroot volume
          command: ["sh", "-c", "cp -r /var/www/k8s-php-thinkphp-hello /appdata"]
          volumeMounts:
          - mountPath: /appdata
            name: wwwroot
      containers:
       #php-fpm php运行环境
        - name: php-fpm
          image: "wwek/k8s-php-thinkphp-hello:php-fpm-7.2"
          imagePullPolicy: Always
          volumeMounts:
          - mountPath: /var/www
            name: wwwroot
      #openrsty webserver
        - name: openresty
          image: "wwek/k8s-php-thinkphp-hello:openresty"
          imagePullPolicy: Always
          volumeMounts:
          - mountPath: /var/www
            name: wwwroot
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          # livenessProbe:
          #   httpGet:
          #     path: /
          #     port: http
          # readinessProbe:
          #   httpGet:
          #     path: /
          #     port: http
          resources:
            {}
---
# Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: k8s-php-thinkphp-hello
  labels:
    app: k8s-php-thinkphp-hello
spec:
  rules:
    - host: k8sphpthinkphp.com
      http:
        paths:
          - path: /
            backend:
              serviceName: k8s-php-thinkphp-hello
              servicePort: http
kubectl apply -f k8s-php-thinkphp-hello.yml
kubectl get pods |grep k8s-php-thinkphp-hello
kubectl get service |grep k8s-php-thinkphp-hello
kubectl get ingress |grep k8s-php-thinkphp-hello

把 k8sphpthinkphp.com hosts解析到Ingress 的ip
然后浏览器

访问 http://k8sphpthinkphp.com/ 可以看到thinkphp的欢迎页面

访问 http://k8sphpthinkphp.com/phpinfo.php 可以看到phpinfo信息

如果没有ingress请自行修改service的type为 NodePort 使用节点的ip和端口访问

docker-compose部署运行

一套打包好的业务PHP Docker业务镜像也可以用docker-compose部署,这样方便了本地的开发调试使用

version: '2'

services:

### Applications Code Container #############################

    appphp:
      image: wwek/k8s-php-thinkphp-hello:app-v1
      build:
        context: ./appphp
        dockerfile: "Dockerfile"

### PHP-FPM Container #######################################

    php-fpm:
      image: wwek/k8s-php-thinkphp-hello:php-fpm-7.2
      build:
        context: ./php-fpm
        dockerfile: "Dockerfile"
      volumes_from:
        - appphp
      environment:
        - RUN_MODE=prd
        - MYSQL_HOSTNAME= \
        - MYSQL_USERNAME= \
        - MYSQL_PASSWORD= 
      depends_on:
        - appphp
      expose:
        - "9000"
      networks:
        - backend

### OPENRESTY Server Container ##################################

    openresty:
      image: wwek/k8s-php-thinkphp-hello:openresty
      build:
        context: ./openresty
        dockerfile: "Dockerfile"
      volumes_from:
        - appphp
      ports:
        - "80:80"
        - "443:443"
      depends_on:
        - php-fpm
      networks:
        - frontend
        - backend

### Networks Setup ############################################

networks:
  frontend:
    driver: "bridge"
  backend:
    driver: "bridge"

### Volumes Setup #############################################

volumes:
  redis:
    driver: "local"

直接up方式,直接pull已经build好的docker images

docker-compose up -d

本地build方式

docker-compose up -d --build

浏览器 访问 http://127.0.0.1 访问 http://127.0.0.1/phpinfo.php

代码

所有配置范例代码已经托管到github
k8s-php-thinkphp-hello