Docker/DockerSwarm部署LNMP并平滑升级PHP

本文介绍如何使用Docker部署LNMP环境,并通过Docker Swarm实现PHP版本平滑升级,包括配置镜像仓库、搭建MySQL、PHP及Nginx容器和服务等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.基础环境

1.配置系统内核转发功能

docker网络依赖于系统的内核转发功能,如果不配置内核转发,docker功能可能会出错
[root@webapi4-app-22-151 ~]# vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
[root@webapi4-app-22-151 ~]# sysctl -p

2.安装docker-ce

移除旧版本,如果之前没有安装过docker则跳过
[root@webapi4-app-22-151 ~]# yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine

安装工具
[root@webapi4-app-22-151 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

添加docker-ce的yum源
[root@webapi4-app-22-151 ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装docker-ce
[root@webapi4-app-22-151 ~]# yum install -y docker-ce

开启docker
[root@webapi4-app-22-151 ~]# systemctl daemon-reload
[root@webapi4-app-22-151 ~]# systemctl start docker
[root@webapi4-app-22-151 ~]# systemctl enable docker

3.配置镜像仓库

docker默认从国外的DockerHub公共仓库拉取镜像,拉取镜像的速度可能会很慢,所以要配置国内的镜像仓库。
[root@webapi4-app-22-151 ~]#mkdir /etc/docker #如果文件夹已存在则跳过

新建daemon.json文件
[root@webapi4-app-22-151 ~]# cat /etc/docker/daemon.json
{
“registry-mirrors”: [“https://5twf62k1.mirror.aliyuncs.com”]
}

[root@webapi4-app-22-151 ~]# systemctl restart docker

[root@webapi4-app-22-151 ~]#docker info
查看,配置镜像仓库成功
在这里插入图片描述

4.拉取镜像

[root@webapi4-app-22-151 ~]# docker pull php:7.3.27-fpm
[root@webapi4-app-22-151 ~]# docker pull nginx:latest
[root@webapi4-app-22-151 ~]# docker pull mysql:8.0
查看当前主机的镜像
在这里插入图片描述

二、部署LNMP

新建nginx、php、mysql目录,这三个目录用于保存容器内的配置文件和数据文件,防止删除容器之后导致数据丢失。
[root@webapi4-app-22-151 ~]# mkdir -p /lnmp/{nginx,php,mysql}
[root@webapi4-app-22-151 ~]# mkdir /lnmp/mysql/data

1.搭建mysql

启动一个临时的mysql容器
[root@webapi4-app-22-151 ~]# docker run -itd --name tmp mysql:8.0 /bin/bash
将mysql容器内的配置文件拷贝出来,拷贝到主机的目录
[root@webapi4-app-22-151 ~]# docker cp tmp:/etc/mysql /lnmp/mysql/
在这里插入图片描述

删除临时容器
[root@webapi4-app-22-151 mysql]# docker rm -f tmp
配置防火墙,放通端口
[root@webapi4-app-22-151 mysql]# firewall-cmd --add-port=3306/tcp

启动mysql容器
[root@webapi4-app-22-151 mysql]# docker run -d --name mysql -p 3306:3306 --restart always -e MYSQL_ROOT_PASSWORD=000000 -v /lnmp/mysql/mysql/:/etc/mysql -v /lnmp/mysql/data/:/var/lib/mysql mysql:8.0

参数解释
-d:后台运行容器
–name:指定容器名
-p:端口映射,将主机的3306端口与容器的3306端口映射起来。外部访问数据库时可以通过主机的IP:Port来访问,不需要访问容器的IP:Port。
–restart:指定容器的重启策略,always表示总是重启容器,可以实现容器异常退出时自动重启容器
-e:指定容器的环境变量,其中MYSQL_ROOT_PASSWORD=000000表示设置数据库root用户的密码为000000。mysql容器内有脚本可以接收这个参数,如果启动mysql容器时不指定这个环境变量,则容器可能会启动失败。
在这里插入图片描述
-v:映射数据卷,其中/lnmp/mysql/mysql/:/etc/mysql表示将主机的/lnmp/mysql/mysql/目录映射为容器的/etc/mysql目录。

查看容器
在这里插入图片描述

测试Mysql连接,使用主机的IP:Port访问

在这里插入图片描述

在这里插入图片描述

连接mysql成功

2.搭建php

启动一个临时的php容器
[root@webapi4-app-22-151 ~]# docker run -itd --name tmp php:7.3.27-fpm

将容器内的配置文件复制到主机目录
[root@webapi4-app-22-151 ~]# docker cp tmp:/usr/local/etc/ /lnmp/php

删除临时容器
[root@webapi4-app-22-151 ~]# docker rm -f tmp

[root@webapi4-app-22-151 ~]# firewall-cmd --add-port=9000/tcp

启动php容器
[root@webapi4-app-22-151 ~]# docker run -itd -p 9000:9000 --name php --restart always -v /lnmp/php/etc/:/usr/local/etc -v /lnmp/nginx/html:/usr/share/nginx/html php:7.3.27-fpm

参数解释
-i:打开容器的标准输入
-t:给容器分配一个终端

3.搭建nginx

启动临时的nginx容器
[root@webapi4-app-22-151 ~]# docker run -d --name tmp nginx:latest

将容器内的网页文件和配置文件拷贝出来,拷贝到主机目录
[root@webapi4-app-22-151 ~]# docker cp tmp:/usr/share/nginx/html/ /lnmp/nginx/
[root@webapi4-app-22-151 ~]# docker cp tmp:/etc/nginx /lnmp/nginx/
在这里插入图片描述

删除临时容器
[root@webapi4-app-22-151 ~]# docker rm -f tmp

[root@webapi4-app-22-151 ~]# firewall-cmd --add-port=80/tcp

启动nginx容器
[root@webapi4-app-22-151 ~]# docker run -d --name nginx -p 80:80 --restart always -v /lnmp/nginx/html:/usr/share/nginx/html -v /lnmp/nginx/nginx/:/etc/nginx --link php nginx:latest
参数解释
–link:容器互联,–link php表示nginx容器连接到php容器。设置这个参数之后,nginx容器内的hosts文件会添加一条php容器的IP映射。

网页访问

在这里插入图片描述

4.将nginx和php连接起来

添加php测试页面index.php
在这里插入图片描述

编辑nginx的配置文件default.conf。(之前nginx容器配置过-v参数的数据卷映射。修改主机目录中的配置文件,那么文件的修改会同步到nginx容器,这样子就省去了进去容器修改文件的麻烦,而且容器内一般是没有vi命令的)

[root@webapi4-app-22-151 ~]# cat /lnmp/nginx/nginx/conf.d/default.conf
location / {
        root   /usr/share/nginx/html;
        index  index.php index.html index.htm;
   }
location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   php:9000; 
#之前nginx容器配置过--link php参数,nginx容器可以使用php这个名字来连接
php容器。使用容器的IP来标识php容器不太方便,因为php容器异常重启时容器
的IP可能会变化。
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
#        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
}

完整配置文件:

[root@webapi4-app-22-151 ~]# cat /lnmp/nginx/nginx/conf.d/default.conf
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.php index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
#        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

编辑好文件之后,重启nginx容器
[root@webapi4-app-22-151 ~]# docker restart nginx

打开浏览器,访问nginx
在这里插入图片描述

三、问题

1.php容器状态异常

php容器一启动就退出,状态异常,一直重启
在这里插入图片描述
解决:在启动容器时添加两个参数-it
在这里插入图片描述

容器就不会异常退出了

2.nginx连接php失败

添加了php的测试主页index.php,修改了nginx的配置文件来连接php之后,访问nginx主页失败:
在这里插入图片描述
用命令“docker logs nginx”查看nginx容器的日志:
2021/04/28 09:55:32 [error] 24#24: *4 FastCGI sent in stderr: “Primary script unknown” while reading response header from upstream, client: 125.218.208.62, server: localhost, request: “GET / HTTP/1.1”, upstream: “fastcgi://172.17.0.3:9000”, host: “192.168.22.151”
在这里插入图片描述
解决:编辑nginx的default.conf文件,在location ~ .php$模块中将
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
修改成
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
在这里插入图片描述
然后使用命令“docker exec nginx nginx -s reload”重载文件
访问成功
在这里插入图片描述

四、DockerSwarm平滑升级PHP版本

一些优秀的容器平台/产品(例如Docker Swarm、Kubernetes、Rancher),集成了“平滑升级应用”的功能,借助这些平台,能够比较顺利、方便地完成应用升级。
上面部署的LNMP是通过docker部署三个容器(mysql容器、php容器、nginx容器)完成的;现在部署的LNMP是通过docker swarm集群(单节点)部署三种服务(mysql服务、php服务、nginx服务)来完成的,每种服务可以包含多个容器,这样的话即使其中一个容器异常那么其他容器也能够正常提供服务。

这里演示PHP从7.3.27版本升级到7.4.16 版本。
在这里插入图片描述
删除之前部署的mysql、php、nginx容器
[root@webapi4-app-22-151 ~]# docker rm -f mysql php nginx
查看容器,没有容器在运行
[root@webapi4-app-22-151 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@webapi4-app-22-151 ~]#

之前部署LNMP时用数据卷实现了数据持久化,即使把nginx、mysql、php容器删除,容器的配置文件、数据文件依然存留在主机中。接下来直接引用这些现成的配置文件和数据文件。
在这里插入图片描述

1.初始化集群

[root@webapi4-app-22-151 ~]# docker swarm init --advertise-addr 192.168.22.151 #192.168.22.151为当前主机的IP地址

查看集群里的节点
在这里插入图片描述

2.创建overlay网络

创建一个名字为lnmp-demo的overlay类型网络。
[root@webapi4-app-22-151 ~]# docker network create --driver overlay lnmp-demo

3.部署LNMP服务

创建PHP服务(7.3.27版本)

[root@webapi4-app-22-151 ~]# docker service create --name php --network lnmp-demo --publish 9000:9000 --mount type=bind,src=/lnmp/php/etc,dst=/usr/local/etc --mount type=bind,src=/lnmp/nginx/html,dst=/usr/share/nginx/html --replicas=4 php:7.3.27-fpm

参数解释
–name:设置服务名称
–network:设置服务的网络
–publish:暴露端口,9000:9000表示把主机的9000端口与容器的9000端口映射起来
–mount:挂载文件系统,bind指主机目录挂载到容器目录
–replicas:设置服务的副本数量,这里值为4,也就是说PHP服务内有4个PHP容器

创建mysql服务

[root@webapi4-app-22-151 ~]# docker service create --name mysql --network lnmp-demo --publish 3306:3306 --replicas=4 --env MYSQL_ROOT_PASSWORD=000000 --mount type=bind,src=/lnmp/mysql/mysql,dst=/etc/mysql mysql:8.0

创建nginx服务

[root@webapi4-app-22-151 ~]# docker service create --name nginx --network lnmp-demo --publish 80:80 --mount type=bind,src=/lnmp/nginx/nginx,dst=/etc/nginx --mount type=bind,src=/lnmp/nginx/html,dst=/usr/share/nginx/html --replicas 4 nginx:latest

查看服务状态
在这里插入图片描述

4.连接nginx与php

编辑nginx的default.conf配置文件

location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   php:9000;
 #三种容器运行在同一个overlay网络,服务之间可以用服务名或服务的虚拟IP来通信。
  fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
#        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
    }

完整配置文件:

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.php index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
#        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

重启nginx服务内的所有容器
[root@webapi4-app-22-151 ~]# docker restart $(docker ps -a -f name=nginx --format ‘{{.Names}}’)

访问nginx主页,可以看到当前PHP版本是7.3.27
在这里插入图片描述

升级PHP

Docker Swarm更新版本时,先停止一个旧版本容器,然后启动一个新版本容器,隔一段时间之后再停止一个旧版本容器、启动一个新版本容器,一直到所有旧版本容器停止、所有新版本容器启动完成,更新完成。

执行docker service update命令,对PHP服务进行升级

[root@webapi4-app-22-151 ~]# docker service update --image php:7.4.16-fpm --update-parallelism 1 --update-delay 10s --update-max-failure-ratio 0.5 --update-failure-action pause php

参数解释
–image: 设置更新的镜像,这里用php:7.4.16-fpm,也就是把PHP服务的镜像换成php:7.4.16-fpm镜像,即升级为7.4.16版本
–update-parallelism :设置并行更新的副本数,这里设置为1,也就是停止1个旧版本容器,启动1个新版本容器。设置为2的话则表示每停止2个旧版本容器,启动2个新版本容器。
–date-delay:更新间隔,这里设置为10秒。也就是更新一次容器之后,过10秒再进行下一次更新。
–update-max-failure-ratio:更新期间可以容忍的故障率,这里设置为0.5即50%,也就是说如果更新过程中有50%容器更新失败那么就认为此次更新是失败的,与–update-failure-action参数搭配使用。
–update-failure-action:设置更新失败之后的策略,pause表示更新失败之后停止更新,与上面的–update-max-failure-ratio参数连用,两个参数结合起来的作用是:当50%容器更新失败之后,就停止更新。另外,–update-failure-action还可以设置成rollback,即更新失败后自动回滚上一个版本。

更新过程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更新完成,可以看到PHP服务已经升级到7.4.16版本。
在这里插入图片描述
访问更新PHP之后的Nginx
在这里插入图片描述
至此,PHP版本升级完成

更新之后,旧版本容器没有被删除,占用空间
在这里插入图片描述
删除旧版本容器,docker rm $(docker ps -qa -f status=exited)
在这里插入图片描述

6.回滚测试

现在PHP已经升级到7.4.16版本,如果想要PHP回滚成旧的7.3.27版本,可以使用docker swarm的rollback功能来实现:
在这里插入图片描述
在这里插入图片描述

五、DockerSwarm升级应用遇到的问题

1 . File not found

执行以下三条命令部署三种服务
在这里插入图片描述
并且连接了nginx和php之后,访问nginx主页显示File not found:
在这里插入图片描述
原因是三种服务运行没有运行在overlay网络中,导致服务之间无法通过服务名来通信。
解决:删除三种服务,然后新建overlay网络,让三种服务运行在同一个overlay网络中
在这里插入图片描述
就可以正常显示网页了
在这里插入图片描述

智能网联汽车的安全员高级考试涉及多个方面的专业知识,包括但不限于自动驾驶技术原理、车辆传感器融合、网络安全防护以及法律法规等内容。以下是针对该主题的一些核心知识解析: ### 关于智能网联车安全员高级考试的核心内容 #### 1. 自动驾驶分级标准 国际自动机工程师学会(SAE International)定义了六个级别的自动驾驶等级,从L0到L5[^1]。其中,L3及以上级别需要安全员具备更高的应急处理能力。 #### 2. 车辆感知系统的组成与功能 智能网联车通常配备多种传感器,如激光雷达、毫米波雷达、摄像头和超声波传感器等。这些设备协同工作以实现环境感知、障碍物检测等功能[^2]。 #### 3. 数据通信与网络安全 智能网联车依赖V2X(Vehicle-to-Everything)技术进行数据交换,在此过程中需防范潜在的网络攻击风险,例如中间人攻击或恶意软件入侵[^3]。 #### 4. 法律法规要求 不同国家和地区对于无人驾驶测试及运营有着严格的规定,考生应熟悉当地交通法典中有关自动化驾驶部分的具体条款[^4]。 ```python # 示例代码:模拟简单决策逻辑 def decide_action(sensor_data): if sensor_data['obstacle'] and not sensor_data['emergency']: return 'slow_down' elif sensor_data['pedestrian_crossing']: return 'stop_and_yield' else: return 'continue_driving' example_input = {'obstacle': True, 'emergency': False, 'pedestrian_crossing': False} action = decide_action(example_input) print(f"Action to take: {action}") ``` 需要注意的是,“同学”作为特定平台上的学习资源名称,并不提供官方认证的标准答案集;建议通过正规渠道获取教材并参加培训课程来准备此类资格认证考试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值