PHP `Kubernetes` 部署:`Pod`、`Deployment`、`Service` 与 `Ingress`

各位朋友,大家好!我是今天的主讲人,咱们今天来聊聊PHP应用在Kubernetes上的部署,以及如何利用PodDeploymentServiceIngress 这四大金刚来构建一个稳定、可扩展的PHP应用。

别担心,这听起来可能有点吓人,但实际上,Kubernetes并没有那么神秘。让我们用通俗易懂的方式,把这些概念拆解开来,再用实际代码演示如何应用它们。

第一部分:Kubernetes 基础概念扫盲

首先,咱们得先搞清楚这几个核心概念,它们就像盖房子用的砖头、水泥和钢筋,缺一不可。

  • Pod: 这是Kubernetes里最小的部署单元,你可以把它想象成一个“房间”。一个Pod里可以运行一个或多个容器(Docker容器),这些容器共享网络和存储。一般来说,我们一个Pod里放一个应用容器,比如运行PHP-FPM的容器。

  • Deployment: 如果Pod是房间,那么Deployment就是“楼房的设计图”。它描述了你想要运行多少个Pod副本,以及如何更新这些Pod。通过Deployment,你可以轻松地实现应用的滚动升级、回滚和扩容。

  • Service: 有了楼房,还得有“门牌号”才能让别人找到你。Service就是Kubernetes里的门牌号,它提供了一个稳定的IP地址和DNS名称,让其他应用可以通过这个Service访问到Pod。

  • Ingress: 如果Service是内网的门牌号,那么Ingress就是暴露给外网的“总入口”。它可以根据不同的域名或路径,将流量路由到不同的Service。

第二部分:PHP 应用 Docker 化

要想把PHP应用部署到Kubernetes上,首先得把它Docker化。Docker化就是把你的PHP代码、依赖项和运行环境打包到一个Docker镜像里。

下面是一个简单的Dockerfile示例,用于构建一个包含PHP-FPM和Nginx的Docker镜像:

# 使用官方的PHP-FPM镜像作为基础镜像
FROM php:7.4-fpm

# 安装必要的扩展
RUN apt-get update && apt-get install -y 
    git 
    zip 
    unzip 
    libpng-dev 
    libjpeg62-turbo-dev 
    libfreetype6-dev 
    --no-install-recommends

# 安装PHP扩展
RUN docker-php-ext-configure gd --with-freetype --with-jpeg 
    && docker-php-ext-install -j$(nproc) gd 
    && docker-php-ext-install pdo_mysql 
    && docker-php-ext-install opcache

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

# 设置工作目录
WORKDIR /var/www/html

# 将PHP代码复制到容器中
COPY . /var/www/html

# 设置容器启动时执行的命令
CMD ["php-fpm"]

# 暴露9000端口
EXPOSE 9000

这个Dockerfile做了以下几件事:

  1. 基于官方的php:7.4-fpm镜像。
  2. 安装了一些常用的PHP扩展,比如GD、PDO MySQL和OPcache。
  3. 安装了Composer,用于管理PHP依赖项。
  4. 将PHP代码复制到/var/www/html目录。
  5. 启动PHP-FPM。
  6. 暴露9000端口,供Nginx连接。

为了提供静态文件服务,我们还需要一个Nginx容器。下面是一个简单的Nginx配置文件:

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;

    location ~ .php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass 127.0.0.1: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 ~ /.ht {
        deny all;
    }
}

这个Nginx配置文件做了以下几件事:

  1. 监听80端口。
  2. 设置网站根目录为/var/www/html
  3. .php请求转发到PHP-FPM。
  4. 禁止访问.ht文件。

然后,我们还需要一个Dockerfile来构建Nginx容器:

FROM nginx:latest

# 删除默认的Nginx配置文件
RUN rm /etc/nginx/conf.d/default.conf

# 复制自定义的Nginx配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 复制html静态文件
COPY ./public /var/www/html

# 暴露80端口
EXPOSE 80

这个Dockerfile做了以下几件事:

  1. 基于官方的nginx:latest镜像。
  2. 删除默认的Nginx配置文件。
  3. 复制自定义的Nginx配置文件到/etc/nginx/conf.d/default.conf
  4. 将静态资源复制到/var/www/html目录。
  5. 暴露80端口。

现在,我们就可以使用docker build命令来构建这两个镜像了:

docker build -t my-php-app .
docker build -t my-nginx-app ./nginx

第三部分:Kubernetes YAML 文件编写

有了Docker镜像,接下来就是编写Kubernetes YAML文件了。YAML文件用于描述Kubernetes资源,比如Pod、Deployment、Service和Ingress。

  1. Pod 定义

首先,我们定义一个Pod,包含Nginx和PHP-FPM两个容器。

apiVersion: v1
kind: Pod
metadata:
  name: my-php-app-pod
  labels:
    app: my-php-app
spec:
  containers:
    - name: php-fpm
      image: my-php-app:latest
      ports:
        - containerPort: 9000
    - name: nginx
      image: my-nginx-app:latest
      ports:
        - containerPort: 80
      volumeMounts:
        - mountPath: /var/www/html
          name: my-app-volume
  volumes:
    - name: my-app-volume
      emptyDir: {}

这个YAML文件定义了一个名为my-php-app-pod的Pod,它包含两个容器:

  • php-fpm:运行my-php-app:latest镜像,监听9000端口。
  • nginx:运行my-nginx-app:latest镜像,监听80端口,并将/var/www/html目录挂载到my-app-volume卷。

my-app-volume是一个emptyDir卷,它会在Pod启动时自动创建,并在Pod删除时自动销毁。这样可以实现Nginx和PHP-FPM容器之间共享文件。

注意: 在实际生产环境中,不建议直接使用Pod进行部署。因为Pod是短暂的,如果Pod发生故障,Kubernetes不会自动重启它。建议使用Deployment来管理Pod。

  1. Deployment 定义

接下来,我们定义一个Deployment,用于管理Pod的副本数量和更新策略。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-php-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-php-app
  template:
    metadata:
      labels:
        app: my-php-app
    spec:
      containers:
        - name: php-fpm
          image: my-php-app:latest
          ports:
            - containerPort: 9000
        - name: nginx
          image: my-nginx-app:latest
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /var/www/html
              name: my-app-volume
      volumes:
        - name: my-app-volume
          emptyDir: {}

这个YAML文件定义了一个名为my-php-app-deployment的Deployment,它做了以下几件事:

  • replicas: 3:指定运行3个Pod副本。
  • selector:指定Deployment管理的Pod的标签,这里是app: my-php-app
  • template:定义Pod的模板,与上面的Pod定义相同。
  1. Service 定义

现在,我们需要定义一个Service,用于暴露Deployment管理的Pod。

apiVersion: v1
kind: Service
metadata:
  name: my-php-app-service
spec:
  selector:
    app: my-php-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

这个YAML文件定义了一个名为my-php-app-service的Service,它做了以下几件事:

  • selector:指定Service路由流量的Pod的标签,这里是app: my-php-app
  • ports:定义Service的端口映射,这里将Service的80端口映射到Pod的80端口。
  1. Ingress 定义

最后,我们需要定义一个Ingress,用于将外部流量路由到Service。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-php-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: my-php-app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-php-app-service
                port:
                  number: 80

这个YAML文件定义了一个名为my-php-app-ingress的Ingress,它做了以下几件事:

  • host: my-php-app.example.com:指定Ingress处理的域名。
  • path: /:指定Ingress处理的路径。
  • backend:指定Ingress将流量路由到的Service,这里是my-php-app-service的80端口。

注意: 要使用Ingress,你需要先安装Ingress Controller,比如Nginx Ingress Controller。

第四部分:部署和管理 PHP 应用

有了YAML文件,就可以使用kubectl命令来部署和管理PHP应用了。

  1. 部署应用

首先,使用kubectl apply命令来创建Deployment、Service和Ingress:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
  1. 查看状态

可以使用kubectl get命令来查看Deployment、Service和Ingress的状态:

kubectl get deployments
kubectl get services
kubectl get ingresses
  1. 扩容应用

可以使用kubectl scale命令来扩容Deployment:

kubectl scale deployment/my-php-app-deployment --replicas=5
  1. 更新应用

更新应用只需要修改Deployment的YAML文件,然后再次使用kubectl apply命令即可。Kubernetes会自动进行滚动升级,保证应用的高可用性。

第五部分:一些高级技巧和注意事项

  • 配置管理: 使用ConfigMap和Secret来管理应用的配置信息和敏感数据。
  • 日志管理: 使用ELK Stack或Fluentd来收集和分析应用的日志。
  • 监控: 使用Prometheus和Grafana来监控应用的性能指标。
  • 自动伸缩: 使用Horizontal Pod Autoscaler (HPA) 来根据CPU利用率自动调整Pod的副本数量。
  • 持久化存储: 如果应用需要持久化存储数据,可以使用Persistent Volume和Persistent Volume Claim。
  • 命名空间: 使用命名空间来隔离不同的应用环境。
  • 健康检查: 配置liveness和readiness probes,让Kubernetes能够自动检测和重启故障的Pod。
  • 资源限制: 为每个容器设置资源限制(CPU和内存),防止容器占用过多资源。
  • 安全: 使用RBAC(Role-Based Access Control)来控制对Kubernetes资源的访问权限。
  • 镜像版本管理: 始终使用版本号来标记Docker镜像,避免使用latest标签。

总结

今天我们一起学习了如何使用PodDeploymentServiceIngress来部署PHP应用到Kubernetes上。希望通过这次讲座,大家能够对Kubernetes有一个更清晰的认识,并能够将其应用到实际的项目中。

当然,Kubernetes的世界非常广阔,还有很多值得学习的东西。希望大家能够继续探索,不断提升自己的技能。

最后,祝大家工作顺利,生活愉快! 如果大家有任何问题,欢迎随时提问。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注