基于LNMP的综合实验

基于LNMP架构部署综合实验

实验要求

基于LNMP架构部署blog应用。

具体要求如下:

  1. 使用mysql:5.7、php-fpm-wordpress、nginx镜像和wordpress-4.9.4-zh_CN.zip文件部署blog应用。
  2. 使用pv-pvs方式为mysql和wordpress提供存储。
  3. pv通过nfs提供。
  4. blog 应用通过https访问。
  5. 密码和站点证书用secret存储。
  6. 站点 vhost 配置使用configmap提供。

提示:php-fpm-wordpress 镜像找老师获取。

实验步骤

部署 NFS 服务

NFS 服务器操作

bash 复制代码
# 安装 NFS 服务
[root@master30 ~]# apt install -y nfs-kernel-server

# 创建共享目录
[root@master30 ~]# mkdir -p -m 777 /nfsshares/{mysql,blog}

# 配置 NFS 共享(地址已改为10.1.8.30,允许所有节点访问)
[root@master30 ~]# echo "/nfsshares/mysql *(rw,sync,no_root_squash,no_all_squash)
/nfsshares/blog *(rw,sync,no_root_squash,no_all_squash)" >> /etc/exports

# 启动服务
[root@master30 ~]# systemctl restart nfs-server

NFS 客户端操作

bash 复制代码
## 安装 NFS 客户端
[root@worker31-32 ~]# apt install -y nfs-common

## 验证共享
[root@worker31-32 ~]# showmount -e master30
Export list for master30:
/nfsshares/blog  *
/nfsshares/mysql *
准备 pv 和 pvc
bash 复制代码
[root@master30 ~]# vim pv-pvc.yaml
bash 复制代码
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-mysql
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /nfsshares/mysql
    server: 10.1.8.30
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-blog
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /nfsshares/blog
    server: 10.1.8.30
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-mysql
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-blog
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
bash 复制代码
[root@master30 ~]# kubectl get pvc
NAME       STATUS   VOLUME   CAPACITY  ACCESS MODES  STORAGECLASS VOLUMEATTRIBUTESCLASS   AGE
pvc-blog   Bound    pv-blog    5Gi        RWO                     <unset>                  9s
pvc-mysql  Bound    pv-mysql   5Gi        RWO                     <unset>                  9s
部署 mysql
bash 复制代码
[root@master30 ~]# kubectl create secret generic mysql --from-literal user=tom --from-literal password_for_user=redhat --from-literal password_for_root=redhat --from-literal db_name=wordpress
[root@master30 certs]# kubectl get secrets mysql
NAME    TYPE     DATA   AGE
mysql   Opaque   4      17s

[root@master30 ~]# vim pod-mysql.yaml
yaml 复制代码
---
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    name: mysql
spec:
  containers:
  - image: docker.io/library/mysql:latest
    imagePullPolicy: IfNotPresent
    name: mysql
    ports:
    - containerPort: 3306
      name: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql
          key: password_for_root
    - name: MYSQL_USER
      valueFrom:
        secretKeyRef:
          name: mysql
          key: user
    - name: MYSQL_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql
          key: password_for_user
    - name: MYSQL_DATABASE
      valueFrom:
        secretKeyRef:
          name: mysql
          key: db_name
    volumeMounts:
    - name: mysql-data
      mountPath: /var/lib/mysql
  volumes:
    - name: mysql-data
      persistentVolumeClaim:
        claimName: pvc-mysql
bash 复制代码
[root@master30 ~]# kubectl apply -f pod-mysql.yaml 
[root@master30 ~]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
mysql   1/1     Running   0          3s
[root@master30 ~]# kubectl exec -it mysql -- mysql -utom -predhat -e "show databases;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
| wordpress          |
+--------------------+
部署 php-fpm
bash 复制代码
# worker节点导入镜像
[root@worker31 ~]# nerdctl load -i php-7.2-fpm-wordpress.tar 
[root@worker32 ~]# nerdctl load -i php-7.2-fpm-wordpress.tar
# 镜像名称是 docker.io/library/php:7.2-fpm-wordpress

[root@master30 ~]# vim pod-php.yaml
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: php-fpm
  name: php-fpm
spec:
  containers:
  - image: docker.io/library/php:7.2-fpm-wordpress
    imagePullPolicy: IfNotPresent
    name: php-fpm
    volumeMounts:
    # PHP 网站根目录
    - name: blog-data
      mountPath: /usr/share/nginx/html  
  volumes:
  # PHP 网站根目录
  - name: blog-data
    persistentVolumeClaim:
      claimName: pvc-blog
bash 复制代码
[root@master30 ~]# kubectl apply -f pod-php.yaml
[root@master30 ~]# kubectl get pods php-fpm -o jsonpath={.status.podIP}
10.224.19.44
部署 nginx

创建私钥和证书

bash 复制代码
#--1--生成私钥 
[root@master30 ~]# openssl genrsa -out blog.key 2048  

#--2--生成请求文件csr
[root@master30 ~]# openssl req -new -key blog.key -out blog.csr -subj "/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=blog.laoma.cloud/emailAddress=webadmin@laoma.cloud" 
# CN的值必须是网站域名

#--3--使用自己的私钥对请求文件签名,以生成证书 
[root@master30 ~]# openssl x509 -req -days 3650 -in blog.csr -signkey blog.key -out blog.crt

创建 tls 类型secret

bash 复制代码
[root@master30 ~]# kubectl create secret tls tls-blog --cert=./blog.crt --key=./blog.key
[root@master30 ~]# kubectl get secrets tls-blog 
NAME       TYPE                DATA   AGE
tls-blog   kubernetes.io/tls   2      25s

准备虚拟主机配置文件

bash 复制代码
[root@master30 ~]# vim vhost-blog.conf 
bash 复制代码
server {
    listen 80;
    listen 443 ssl;
    server_name blog.laoma.cloud;  # 替换为实际域名

    # TLS 配置
    ssl_certificate /etc/nginx/tls/tls.crt;
    ssl_certificate_key /etc/nginx/tls/tls.key;

    # 网站根目录
    root /usr/share/nginx/html;
    index index.php index.html;

    # PHP 转发配置(PHP IP)
    location ~ \.php$ {
        fastcgi_pass 10.224.19.44:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }
}
bash 复制代码
[root@master30 ~]# kubectl create configmap vhost-blog --from-file=vhost-blog.conf=./vhost-blog.conf

准备 pod-nginx

bash 复制代码
[root@master30 ~]# vim pod-nginx.yaml
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: docker.io/library/nginx:latest
    imagePullPolicy: IfNotPresent
    name: nginx
    volumeMounts:
    - name: vhost-blog
      mountPath: /etc/nginx/conf.d/vhost-blog.conf
      subPath: vhost-blog.conf
    - name: tls-blog
      mountPath: /etc/nginx/tls
      readOnly: true
    - name: blog-data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: vhost-blog
    configMap:
      name: vhost-blog
  - name: tls-blog
    secret:
      secretName: tls-blog
  - name: blog-data
    persistentVolumeClaim:
      claimName: pvc-blog
bash 复制代码
[root@master30 ~]# kubectl apply -f pod-nginx.yaml
[root@master30 ~]# kubectl get pod nginx 
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          11s
[root@master30 ~]# kubectl get pod nginx -o jsonpath={.status.podIP}
10.224.113.173

准备测试页面

bash 复制代码
[root@master30 ~]# echo Hello World From Nginx > /nfsshares/blog/index.html
[root@master30 ~]# echo "<?php phpinfo(); ?>" > /nfsshares/blog/phpinfo.php
[root@master30 ~]# cat <<'EOF' > /nfsshares/blog/test-mysql.php
<?php
// 数据库配置信息 ------ 请改成你自己的
$host = '10.224.19.45';   // 数据库地址,一般都是 localhost
$user = 'tom';        // 数据库用户名
$pass = 'redhat';            // 数据库密码
$dbname = 'wordpress';      // 要连接的数据库名(必须先创建好)

// 创建连接
$conn = mysqli_connect($host, $user, $pass, $dbname);

// 检测连接是否成功
if (!$conn) {
    die("连接失败:" . mysqli_connect_error());
}

// 设置字符集,防止乱码
mysqli_set_charset($conn, 'utf8mb4');

echo "✅ MySQL 数据库连接成功!";

// 关闭连接(可选)
mysqli_close($conn);
?>
EOF

测试 Nginx

bash 复制代码
# 配置解析
[root@master30 ~]# echo '10.224.113.173 blog.laoma.cloud' >> /etc/hosts

# http 站点
[root@master30 ~]# curl http://blog.laoma.cloud/index.html
Hello World From Nginx
[root@master30 ~]# curl -s http://blog.laoma.cloud/phpinfo.php |grep -o 'PHP Version 7'
PHP Version 7
[root@master30 ~]# curl http://blog.laoma.cloud/test-mysql.php
✅ MySQL 数据库连接成功!

# https 站点
[root@master30 ~]# curl -k https://blog.laoma.cloud/index.html
Hello World From Nginx
[root@master30 ~]# curl -sk https://blog.laoma.cloud/phpinfo.php |grep -o 'PHP Version 7'
PHP Version 7
[root@master30 ~]# curl -k https://blog.laoma.cloud/test-mysql.php
✅ MySQL 数据库连接成功!
部署 wordpress 代码
yaml 复制代码
## 进入 NFS 服务器(IP:10.1.8.30),下载 Wordpress 源码
[root@master30 ~]# unzip wordpress-4.9.4-zh_CN.zip 
[root@master30 ~]# cp -a wordpress/* /nfsshares/blog/

## 修改配置文件(连接 MySQL)
[root@master30 ~]# cp /nfsshares/blog/wp-config{-sample,}.php 

## 配置数据库信息
[root@master30 ~]# vim /nfsshares/blog/wp-config.php
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress');

/** MySQL数据库用户名 */
define('DB_USER', 'tom');

/** MySQL数据库密码 */
define('DB_PASSWORD', 'redhat');

/** MySQL主机 */
define('DB_HOST', '10.224.19.45');
访问网站
bash 复制代码
[root@master30 ~]# kubectl port-forward pod/nginx --address 10.1.8.30 80:80 443:443
Forwarding from 10.1.8.30:80 -> 80
Forwarding from 10.1.8.30:443 -> 443
相关推荐
极客先躯6 小时前
高级java每日一道面试题-2026年05月03日-实战篇[Docker]-如何实现容器化环境的数据加密?
java·运维·docker·容器·金融·加解密·高级面试
ChaITSimpleLove8 小时前
SimpleIdServer 6.0.4 Docker Compose 实战部署指南
运维·docker·容器·身份认证·id-server·simpleidserver
程序喵大人11 小时前
【C++进阶】STL容器与迭代器 - 05 map 和 set 为什么按键保持有序
开发语言·c++·容器·迭代器·stl
风曦Kisaki12 小时前
Kubernetes(K8s)笔记Day03: Pod命名空间,标签,Pod 的调度,污点与容忍度,Pod 常见状态和重启策略,Pod 生命周期
linux·运维·笔记·docker·云原生·容器·kubernetes
张忠琳12 小时前
【NVIDIA】NVIDIA k8s-device-plugin v0.19.3 资源管理器模块深度分析之三
云原生·容器·架构·kubernetes·nvidia
Chengbei1114 小时前
云安全漏洞挖掘SKILL、一站式云漏洞挖掘工具,支持S3爆破、IMDS探测、K8s检测与AK/SK权限利用
前端·人工智能·网络安全·云原生·容器·kubernetes·系统安全
Ai拆代码的曹操15 小时前
K8s 调度器 predicate 阶段揭秘:为什么你的 Pod 总是堆在同一台机器
后端·容器
Ai拆代码的曹操15 小时前
手摸手排查:Pod CrashLoopBackOff 日志丢失问题,3 层兜底方案
后端·容器
张忠琳16 小时前
【NVIDIA】k8s-device-plugin v0.19.3 — CDI / MIG / vGPU 模块超深度代码分析之五
云原生·容器·架构·kubernetes·nvidia
冷莫溪16 小时前
Docker——3.Harbor 核心架构与原理详解
docker·容器·架构