各位朋友,大家好!我是今天的主讲人,咱们今天来聊聊PHP应用在Kubernetes上的部署,以及如何利用Pod
、Deployment
、Service
和 Ingress
这四大金刚来构建一个稳定、可扩展的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
做了以下几件事:
- 基于官方的
php:7.4-fpm
镜像。 - 安装了一些常用的PHP扩展,比如GD、PDO MySQL和OPcache。
- 安装了Composer,用于管理PHP依赖项。
- 将PHP代码复制到
/var/www/html
目录。 - 启动PHP-FPM。
- 暴露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配置文件做了以下几件事:
- 监听80端口。
- 设置网站根目录为
/var/www/html
。 - 将
.php
请求转发到PHP-FPM。 - 禁止访问
.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
做了以下几件事:
- 基于官方的
nginx:latest
镜像。 - 删除默认的Nginx配置文件。
- 复制自定义的Nginx配置文件到
/etc/nginx/conf.d/default.conf
。 - 将静态资源复制到/var/www/html目录。
- 暴露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。
- 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。
- 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定义相同。
- 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端口。
- 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应用了。
- 部署应用
首先,使用kubectl apply
命令来创建Deployment、Service和Ingress:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
- 查看状态
可以使用kubectl get
命令来查看Deployment、Service和Ingress的状态:
kubectl get deployments
kubectl get services
kubectl get ingresses
- 扩容应用
可以使用kubectl scale
命令来扩容Deployment:
kubectl scale deployment/my-php-app-deployment --replicas=5
- 更新应用
更新应用只需要修改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
标签。
总结
今天我们一起学习了如何使用Pod
、Deployment
、Service
和Ingress
来部署PHP应用到Kubernetes上。希望通过这次讲座,大家能够对Kubernetes有一个更清晰的认识,并能够将其应用到实际的项目中。
当然,Kubernetes的世界非常广阔,还有很多值得学习的东西。希望大家能够继续探索,不断提升自己的技能。
最后,祝大家工作顺利,生活愉快! 如果大家有任何问题,欢迎随时提问。