Ansible自动化部署LNMP企业实战 实现LNMP个人博客站点实操

  • Linux系统安装
  • 利用 Cobbler 实现系统自动化安装
  • 程序包手动部署 wordpress
  • 利用 shell 脚本实现一键部署 wordpress
  • 利用 ansible 实现自动化部署 wordpress
  • 利用 shell 脚本实现一键 docker
  • 安装 docker compose
  • 利用 docker compose 部署 wordpress

    0 云计算运维工程师核心职能

    image.png

    0.1 运维自动化发展历程及技术应用

    实现LNMP个人博客(手动部署&自动化部署&容器部署) - 图2

    0.2 云服务三种模式

    0.2.1 laaS 基础架构即服务

    云基础架构服务称为基础架构即服务(laaS) , laaS通过虚拟化技术为组织提供云计算基础架构,包括服务器、网络,操作系统和存储等。这些云服务器通常通过仪表盘或API提供给客户端,laaS客户端可以完全控制整个基础架构。laaS提供与传统数据中心相同的技术和功能,而无需对其进行物理上的维护或管理。laaS客户端仍然可以直接访问其服务器和存储,但它们都通过云中的“虚拟数据中心”
    如果是初创公司或小公司,laaS是一个很好的选择,欧此不必花费时间或金钱来创建硬件和软件。有些大型组织希望完全控制其应用程序和基础架构,同时又想仅购买实际消耗或需要的硬件, laaS对他们也是有益的

    0.2.2 PaaS 平台即服务

    云平台服务称为平台即服务(PaaS),为某些软件提供云组件,这些组件主要用于应用程序。PaaS为开发人员提供了一个框架,使他们可以基于它创建自定义应用程序。所有服务器,存储和网络都可以由企业或第三方提供商进行管理,而开发人员可以负责应用程序的管理
    PaaS提供一个软件创建平台。该平台一般通过Web方式提供,使开发人员可以自由地专注于创建软件,同时不必担心操作系统、软件更新,存储或基础架构。如果有多个开发人员在同一个开发项目上工作,或者必须包含其他供应商,PaaS可以为整个过程提供极大的速度和灵活性。如果希望能够创建自己的自定义应用程序,PaaS也是有益的。云服务还可以大大降低成本,并且可以简化在快速开发或部署应用程序时出现的一些挑战

    0.2.3 SaaS 软件即服务

    软件即服务,也称为云应用程序服务,SaaS利用互联网向其用户提供应用程序,这些应用程序由第三方供应商管理。大多数SaaS应用程序直接通过Web浏览器运行,不需要在客户端进行任何下载或安装。
    SaaS通过大大减少安装,管理和升级软件等繁琐任务所花费的时间和金钱,为员工和公司提供了许多好处。这让技术人员可以花更多时间来处理组织内更紧迫的事情和问题。
    SaaS在许多场景中很有用的,比如:初创公司或小公司,需要快速启动电子商务,没有时间处理服务器问题或软件,适用于需要协作的短期项目,需要不常用的应用程序,适用于需要通过Web和移动访问的应用程序

    0.3 Cobbler

0.3.1 Cobbler 简介

Cobbler是一款Linux生态的自动化运维工具,基于Python2开发,用于自动化批量部署安装操作系统;其提供基于CLI的管理方式和WEB配置界面,其中WEB配置界面是基于Python2和Django框架开发。另外,cobbler还提供了API,方便二次开发。Cobbler属于C/S模型(客户端/服务器模型)
Cobbler主要用于快速网络安装linux操作系统,支持众多的Linux发行版如:Red Hat、Fedora、CentOS、Debian、Ubuntu和SuSE等,甚至支持 Windows的安装
Cobbler 实质是PXE的二次封装,将多种安装参数封装到一起,并提供统一的管理方法
CentOS 8目前还没有提供Cobbler相关包

0.3.2 Cobbler 的相关服务

使用Cobbler安装系统需要一台专门提供各种服务的服务器,提供的服务包括(HTTP/FTP/NFS,
TFTP,DHCP),也可以将这几个服务分别部署到不同服务器。事实上在实际应用中,总是将不同的服务分别
部署到专门的服务器。
Cobbler是在HTTP、TFTP、DHCP等各种服务的基础上进行相关操作的,实际安装的大体过程类似于基
于PXE的网络安装:客户端(裸机)开机使用网卡引导启动,其请求DHCP分配一个地址后从TFTP服务器获取
启动文件,加载到客户端本地内存中运行,并显示出可安装的系统列表;在人为的选定安装的操作系统类
型后,客服端会到HTTP服务器下载相应的系统安装文件并执行自动安装

0.3.3 Cobbler 的工作原理

实现LNMP个人博客(手动部署&自动化部署&容器部署) - 图3

  • client裸机配置了从网络启动后,开机后会广播包请求DHCP服务器(cobbler server)发送其分配好的一个IP
  • DHCP服务器(cobbler server)收到请求后发送responese,包括其ip地址
  • client裸机拿到ip后再向cobbler server发送请求OS引导文件的请求
  • cobbler server告诉裸机OS引导文件的名字和TFTP server的ip和port
  • client裸机通过上面告知的TFTP server地址通信,下载引导文件
  • client裸机执行执行该引导文件,确定加载信息,选择要安装的os,期间会再向cobbler server请求kickstart文件和os image
  • cobbler server发送请求的kickstart和os iamge
  • client裸机加载kickstart文件
  • client裸机接收os image,安装该os image

    0.3.4 Cobbler 实现

    设置VMware Workstation DHCP 服务关闭
    image.png
    虚拟机:用软件(如Vmware,Virtualbox等)模拟硬件,方便实验的灵活配置
    image.png
    虚拟化软件,建议使用Vmware Workstation

CPU:默认,2核或者更多
内存:1G以上,推荐2G
硬盘:一块硬盘,200G
网卡:桥接或者仅主机模式
光盘:挂载对应的版本的ISO文件
主分区+扩展分区<=4
逻辑分区属于扩展分区中的小的分区。

打开虚拟化功能
在很多家用台式机和笔记本电脑上,虚拟化功能默认是关闭的,再要打开才能使用VMware等虚拟化软件,进入到对应的主板BIOS开启虚拟化功能。根据主板和处理器型号进行搜索解决。
Intel:Intel Virtualization Technology 虚拟化功能打开
AMD:SVM Mode 虚拟化功能打开

0.3.4.1 安装CentOS

初始化操作系统的分区计划 总容量为:200G / 100G —> xfs /boot 1G —> ext4 /data 50G —> xfs swap 2G

0.3.4.1.2 针对CentOS 8 创建虚拟机环境

打开VMware Workstation后创建虚拟机,根据安装虚拟机向导进行配置虚拟机安装

0.3.4.1.2 安装CentOS 8

根据操作系统的ISO镜像进行安装,安装配置根据向导进行安装。

0.3.4.2 安装Ubuntu

0.3.4.2.1 针对Ubuntu18.04 创建虚拟机环境

打开VMware Workstation后创建虚拟机,根据安装虚拟机向导进行配置虚拟机安装

0.3.4.2.2 安装Ubuntu18.04

根据操作系统的ISO镜像进行安装,安装配置根据向导进行安装。
注意:安装Ubuntu时一定要在安装中选择”安装 SSH 软件”

0.3.4.3 Linux系统目录结构

image.png

  • /bin:该目录是 Binaries(二进制文件)的缩写,这个目录是存放最经常使用的命令
  • /boot:该目录是存放启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件
  • /dev:该目录是 Device(设备)的缩写,该目录是存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。
  • /etc:该目录是存放所有系统管理所需要的配置文件和子目录
  • /home:用户的主目录,在Linux系统中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名。
  • /lib:该目录是 Library(库)的缩写,这个目录是存放系统最基本的动态连接共享库。
  • /lost+found:当系统非法关机后,就会存放相应的日志文件。
  • /mnt:系统提供该目录是为了让用户临时挂载别的文件系统。
  • /opt:系统给主机额外安装软件所摆放的目录
  • /proc:是 Processes(进程)的缩写,是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,这个目录是虚拟的目录,它是系统内存的映射,通过直接访问这个目录获取系统信息。
    这个目录的内容不在硬盘上而是在内存中,可以通过修改里面的某些文件,比如可以通过命令来屏蔽主机的ping命令,使得别人无法ping你的机器。

    1. echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
  • /root:该目录为系统管理员,也称作超级权限者的用户家目录

  • /run:是一个临时文件系统,存储系统启动以来的消息。当系统重启时,这个目录下的文件一个被删除和清除。
  • /sbin:s 是 Super User 的意思,是 Superuser Binaries(超级管理员的二进制文件)的缩写,这里存放的是系统管理员使用的系统管理程序。
  • /selinux:这个目录是 Redhat/CentOS 所特有的目录,Selinux 是一个安全机制,类似于Windows的防火墙。
  • /srv:该目录是存放一些服务启动之后需要提取的数据
  • /tmp:是 Temporary(临时)的缩写这个目录是用来存放一些临时文件的。
  • /sys:该文件系统是内核设备树的一个直观反映。当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。
  • /usr:是Unix Shared Resources(共享资源)的缩写,该目录是用户的很多用户程序和文件都存放的目录,类似于Windows下的 Program Files 目录。
  • /usr/bin:系统用户使用的应用程序
  • /usr/sbin:超级用户使用比较高级的管理程序和系统守护程序
  • /var:是 Variable(变量)的缩写,这个目前存放着不断扩充着的东西,包括各种日志文件。

    0.3.4.4 实现Cobbler 自动化安装

    0.3.4.4.1 环境准备
    两台主机:
    一台主机:centos 7 充当 Cobbler,Http,DHCP,TFTP 服务器,并关闭防火墙和SELinux
    一台主机:充当测试机,用于实现自动化安装Linux系统
    网络要求:
    关闭Vmware软件中的NAT模式中的DHCP服务两个主机网卡基于NAT模式
    0.3.4.4.2 安装相关包并启动服务
    范例: ```bash

    使用初始化脚本进行系统环境初始化

    ~ hostnamectl set-hostname cobbler-centos.kubesphere.com ~ yum repolist -v

~ wget https://mirrors.ustc.edu.cn/epel//epel-release-latest-7.noarch.rpm ~ rpm -Uvh epel-release-latest-7.noarch.rpm

~ yum install -y cobbler dhcp debmirror cobbler-web tftp-server xinetd kickstart ~ systemctl enable —now cobblerd httpd tftp dhcpd

<a name="Nlq0U"></a>
##### 0.3.4.4.3 修改 Cobbler 相关的配置
```bash
~ cobbler check
The following are potential configuration items that you may want to fix:

1 : The 'server' field in /etc/cobbler/settings must be set to something other than localhost, or kickstarting features will not work.  This should be a resolvable hostname or IP for the boot server as reachable by all machines that will use it.
2 : For PXE to be functional, the 'next_server' field in /etc/cobbler/settings must be set to something other than 127.0.0.1, and should match the IP of the boot server on the PXE network.
3 : change 'disable' to 'no' in /etc/xinetd.d/tftp
4 : Some network boot-loaders are missing from /var/lib/cobbler/loaders.  If you only want to handle x86/x86_64 netbooting, you may ensure that you have installed a *recent* version of the syslinux package installed and can ignore this message entirely.  Files in this directory, should you want to support all architectures, should include pxelinux.0, menu.c32, elilo.efi, and yaboot.
5 : enable and start rsyncd.service with systemctl
6 : debmirror package is not installed, it will be required to manage debian deployments and repositories
7 : The default password used by the sample templates for newly installed machines (default_password_crypted in /etc/cobbler/settings) is still set to 'cobbler' and should be changed, try: "openssl passwd -1 -salt 'random-phrase-here' 'your-password-here'" to generate new one
8 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them

Restart cobblerd and then run 'cobbler sync' to apply changes.

#生成密码的加密字符串
#生成新密码,默认安装好的系统root密码为cobbler
~ openssl passwd -1 'Admin@h3c'
$1$SETNblb7$51fVwrCFrIgo1Maun4lET/

#根据以上提示,只需要做1,2,8这三项即可,修改下面四行
#修改Cobbler配置文件
~ vim /etc/cobbler/settings
allow_dynamic_settings: 1
#大概在101行
default_password_crypted: "$1$SETNblb7$51fVwrCFrIgo1Maun4lET/"
#大概在242行
manage_dhcp: 1
#大概在278行
next_server: 10.0.0.110
#大概在390行
server: 10.0.0.110
#default_password_crypted "$1$SETNblb7$51fVwrCFrIgo1Maun4lET/"
#next_server: <tftp服务器的IP地址>
#server: <cobbler服务器的IP地址>
#manage_dhcp: 1 #设置为1,表示通过cobbler生成dhcpd.conf配置文件

systemctl restart cobblerd
systemctl enable --now rsyncd.service

### 需要禁用VMware的DHCP服务

0.3.4.4.4 实现 DHCP服务
#修改DHCP的模板文件下面的行,用来生成DHCP的配置文件
~ vim /etc/cobbler/dhcp.template
subnet 10.0.0.0 netmask 255.255.255.0 {
     option routers             10.0.0.2;
     option domain-name-servers 223.5.5.5,223.6.6.6;
     option subnet-mask         255.255.255.0;
     range dynamic-bootp        10.0.0.180 10.0.0.190;

~ cobbler sync
~ systemctl start dhcpd

0.3.4.4.5 下载启动的相关文件
~ cobbler get-loaders #必须联网操作下载
#在CentOS7.9版本以后就不支持使用该命令下载引导启动文件

~ cobbler sync
~ ls /var/lib/cobbler/loaders
~ tree /var/lib/tftpboot/
~ cobbler sync

0.3.4.4.6 修改菜单的标题信息(可选择)
~ vim /etc/cobbler/pxe/pxedefault.template
MENU TITLE Cobbler | http://www.kubesphere.com/

~ cobbler sync
~ cat /var/lib/tftpboot/pxelinux.cfg/default
DEFAULT menu
PROMPT 0
MENU TITLE Cobbler | http://www.kubesphere.com/
TIMEOUT 200
TOTALTIMEOUT 6000
ONTIMEOUT local

LABEL local
        MENU LABEL (local)
        MENU DEFAULT
        LOCALBOOT -1

MENU end

0.3.4.4.7 导入CentOS系统的安装文件,生成相应的YUM源

使用VMware 对该 Cobbler Server服务器导入光盘
image.png

~ for num in {1..3};do echo "- - -" >> /sys/class/scsi_host/host${num}/scan;done
~ lsblk | grep sr
sr0     11:0    1  9.5G  0 rom #CentOS7光盘
sr1     11:1    1  1.1G  0 rom #Ubuntu光盘
sr2     11:2    1 10.5G  0 rom #RockyLinux光盘

#导入RockyLinux的安装文件
~ mkdir /mnt/rockylinux
~ mount /dev/sr2 /mnt/rockylinux
~ cobbler import --name=rockylinux-8.6-x86_64 --path=/mnt/rockylinux --arch=x86_64
task started: 2022-06-30_163256_import
task started (id=Media import, time=Thu Jun 30 16:32:56 2022)
Found a candidate signature: breed=suse, version=sles15generic
Found a candidate signature: breed=suse, version=opensuse15.0
Found a candidate signature: breed=suse, version=opensuse15.1
Found a candidate signature: breed=redhat, version=rhel8
Found a matching signature: breed=redhat, version=rhel8
Adding distros from path /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64:
creating new distro: rockylinux-8.6-x86_64
trying symlink: /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64 -> /var/www/cobbler/links/rockylinux-8.6-x86_64
creating new profile: rockylinux-8.6-x86_64
associating repos
checking for rsync repo(s)
checking for rhn repo(s)
checking for yum repo(s)
starting descent into /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64 for rockylinux-8.6-x86_64
processing repo at : /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/AppStream
need to process repo/comps: /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/AppStream
looking for /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/AppStream/repodata/*comps*.xml
Keeping repodata as-is :/var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/AppStream/repodata
processing repo at : /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/BaseOS
need to process repo/comps: /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/BaseOS
looking for /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/BaseOS/repodata/*comps*.xml
Keeping repodata as-is :/var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/BaseOS/repodata
*** TASK COMPLETE ***

~ cobbler sync

#查看cobbler导入镜像
~ du -sh /var/www/cobbler/*
~ du -sh /var/www/cobbler/ks_mirror/*

#导入Ubuntu的安装文件(可选择)
~ mkdir /mnt/ubuntu
~ mount /dev/sr1 /mnt/ubuntu/
~ cobbler import --name=ubuntu-2004-x86_64 --path=/mnt/ubuntu/ --arch=x86_64
~ cobbler sync

#解决在 /var/www/cobbler/ks_mirror/fedora19-x86_64 !!! 中没有匹配的签名任务失败!!!
~ cobbler signature update
#然后它应该导入正常。您可能需要先删除 fedora19-x86_64 目录。

#查看
~ cobbler distro list 
   rockylinux-8.6-x86_64
   ubuntu-2004-casper-x86_64
~ cobbler profile list
   rockylinux-8.6-x86_64
   ubuntu-2004-casper-x86_64
#默认生成的是最小化安装

导入成功界面:
image.png

image.png
报错:No signature matched in /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64
image.png
解决方法:

~ cobbler signature update
~ rm -rf /var/www/cobbler/ks_mirror/rockylinux-8.6-x86_64/
#重新导入镜像
~ cobbler import --name=rockylinux-8.6-x86_64 --path=/mnt/rockylinux --arch=x86_64

0.3.4.4.8 准备 kickstart 文件,并关联至指定的YUM源
~ vim /var/lib/cobbler/kickstart/ks_for_ks_for_rockylinux.cfg
~ cat /var/lib/cobbler/kickstart/ks_for_ks_for_rockylinux.cfg
ignoredisk --only-use=sda
zerombr
text
reboot
clearpart --all --initlabel
selinux --disabled
firewall --disabled
url --url=$tree
keyboard --vckeymap=us--xlayouts='us'
lang en_US.UTF-8
network--bootproto=dhcp --device=ens160 --ipv6=auto --activste
network --hostname=rockylinux.kubesphere.com
rootpw --iscrypted $69FfPDZvWNP$ChTeYkWfpN.WNaLaezhTdNBhLN4oqV5fg0K3fEgRNBNWGeiuDLRagV8DcFUqi08PU840X9XRtynBSsrElIRNS/
firstboot --enable
skipx
services --disabled="chronyd"
timezone Asia/Shanghai --isUtc --nontp
user --name=wang --password=$6$oUfb/02CWfLb518f$sgEZeR7c7DpqfpmFEDH6huSmDbwLXOMNR4qK12EPms.gOXqLnAIgy$pTogtFVaDtEpMOC.SwXKYqxfVtd9MCwxb1 --iscrypted --gecos="wang"
part / --fstype="xfs" --ondisk=sda --size=102400
part /data --fstype="xfs" --ondisk=sda --size=51200
part swap --fstype="swap" --ondisk=sda --size=2048
part /boot --fstype="ext4" --ondisk=sda --size=1024
%packages
@^minimal-environment

kexec-tools
%end
%addon com redhat_kdump --enable --reserve-mb='auto'
%end
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
%post
useradd zzw
echo magedu | passwd --stdin zzw &> /dev/null
%end

#将kickstart文件,关联指定的YUM源和生成菜单列表
~ cobbler profile add --name=rockylinux-8.6_test --distro=rockylinux-8.6-x86_64 --kickstart=/var/lib/cobbler/kickstart/ks_for_ks_for_rockylinux.cfg
~ cobbler profile add --name=ubuntu-2004_test --distro=ubuntu-2004-casper-x86_64 --kickstart=/var/lib/cobbler/kickstart/ks_for_ks_for_ubuntu.cfg

#删除默认生成的菜单
cobbler profile remove --name=rockylinux-8.6-x86_64
cobbler profile remove --name=ubuntu-2004-casper-x86_64

#查看配置
cobbler profile list

#删除默认的菜单列表
cobbler profile remove --name=rockylinux-8.6-x86_64

0.3.4.4.9 测试客户端基于 Cobbler 实现自动安装

使用未插光盘的机器,开启使其识别 Cobbler 界面
image.png

1 WWW 万维网

  • 因特网:世界上最大的互联网网络。即因特网概念从属于互联网概念。互联网指的是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。
  • 万维网:www (world wide web)万维网是一个大规模的、联机式的信息贮藏所,使用链接的方法能非常方便地从因特网上的一个站点访问另一个站点(超链技术),具有提供分布式服务的特点。万维网是一个分布式的超媒体系统,是超文本系统的扩充,基于B/S架构。
  • HTML: HyperText Markup Language 超文本标记语言,用于实现不同用户创作的不同风格的方维网文档,都能在因特网上的各种主机上显示出来,同时使用户清楚地知道在什么地方存在着链接,万维网页面的设计者可以很方便地用链接从页面的某处链接到因特网的任何一个万维网页面,并且能够在自己的主机品目止将这些页面显示出来。HTML与txt一样,仅仅是是一种文档,不同之处在于,这种文档专供于浏览器上为浏览器用户提供统一的界面呈现的统一规约,且具备结构化的特征。
  • HTTP: HyperText Transfer Protocol,是用于实现整个因特网上的万维网文档的网络协议,万维网客户程序(以浏览器为主,但不限于浏览器)与方维网服务器程序之间的交互遵守严格的协议,这就是超文本传送协议()。HTTP是处于应用层的协议,使用TCP传输层协议进行可靠的传送。因此,需要特别提醒的是,万维网是基于因特网的一种广泛因特网应用系统,且万维网采用的是HTTP/HTTPS的传输协议

    1.1 HTTP 协议

    1980年代,Tim Berners-Lee为CERN(欧洲核子研究中心)开发了World Wide Web项目,打造了世界上第一个网站,于1991年8月6日正式上线。
    Tim Berners-Lee于1990年12月29日发明了第一个浏览器WorldWideWeb,还发明了HTTP协议。
    HTTP标准由万维网协会W3C和互联网工程任务组(IETF)制定,发布了一系列的相关的RFC,其中由1999年6月公布的RFC 2616定义了现今广泛使用的HTTP协议1.1版。

    1.2 HTTP服务器和客户端

  • 常见HTTP服务器程序

Apache:即Httpd,传统的http服务器,存在C10K问题(C10K:最大并发达到一万)
Nginx:性能优秀,主流互联网公司采有,解决C10K问题
Tomcat:应用程序服务器,处理jsp程序
IIS:微软公司的应用程序服务器,处理asp程序
HTTP服务器市场占有率统计: http://www.netcraft.com

  • 常见HTTP客户端(浏览器)
  1. Chrome
  2. Firefox
  3. Safari
  4. Edge / IE

浏览器市场占有率统计: https://gs.statcounter.com/
image.png

1.3 WEB资源

image.png
WEB资源类型:

  • 静态资源:原始形式与响应内容一致,在客户端浏览器执行
  • 动态资源:原始形式通常为程序文件,需要在服务器端执行之后,将执行结果返回给客户端

注意:静态和动态的区别,不在于网页是否能动态变化,而在于服务端的页面文件和客户端得到页面文件是否一致
Web相关语言
客户端技术: html,JavaScript,css, jpg
服务器端技术: php, jsp, python,asp, JavaScript (Node.js)
范例:php动态资源

~ cat > /var/www/html/php.php <<EOF
<?php
phpinfo();
?>

2 PHP 简介

PHP官网: http://www.php.net/
PHP是通用服务器端脚本编程语言,主要用于web开发实现动态web页面,也是最早实现将脚本嵌入HTML源码文档中的服务器端脚本语言之一。同时,php还提供了一个命令行接口,因此,其也可以在大多数系统上作为一个独立的shell来使用。
Rasmus Lerdorf 于 1994年开始开发PHP,最初是一组被 Rasmus Lerdorf 称作 “Personal Home Page Tool”的 Perl 脚本,可以用于显示作者的简历并记录用户对其网站的访问。后来,Rasmus Lerdorf使用C语言将这些 Perl 脚本重写为CGI程序,还为其增加了运行Web forms的能力以及与数据库交互的特性,并将其重命名为”PersonalHome Page/Forms Interpreter”或”PHP/FI”。此时,PHP/FI 已经可以用于开发简单的动态web 程序了,这即PHP1.0。1995年6月,Rasmus Lerdorf 把它的 PHP 发布于comp.infosystems.www.authoring.cgi Usenet讨论组,从此PHP开始走进人们的视野。1997年,其2.0版本发布
1997年,两名以色列程序员Zeev Suraski和Andi Gutmans重与的PHP的分析器(parser)成为PHP发展到3.0的基础,而且从此将PHP重命名为PHP: Hypertext Preprocessor。此后,这两名程序员开始重写整个PHP核心,并于1999年发布了Zend Engine 1.0,这也意味着PHP4.0的诞生。2004年7月,Zend Engine 2.0发布,由此也将PHP带入了PHP 5时代。PHP5包含了许多重要的新特性,如增强的面向对象编程的支持、支持PDO(PHP Data Objects)扩展机制以及一系列对PHP性能的改进
Zend Engine是开源的、PHP脚本语言的解释器,它最早是由以色列理工学院(Technion)的学生Andi Gutmans 和 zeev Suraski所开发,Zend 也正是此二人名字的合称。后来两人联合创立了Zend Technologies公司
Zend Engine 1.0于1999年随PHP4发布,由C语言开发且经过高度优化,并能够做为PHP的后端模块使用。ZendEngine为PHP提供了内存和资源管理的功能以及其它的一些标准服务,其高性能、可靠性和可扩展性在促进 PHP 成为一种流行的语言方面发挥了重要作用。
Zend Engine的出现将PHP代码的处理过程分成了两个阶段:首先是分析PHP代码并将其转换为称作Zend opcode的二进制格式opcode(类似Java的字节码),并将其存储于内存中;第二阶段是使用Zend Engine去执行这些转换后的Opcode


PHP 各种版本官方支持时间:
https://www.php.net/supported-versions.php
image.png

3 LAMP

3.1 传统LAMP 架构

image.png
LAM(M)P:
L: linux
A: apache (httpd)
M: mysql, mariadb
M: memcached
P: php, perl, python

3.2 LAMP 工作原理

image.png
image.png

CGI 和 FastCGI 协议可以让 Apache 或者 Web服务把动态请求转发到后端处理动态页面的服务器。

3.3 CGI 和 FastCGI

3.3.1 CGI

CGl: Common Gateway Interface公共网关接口
CG在2000年或更早的时候用得比较多,以前web服务器一般只处理静态的请求,如果碰到一个动态请求怎么办呢? web服务器会根据这次请求的内容,然后会fork一个新进程来运行外部c程序(或bash,perl脚本等),这个进程会把处理完的数据返回给web服务器,最后web服务器把内容发送给用户,刚才fork的进程也随之退出。如果下次用户还请求改动态脚本,那么web服务器又再次fork一个新进程,周而复始的进行。
CGI可以让一个客户端,从网页浏览器通过http服务器向执行在网络服务器上的程序传输数据;CGI描述了客户端和服务器程序之间传输的一种标准
请求流程:
Client — (http协议) —> httpd — (cgi协议)—>application server (program file) —(mysql协议) —>mysql

3.3.2 FastCGI

FastCGI 的方式是,web服务器收到一个请求时,不会重新fork一个进程(因为这个进程在web服务器启动时就开启了,而且不会退出),web服务器直接把内容传递给这个进程(进程间通信,但 FastCGI 使用了别的方式, tcp方式通信),这个进程收到请求后进行处理,把结果返回给web服务器,最后自己接着等待下一个请求的到来,而不是退出。FastCGI 的默认端口是9000端口
请求流程:
Client — (http协议) —> httpd — (FastCGI协议) —>FastCGI 服务器—(mysql协议) —> mysql

3.3.3 CGI 和 FastCGI

image.png

CGI 协议,相当于Apache激活了 CGI的进程(是Apache的子进程),子进程处理完毕后就销毁了,下一个用户请求时就会又开启。就会频繁的消耗机器的资源性能。会使得CPU从该进程切换到另一个进程,频繁的进行上下文切换。 简单理解:CGI是依附于Apache的子进程,而FastCGI则是独立的服务。

名称 在web服务器方面 在对数据进行处理的进程方面
CGI fork一个新的进程进行处理 读取参数,处理数据,然后就结束生命期
FastCGI 用tcp方式跟远程机子上的进程或本地进程建立连接 要开启tcp端口,进入循环,等待数据的到来,处理数据

4 LNMP

image.png

4.1 Wordpress

  • WordPress是一个免费的开源PHP软件项目,GNU通用公共许可证授权发布。WordPress是世界上使用最广泛的博客系统之一
  • WordPress不仅仅是一个博客程序,也是一款CMS(内容管理系统),很多非博客网站也是用WordPress搭建的。
  • 使用WordPress平台的发行商约占全球网站的10%。而WordPress官方网站的每月独立访问用户数则达到3亿。
  • WordPress因为使用者众多,所以WordPress社区非常活跃,有丰富的插件模板资源,有许多第三方开发的免费模板,使用WordPress可以快速搭建独立的博客网站。
  • 官网: https://cn.wordpress.org/download/

    4.2 手动部署 LNMP

    4.2.1 利用程序包手动部署 Wordpress

    环境准备:

    一台 RockyLinux | CentOS 8 最小化安装 禁用SELinux ,禁用防火墙 配置 yum 源(阿里源 & 清华源)

  1. 安装相关包

    #LNMP服务器
    yum install -y nginx php-fpm php-json php-mysqlnd mariadb-server
    #数据库服务器
    yum install -y mariadb-server
    
  2. 准备 wordress 文件和设置权限

    wget https://cn.wordpress.org/latest-zh_CN.tar.gz
    tar -xvf latest-zh_CN.tar.gz
    mv wordpress/* /usr/share/nginx/html
    #避免在后续上传资源会报错
    chown -R nginx:nginx /usr/share/nginx/html/
    
  3. 配置 nginx 服务

    vim /etc/nginx/nginx.conf
    ......
         location / {
             index index.php;
         }
         location ~ \.php$ {
             root            /usr/share/nginx/html;
             fastcgi_pass    127.0.0.1:9000;
             fastcgi_index   index.php;
             fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
             include         fastcgi_params;
         }
    ......
    
  4. 配置 php-fpm 服务

    vim /etc/php-fpm.d/www.conf
    ......
    user = nginx
    group = nginx
    ......
    listen = /run/php-fpm/www.sock #默认使用的套接字
    
  5. 启动相关服务

    ~ systemctl enable --now nginx php-fpm
    #查看服务是否启动
    #确保nginx , php-fpm 服务成功启动
    ~ systemctl is-active nginx php-fpm
    active
    active
    #查看服务端口
    #查看是否打开相应的端口
    ~ ss -tunlp
    
  6. 准备数据库和用户及权限 ```bash

    数据库服务器

    ~ systemctl enable —now mariadb

    systemctl start mariadb ; systemctl enable mariadb

数据库加固

~ mysql_secure_installation Set root password? [Y/n] y New password: kubesphere Re-enter new password: kubesphere

Remove anonymous users? [Y/n] y Disallow root login remotely? [Y/n] y Remove test database and access to it? [Y/n] y Reload privilege tables now? [Y/n] y

~ mysql -uroot -pkubesphere

create database wordpress; grant all on wordpress.* to wordpress@’10.0.0.%’ identified by ‘kubesphere’; exit

~ mysql -uwordpress -pkubesphere -h10.0.0.51 MariaDB [(none)]> show databases; +——————————+ | Database | +——————————+ | information_schema | | wordpress | +——————————+ 2 rows in set (0.002 sec)


7. 浏览器访问
```bash
curl 10.0.0.50
#浏览器打开 10.0.0.50

image.png
设置 Wordpress 的数据库信息
image.png
设置Wordpress 的后台管理员账号和密码
image.png
登录 Wordpress 的后台管理系统
image.png

  1. 网站加速 ```bash ~ yum install -y httpd-tools

    -c 10:同时模拟10个浏览器发起连接并且并发10个连接

    -n 100:总共访问100次

    ~ ab -c 10 -n 100 http://10.0.0.50/ This is ApacheBench, Version 2.3 <$Revision: 1843412 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.0.0.50 (be patient)…..done

Server Software: nginx/1.14.1 Server Hostname: 10.0.0.50 Server Port: 80

Document Path: / Document Length: 30509 bytes

Concurrency Level: 10 Time taken for tests: 7.001 seconds Complete requests: 100 Failed requests: 0 Total transferred: 3074300 bytes HTML transferred: 3050900 bytes Requests per second: 14.28 [#/sec] (mean) #主要查看该指标 Time per request: 700.112 [ms] (mean) Time per request: 70.011 [ms] (mean, across all concurrent requests) Transfer rate: 428.82 [Kbytes/sec] received

Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 0.8 1 5 Processing: 337 667 244.2 631 1891 Waiting: 233 574 239.7 528 1796 Total: 338 668 244.1 636 1893

Percentage of the requests served within a certain time (ms) 50% 636 66% 704 75% 744 80% 789 90% 851 95% 1215 98% 1639 99% 1893 100% 1893 (longest request)

~ yum install -y php-opcache ~ rpm -ql php-opcache ~ head /etc/php.d/10-opcache.ini

~ systemctl restart php-fpm

再次测试,性能提升明显

~ ab -c 10 -n 100 http://10.0.0.50/ This is ApacheBench, Version 2.3 <$Revision: 1843412 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.0.0.50 (be patient)…..done

Server Software: nginx/1.14.1 Server Hostname: 10.0.0.50 Server Port: 80

Document Path: / Document Length: 30509 bytes

Concurrency Level: 10 Time taken for tests: 3.160 seconds Complete requests: 100 Failed requests: 0 Total transferred: 3074300 bytes HTML transferred: 3050900 bytes Requests per second: 31.65 [#/sec] (mean) #主要查看该指标 Time per request: 315.990 [ms] (mean) Time per request: 31.599 [ms] (mean, across all concurrent requests) Transfer rate: 950.11 [Kbytes/sec] received

Connection Times (ms) min mean[+/-sd] median max Connect: 0 2 1.2 1 7 Processing: 134 270 61.0 269 488 Waiting: 92 213 56.1 213 398 Total: 136 272 60.9 269 489

Percentage of the requests served within a certain time (ms) 50% 269 66% 297 75% 310 80% 318 90% 353 95% 373 98% 440 99% 489 100% 489 (longest request)


9. 网站安全加固
```bash
#版本暴露会带来安全隐患
~ curl -I http://10.0.0.50/
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 30 Jun 2022 03:22:17 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.24
Link: <http://10.0.0.50/index.php/wp-json/>; rel="https://api.w.org/"

#LNMP服务器网站安全加固
~ vim /etc/nginx/nginx.conf
......
http {
    server_tokens off;
}
......

~ vim /etc/php.ini
#修改下面一行
expose_php = Off
~ systemctl restart nginx php-fpm

#再次查看版本已隐藏
~ curl -I http://10.0.0.50/
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 30 Jun 2022 03:31:05 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Link: <http://10.0.0.50/index.php/wp-json/>; rel="https://api.w.org/"

4.2.2 手动编译安装LNMP实现 wordpress

  1. 环境准备
  • 两台CentOS7主机
  • 一台提供LNP
  • 一台提供MySQL
  • 都禁用SELinux和防火墙

准备相关安装包

  1. 二进制安装 MySQL 5.7 ```bash

    第一台主机实现MySQL

    ~ hostnamectl set-hostname mysql-server ~ tar -xf mysql-5.7.29-el7-x86_64.tar.gz -C /usr/local/ ~ ln -sv /usr/local/mysql-5.7.29-el7-x86_64/ /usr/local/mysql ~ chown -R root:root /usr/local/mysql ~ useradd -s /sbin/nologin -c “MySQL User” mysql ~ yum install -y numactl-libs libaio

~ echo “PATH=/usr/local/mysql/bin/:$PATH” > /etc/profile.d/mysql.sh ~ . /etc/profile.d/mysql.sh ~ cat > /etc/my.cnf <<-EOF [mysqld] server-id=1 log-bin datadir=/data/mysql socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log pid-file=/data/mysql/mysql.pid

[client] socket=/data/mysql/mysql.sock EOF

~ mysqld —initialize —user=mysql —datadir=/data/mysql ~ cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld ~ chkconfig —add mysqld ; chkconfig mysqld on ~ service mysqld start Starting MySQL. SUCCESS!

查看并修改root密码

~ MYSQL_OLDPASSWORD=awk '/A temporary password/{print $NF}' /data/mysql/mysql.log ~ echo $MYSQL_OLDPASSWORD ec04o,>aC*ot

~ mysqladmin -uroot -p$MYSQL_OLDPASSWORD password kubesphere ~ mysql -uroot -pkubesphere mysql> create database wordpress; mysql> grant all on wordpress.* to wordpress@’10.0.0.%’ identified by ‘kubesphere’;

![image.png](https://cdn.nlark.com/yuque/0/2022/png/2555283/1656848388852-5d389071-f90e-4511-b346-c2bf753a0f12.png#clientId=ub9a6b58c-64c9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=426&id=u71ff66f6&name=image.png&originHeight=426&originWidth=1024&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46217&status=done&style=none&taskId=u46d2bd4f-8889-4002-a8f6-c2d5e271e27&title=&width=1024)

3. 编译安装 nginx
```bash
#在第二台主机上实现Nginx
~ useradd -s /sbin/nologin -r -c "Nginx User" nginx
~ yum install -y gcc gcc-c++ pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
~ tar -xf nginx-1.16.1.tar.gz -C /usr/local/src/
~ ln -sv /usr/local/src/nginx-1.16.1 /usr/local/src/nginx

#编译安装nginx
~ cd /usr/local/src/nginx
~ ./configure --prefix=/apps/nginx \
--user=nginx --group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_perl_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module

~ make -j 2 && make install 
~ cd && mkdir -pv /data/www/
~ cat > /apps/nginx/conf/nginx.conf <<EOF
worker_processes  auto;
events {
    worker_connections  10240;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;
    log_format  main  '\$remote_addr - \$remote_user [\$time_local] "\$request" '
    sendfile        on;
    client_max_body_size 100m;
    keepalive_timeout  65;
    server {
        listen       80 default_server;
        server_name  localhost ; 
        root /data/www ;
        access_log  logs/nginx.access.log  main;
        location / {
            root   /data/www/;
            index  index.php index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location ~ \.php$ {
            root           /data/www;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  \$document_root\$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
}
EOF

~ echo 'PATH=/apps/nginx/sbin:$PATH' >> /etc/profile.d/lamp.sh
~ cat > /usr/lib/systemd/system/nginx.service <<EOF
[Unit]
After=network.target remote-fs.target nss-lookup.target 

[Service]
Type=forking 
ExecStart=/apps/nginx/sbin/nginx
ExecReload=/apps/nginx/sbin/nginx -s reload
ExecStop=/apps/nginx/sbin/nginx -s stop

[Install]
WantedBy=multi-user.target
EOF

~ systemctl daemon-reload
~ systemctl enable --now nginx ; systemctl status nginx
  1. 编译安装 fastcgi 方式的 php7.4 ```bash

    在第二台主机上实现php

    ~ yum -y install gcc make libxml2-devel bzip2-devel libmcrypt-devel libsqlite3x-devel oniguruma-devel ~ tar -xf php-7.4.8.tar.xz -C /usr/local/src/ ~ ln -sv /usr/local/src/php-7.4.8 /usr/local/src/php

编译安装php

~ cd /usr/local/src/php ~ ./configure —prefix=/apps/php74 \ —enable-mysqlnd —with-mysqli=mysqlnd —with-pdo-mysql=mysqlnd \ —with-openssl —with-zlib —with-config-file-path=/etc \ —with-config-file-scan-dir=/etc/php.d \ —enable-mbstring —enable-xml —enable-sockets \ —enable-fpm —enable-maintainer-zts —disable-fileinfo

~ make -j 4 && make install ~ cp php.ini-production /etc/php.ini ~ mkdir -p /etc/php.d/

配置PHP网站加速

~ cat > /etc/php.d/opcache.ini <<EOF [opcache] zend_extension=opcache.so
opcache.enable=1 EOF

~ cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/ ~ cd /apps/php74/etc ~ cp php-fpm.conf.default php-fpm.conf ~ cd php-fpm.d/ ~ cp www.conf.default www.conf ~ sed -i.bak -e ‘s/^user./user = nginx/‘ -e ‘s/^group./group = nginx/‘ /apps/php74/etc/php-fpm.d/www.conf ~ systemctl daemon-reload ~ systemctl enable —now php-fpm ; systemctl status php-fpm

配置PATH变量

~ echo ‘PATH=/apps/php74/bin:$PATH’ > /etc/profile.d/php.sh ~ . /etc/profile.d/php.sh ~ php —version PHP 7.4.8 (cli) (built: Jul 3 2022 19:54:31) ( ZTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.8, Copyright (c), by Zend Technologies

确保相应的端口已经打开

~ ss -ntlp


5. 准备 wordpress 文件
```bash
~ tar -xf wordpress-6.0-zh_CN.tar.gz
~ mv wordpress/* /data/www/
~ chown -R nginx.nginx /data/www/
  1. 测试访问
    #打开浏览器访问第二台主机
    http://LNMP服务器/
    
    image.png
    image.png
    image.png
    image.png

    4.3 利用脚本实现一键部署 wordpress

    4.3.1 脚本实现一键部署 wordpress

    注意:本脚本只针对CentOS 7测试完成,其他版本的Linux可能需要修改后才能适配 ```bash

    !/bin/bash

    Description: LNMP wordpress 博客系统

    SRC_DIR=/usr/local/src NGINX=’nginx-1.18.0.tar.gz’ MYSQL=’mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz’ PHP=’php-7.4.10.tar.xz’ APP=’wordpress-5.6.2-zh_CN.tar.gz’ COLOR=”echo -e \033[01;31m” END=’\033[0m’ MYSQL_ROOT_PASSWORD=laowang MYSQL_WORDPRESS_PASSWORD=laowang CPU=lscpu| awk '/^CPU\(s\):/{print $NF}'

${COLOR}’开始安装基于LNMP的wordpress’$END sleep 3

check_file (){ cd $SRC_DIR $COLOR”请将相关软件放在${SRC_DIR}目录下”$END if [ ! -e $NGINX ];then $COLOR”缺少${NGINX}文件”$END exit elif [ ! -e $MYSQL ];then $COLOR”缺少${MYSQL}文件”$END exit elif [ ! -e $PHP ];then $COLOR”缺少${PHP}文件”$END exit elif [ ! -e $APP ];then $COLOR”缺少${APP}文件”$END exit else $COLOR”相关文件已准备好”$END fi } install_mysql(){ $COLOR”开始安装MySQL数据库”$END cd $SRC_DIR tar xf $MYSQL -C /usr/local/ if [ -e /usr/local/mysql ];then $COLOR”数据库已存在,安装失败”$END exit fi MYSQL_DIR=echo $MYSQL| sed -nr 's/^(.*[0-9]).*/\1/p' ln -s /usr/local/$MYSQL_DIR /usr/local/mysql chown -R root.root /usr/local/mysql/ id mysql &> /dev/null || { useradd -s /sbin/nologin -r mysql ; $COLOR”创建mysql用户”$END; } yum -y -q install numactl-libs libaio &> /dev/null

echo 'PATH=/usr/local/mysql/bin/:$PATH' > /etc/profile.d/lamp.sh
.  /etc/profile.d/lamp.sh
cat > /etc/my.cnf <<-EOF

[mysqld] server-id=1 log-bin datadir=/data/mysql socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log pid-file=/data/mysql/mysql.pid [client] socket=/data/mysql/mysql.sock EOF [ -d /data ] || mkdir /data mysqld —initialize —user=mysql —datadir=/data/mysql cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld chkconfig —add mysqld chkconfig mysqld on service mysqld start [ $? -ne 0 ] && { $COLOR”数据库启动失败,退出!”$END;exit; } MYSQL_OLDPASSWORD=awk '/A temporary password/{print $NF}' /data/mysql/mysql.log mysqladmin -uroot -p$MYSQL_OLDPASSWORD password $MYSQL_ROOT_PASSWORD &>/dev/null $COLOR”数据库安装完成”$END }

install_nginx(){ ${COLOR}”开始安装NGINX”$END id nginx &> /dev/null || { useradd -s /sbin/nologin -r nginx; $COLOR”创建nginx用户”$END; } $COLOR”安装nginx相关包”$END yum -q -y install gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed git &> /dev/null cd $SRC_DIR tar xf $NGINX

git clone https://github.com/openresty/echo-nginx-module.git || { $COLOR”下载NGINX第三方模块失败,退出!”$END;exit; }

NGINX_DIR=echo $NGINX| sed -nr 's/^(.*[0-9]).*/\1/p' cd $NGINX_DIR ./configure —prefix=/apps/nginx —user=nginx —group=nginx —with-http_ssl_module —with-http_v2_module —with-http_realip_module —with-http_stub_status_module —with-http_gzip_static_module —with-http_perl_module —with-pcre —with-stream —with-stream_ssl_module —with-stream_realip_module make -j $CPU && make install [ $? -eq 0 ] && $COLOR”NGINX编译安装成功”$END || { $COLOR”NGINX编译安装失败,退出!”$END;exit; } [ -d /data/www ] || mkdir -pv /data/www/ cat > /apps/nginx/conf/nginx.conf <> /etc/profile.d/lamp.sh cat > /usr/lib/systemd/system/nginx.service <<EOF [Unit] After=network.target remote-fs.target nss-lookup.target

[Service] Type=forking

ExecStart=/apps/nginx/sbin/nginx

ExecReload=/apps/nginx/sbin/nginx -s reload

ExecStop=/apps/nginx/sbin/nginx -s stop

[Install] WantedBy=multi-user.target EOF

systemctl daemon-reload
systemctl start nginx 
systemctl is-active nginx &> /dev/null ||  { $COLOR"NGINX 启动失败,退出!"$END ; exit; }
$COLOR"NGINX安装完成"

} install_php (){ ${COLOR}”开始安装PHP”$END yum -y -q install gcc make libxml2-devel bzip2-devel libmcrypt-devel libsqlite3x-devel oniguruma-devel &>/dev/null cd $SRC_DIR tar xf $PHP PHP_DIR=echo $PHP| sed -nr 's/^(.*[0-9]).*/\1/p' cd $PHP_DIR ./configure —prefix=/apps/php74 —enable-mysqlnd —with-mysqli=mysqlnd —with-pdo-mysql=mysqlnd —with-openssl —with-zlib —with-config-file-path=/etc —with-config-file-scan-dir=/etc/php.d —enable-mbstring —enable-xml —enable-sockets —enable-fpm —enable-maintainer-zts —disable-fileinfo make -j $CPU && make install [ $? -eq 0 ] && $COLOR”PHP编译安装成功”$END || { $COLOR”PHP编译安装失败,退出!”$END;exit; } cp php.ini-production /etc/php.ini mkdir /etc/php.d/ cat > /etc/php.d/opcache.ini <<EOF [opcache] zend_extension=opcache.so
opcache.enable=1 EOF

cp  sapi/fpm/php-fpm.service /usr/lib/systemd/system/
cd /apps/php74/etc
cp  php-fpm.conf.default  php-fpm.conf
cd  php-fpm.d/
cp www.conf.default www.conf
id nginx  &> /dev/null || { useradd -s /sbin/nologin -r  nginx; $COLOR"创建nginx用户"$END; }
sed -i.bak  -e  's/^user.*/user = nginx/' -e 's/^group.*/group = nginx/' /apps/php74/etc/php-fpm.d/www.conf
systemctl daemon-reload
systemctl start php-fpm 
systemctl is-active  php-fpm &> /dev/null ||  { $COLOR"PHP-FPM 启动失败,退出!"$END ; exit; }
$COLOR"PHP安装完成"

} install_wordpress(){ cd $SRC_DIR tar xf $APP
[ -d /data/www ] || mkdir -pv /data/www mv wordpress/ /data/www/ chown -R nginx.nginx /data/www/wp-content/ cd /data/www/ mv wp-config-sample.php wp-config.php mysql -uroot -p”$MYSQL_ROOT_PASSWORD” -e “create database wordpress;grant all on wordpress. to wordpress@’127.0.0.1’ identified by ‘$MYSQL_WORDPRESS_PASSWORD’” &>/dev/null sed -i.bak -e ‘s/database_name_here/wordpress/‘ -e ‘s/username_here/wordpress/‘ -e ‘s/password_here/‘’’$MYSQL_WORDPRESS_PASSWORD’’’/‘ -e ‘s/localhost/127.0.0.1/‘ wp-config.php $COLOR”WORDPRESS安装完成” }

check_file

install_mysql

install_nginx

install_php

install_wordpress

<a name="fkTBz"></a>
### 4.3.2 互联网运行脚本部署 Wordpress
注意:本脚本只针对CentOS7 测试完成,其它版本的Linux可能需要修改后才能适配 
```bash
curl -s http://www.wangxiaochun.com/testdir/wordpress_lnmp_for_centos7.sh | bash

5 DevOps 和 CICD

之前使用方式大部分是手动部署,该小节以后将使用自动化的方式进行部署。之前的部署一直是系统提供的版本,用户无法选择合适的版本。 在生产环境中基于安全,基于某些功能需要,安装的方式可能会是编译安装。需要将所需的源码编译成二进制。并且将该操作实现自动化。

5.1 DevOps 和 CICD 简介

DevOps是一种思想,是一种文化,主要强调软件开发测试运维的一体化,目标是减少各个部门之间的沟通成本从而实现软件的快速高质量的发布。
CICD:持续集成、交付和部署,是一套流程实现软件的构建测试部署的自动化。
DevOps与CICD紧密相关,是理论与实践的结合,DevOps要实现人员一体化,必须要借助CICD工具来自动化整个流程。
image.png

5.2 CICD 相关工具

image.png

6 Ansible

6.1 Ansible 应用场景

公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备。公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运维老大为了在年底有所表现,要求运维部门同学尽快实现,当你接到这个任务时,有没有更快的解决方案?

6.2 Ansible 介绍

  • 作者: Michael DeHaan ( Cobbler 与 Func作者)
  • Ansible的名称来自科幻小说《安德的游戏》中跨越时空的即时通信工具,使用它可以在相距数光年的距离,远程实时控制前线的舰队战斗
  • 2012-03-09,发布0.0.1版
  • 2015-10-17,Red Hat宣布1.5亿美元收购官网: https://www.ansible.com/
  • 官方文档: https://docs.ansible.com/

    Ansible 只需要在管理端安装软件,被管理端不需要安装软件 而 SaltStack 需要在管理端和被管理端分别安装服务端和客户端软件

6.3 Ansible 架构

image.png

  • HOSTS:被管理端,可以管理Linux系统和Windows系统,以及是各种网络设备
  • NETWORKING:可以管理网络设备(交换机设备,路由器设备)

组合 INVENTORY、API、MODULES、PLUGINS的绿框,可以理解为是 ansible 命令工具,其为核心执行工具。

  • INVENTORY:Ansible 管理主机的清单 /etc/ansible/hosts
  • MODULES:Ansible 执行命令的功能模块,多数为内置核心模块,也可自定义
  • PLUGINS:模块功能的补充,如连接类型插件,循环插件,变量插件,过滤插件等,该功能不常用
  • API:供第三方程序调用的应用程序编程接口

    6.4 利用 Ansible 实现自动化部署 Wordpress

    目前该Ansible 实现是在 CentOS 8 & RockyLinux 操作系统中。

6.4.1 利用脚本批量实现 ssh 服务基于 key 验证

~ sed -i -r '/StrictHostKeyChecking/s|.*|StrictHostKeyChecking no|ig' /etc/ssh/ssh_config

~ cat > hosts.list <<EOF
10.0.0.51
10.0.0.52
EOF

~ vim ssh_key_push.sh
#!/bin/bash
#当前用户的密码
PASS="magedu"
#设置网段最小和最大的地址的尾数
BEGIN=3
END=254

IP=$(ip addr show eth0 | awk -F'[ /]+' 'NR==3{print $3}')
NET=${IP%.*}.

. /etc/os-release

function color()
{
  RES_COL=60;
  MOVE_TO_COL="echo -en \\033[${RES_COL}G";
  SETCOLOR_SUCCESS="echo -en \\033[1;32m";
  SETCOLOR_FAILURE="echo -en \\033[1;31m";
  SETCOLOR_WARNING="echo -en \\033[1;33m";
  SETCOLOR_NORMAL="echo -en \E[0m";
  echo -n "$1" && $MOVE_TO_COL;
  echo -n "[";
  if [ $2 = "success" -o $2 = "0" ] ;then
    ${SETCOLOR_SUCCESS};
    echo -n $"  OK  ";
  elif [ $2 = "failure" -o $2 = "1" ] ;then
    ${SETCOLOR_FAILURE};
    echo -n $"FAILED";
  else
    ${SETCOLOR_WARNING};
    echo -n $"WARNING";
  fi
  ${SETCOLOR_NORMAL};
  echo -n "]";
  echo
}

#安装sshpass
function install_sshpass()
{
  if [[ $ID =~ centos|rocky|rhel ]] ;then
    rpm -q sshpass &> /dev/null || yum install -y sshpass
  else
    dpkg -l sshpass &> /dev/null || { sudo apt update;sudo apt install -y sshpass; }
  fi
  if [ $? -ne 0 ] ;then
    color '安装 sshpass 失败!' 1
    exit 1
  fi
}

function scan_host()
{
  [ -e ./SCANIP.log ] && rm -rf SCANIP.log
  for ((i=$BEGIN;i<="$END";i++));do
    ping -c 1 -W 1 ${NET}$i &> /dev/null && echo "${NET}$i" >> SCANIP.log &
  done
  wait
}

function push_ssh_key()
{
  #生成ssh key
  [ -e ~/.ssh/id_rsa ] || ssh-keygen -P "" -f ~/.ssh/id_rsa
  sshpass -P $PASS ssh-copy-id StrictHostKeyChecking=no ${USER}@${IP} &> /dev/null

  ip_list=(`sort -t . -k 4 -n SCANIP.log`)
  for ip in ${ip_list[*]};do
    sshpass -p $PASS scp -o StrictHostKeyChecking=no -r ~/.ssh ${USER}@${ip}: &> /dev/null
  done

  #把.ssh/known_hosts拷贝到所有主机,使得它们第一次互相访问时不需要输入yes回车
  for ip in ${ip_list[*]};do
    scp ~/.ssh/known_hosts ${USER}@${ip}:.ssh/ &> /dev/null
    color "$ip" 0
  done
}

install_sshpass
scan_host
push_ssh_key

~ vim push_ssh_key.sh
rpm -q sshpass &> /dev/null || yum install -y sshpass
[ -f /root/.ssh/id_rsa ] || ssh-keygen -f /root/.ssh/id_rsa -P ''
export SSHPASS=Admin@h3c
while read IP;do
  sshpass -e ssh-copy-id $IP
done < hosts.list

~ bash push_ssh_key.sh

#验证是否实现基于key验证
~ ssh 10.0.0.51
~ hostname -I
10.0.0.51

~ ssh 10.0.0.52
~ hostname -I
10.0.0.52

6.4.2 安装并配置 Ansible

~ yum install -y ansible

~ vim /etc/ansible/ansible.cfg
[defaults]
host_key_checking = False #检查对应服务器的host_key,建议取消注释

~ vim /etc/ansible/hosts
[appsrvs]
10.0.0.51
10.0.0.52

6.4.3 准备 Ansible 相关文件

~ mkdir -p wordpress_ansible
~ cd wordpress_ansible
~ mkdir files
~ cat > files/nginx.conf <<EOF
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 10240;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        include /etc/nginx/default.d/*.conf;

        location / {
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}
EOF

~ tree ~/wordpress_ansible
wordpress_ansible
├── files
│   ├── nginx.conf
│   └── wordpress-6.0-zh_CN.tar.gz
└── wordpress_lnmp.yml

1 directory, 3 files

6.4.4 准备 Ansible 的 playbook 文件

~ vim wordpress_ansible/wordpress_lnmp.yml
---
- hosts: appsrvs
  remote_user: root

  tasks:
    - name: selinux disabled
      replace: path=/etc/selinux/config regexp='^(SELINUX=.*)' replace='SELINUX=disabled'
    - name: stop firewalld
      service: name=firewalld state=stopped enabled=no
    - name: install packages
      yum: name=nginx,php-fpm,php-json,php-mysqlnd,mariadb-server
    - name: wordpress
      unarchive: src=files/wordpress-6.0-zh_CN.tar.gz dest=/usr/share/nginx/ owner=nginx group=nginx
    - name: wordpress data
      shell: mv /usr/share/nginx/wordpress/* /usr/share/nginx/html
    - name: wordpress dir
      file: path=/usr/share/nginx/html state=directory owner=nginx group=nginx
    - name: php config file
      replace: path=/etc/php-fpm.d/www.conf regexp='(.*)apache$' replace='\1nginx'
    - name: nginx config
      copy: src=files/nginx.conf dest=/etc/nginx/nginx.conf
    - name: service
      service: name={{ item }} state=started enabled=yes
      with_items:
        - nginx
        - php-fpm
        - mariadb
    - name: mysql config
      shell: mysql -e "create database wordpress;grant all on wordpress.* to wordpress@'localhost' identified by 'kubesphere';"

6.4.5 执行 playbook

ansible-playbook wordpress_ansible/wordpress_lnmp.yml

image.png

7 Docker

7.1 软件生命周期

image.png

7.2 容器和Docker

image.png

  • Container ,即容器,平时生活指的是可以装下其它物品的工具,以方便人类归纳放置物品、存储和异地运输,比如人类使用的衣柜、行李箱、背包等可以成为容器
  • Container除了容器以外,另一个意思是集装箱。可以想象:大船停靠在岸边,然后好多整齐划一的箱子可以运来运去
  • 容器技术由来已久,而Docker(码头工人)是属于容器服务的一种,是一个开源的应用容器引擎

image.png

7.3 Docker

传统的容器技术没有成为主流的原因,是因为其未能提供标准化的应用运行时环境,2013年诞生的Docker新一代容器技术,从一开始就以提供标准化的运行时环境为目标,真正做到“build once, run anyWhere”(一次建立,到处运行)Build, Ship and Run Any App, Anywhere,即通过对应用组件的封装(Packaging)、分发(Distribution)、部署(Deployment)、运行(Runtime)等生命周期的管理,达到应用组件级别的“一次建立,到处运行”。应用组件既可以是一个Web应用,也可以是一套数据库服务,甚至是一个操作系统。将应用运行在Docker容器上,可以实现跨平台,跨服务器,只需一次配置准备好相关的应用环境,即可实现到处运行,保证研发和生产环境的一致性,解决了应用和运行环境的兼容性问题,极大提升了部署效率,减少故障的可能性

7.4 使用 Docker 容器化的意义

  • 统一基础设施环境:Docker 环境
    • 硬件的组成配置
    • 操作系统的版本
    • 运行时环境的异构
  • 统一程序打包(装箱)方式:Docker 镜像
    • java程序
    • python程序
    • nodejs程序
  • 统一程序部署(运行)方式:Docker 容器docker run
    • java -jar …
    • python manage.py runserver …
    • npm run dev…

      7.5 Docker 容器生命周期

      image.png

      7.6 利用 Docker 部署 Wordpress

      7.6.1 一键安装脚本实现部署 Docker

      ```bash ~ vim install_docker.sh

      !/bin/bash

DOCKER_VERSION=”20.10.10” UBUNTU_DOCKER_VERSION=”5:${DOCKER_VERSION}~3-0~lsb_release -si-lsb_release -cs

UBUNTU_DOCKER_VERSION=”5:20.10.9~3-0~lsb_release -si-lsb_release -cs

UBUNTU_DOCKER_VERSION=”5:19.03.14~3-0~lsb_release -si-lsb_release -cs

COLOR_SUCCESS=”echo -e \033[1;32m” COLOR_FAILURE=”echo -e \033[1;31m” END=”\033[m”

. /etc/os-release

color () { RES_COL=60 MOVE_TO_COL=”echo -en \033[${RES_COL}G” SETCOLOR_SUCCESS=”echo -en \033[1;32m” SETCOLOR_FAILURE=”echo -en \033[1;31m” SETCOLOR_WARNING=”echo -en \033[1;33m” SETCOLOR_NORMAL=”echo -en \E[0m” echo -n “$1” && $MOVE_TO_COL echo -n “[“ if [ $2 = “success” -o $2 = “0” ] ;then ${SETCOLOR_SUCCESS} echo -n $” OK “
elif [ $2 = “failure” -o $2 = “1” ] ;then ${SETCOLOR_FAILURE} echo -n $”FAILED” else ${SETCOLOR_WARNING} echo -n $”WARNING” fi ${SETCOLOR_NORMAL} echo -n “]” echo }

install_docker(){ if [ $ID = “centos” -o $ID = “rocky” ];then if [ $VERSION_ID = “7” ];then cat > /etc/yum.repos.d/docker.repo <<EOF [docker] name=docker gpgcheck=0

baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/

baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/ EOF else
cat > /etc/yum.repos.d/docker.repo <<EOF [docker] name=docker gpgcheck=0

baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/

baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/8/x86_64/stable/ EOF fi yum clean all ${COLOR_FAILURE}”Docker有以下版本”${END} yum list docker-ce —showduplicates ${COLOR_FAILURE}”5秒后即将安装: docker-“${DOCKER_VERSION}” 版本…..”${END} ${COLOR_FAILURE}”如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行”${END} sleep 5 yum -y install —allowerasing docker-ce-$DOCKER_VERSION docker-ce-cli-$DOCKER_VERSION \ || { color “Base,Extras的yum源失败,请检查yum源配置” 1;exit; } else dpkg -s docker-ce &> /dev/null && $COLOR”Docker已安装,退出” 1 && exit apt update || { color “更新包索引失败” 1 ; exit 1; }
apt -y install apt-transport-https ca-certificates curl software-properties-common || \ { color “安装相关包失败” 1 ; exit 2; }
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add - add-apt-repository “deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable” apt update ${COLOR_FAILURE} “Docker有以下版本”${END} apt-cache madison docker-ce ${COLOR_FAILURE}”5秒后即将安装: docker-“${UBUNTU_DOCKER_VERSION}” 版本…..”${END} ${COLOR_FAILURE}”如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行”${END} sleep 5 apt -y install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION} fi if [ $? -eq 0 ];then color “安装软件包成功” 0 else color “安装软件包失败,请检查网络配置” 1 exit fi

}

config_docker (){ mkdir -p /etc/docker tee /etc/docker/daemon.json <<-‘EOF’ { “registry-mirrors”: [“https://si7y70hh.mirror.aliyuncs.com“], “exec-opts”: [“native.cgroupdriver=systemd”] } EOF systemctl daemon-reload systemctl enable docker systemctl restart docker docker version && color “Docker 安装成功” 0 || color “Docker 安装失败” 1 }

set_alias (){ echo ‘alias rmi=”docker images -qa|xargs docker rmi -f”‘ >> ~/.bashrc echo ‘alias rmc=”docker ps -qa|xargs docker rm -f”‘ >> ~/.bashrc }

install_docker config_docker set_alias

<a name="mKuv6"></a>
### 7.6.2 利用 Docker 部署 Wordpress
```bash
~ mkdir -p wordpress_docker/mysql
~ cat > wordpress_docker/env_mysql.list <<EOF
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=wordpress
MYSQL_USER=wpuser
MYSQL_PASSWORD=wppass
EOF

~ cat > wordpress_docker/env_wordpress.list <<EOF
WORDPRESS_DB_HOST=mysql:3306
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wpuser
WORDPRESS_DB_PASSWORD=wppass
WORDPRESS_TABLE_PREFIX=wp_
EOF

~ cat > wordpress_docker/mysql/mysql_test.cnf <<EOF
[mysqld]
server-id=100
log-bin=mysql-bin
EOF

~ tree wordpress_docker/
wordpress_docker/
├── env_mysql.list
├── env_wordpress.list
└── mysql
    └── mysql_test.cnf

1 directory, 3 files

~ mkdir -pv /data/wp-content
~ setfacl -Rm u:33:rwx /data/wp-content

~ docker run --name mysql \
-v /root/wordpress_docker/mysql/:/etc/mysql/conf.d \
-v /data/mysql:/var/lib/mysql \
--env-file=/root/wordpress_docker/env_mysql.list \
-d -p 3306:3306 mysql:5.7.30

~ docker run -d --name wordpress --link mysql \
-v /data/wp-content:/var/www/html/wp-content/ \
--env-file=/root/wordpress_docker/env_wordpress.list \
-p 80:80 wordpress

~ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
2af091847abd   wordpress      "docker-entrypoint.s…"   3 seconds ago    Up 1 second     0.0.0.0:80->80/tcp, :::80->80/tcp                      wordpress
dd8480103562   mysql:5.7.30   "docker-entrypoint.s…"   14 seconds ago   Up 13 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql
#用浏览器可以访问当前主机,可以看到下面界面

image.png
image.png
更换主题
image.png
image.png

8 Docker Compose

8.1 Docker Compose

当在一台宿主机上启动较多的容器时候,如果都是手动操作会觉得比较麻烦而且容易出错,此时推荐使用docker 单机编排工具docker-compose
docker-compose是docker容器的一种单机编排服务,是一个管理多个容器的工具,比如:可以解决容器之间的依赖关系,并且可以替代docker命令对容器进行创建、启动和停止等手工的操作
如果说docker命令就像linux的命令,docker compse就像shell脚本,可以自动的执行容器批量操作,从而实现自动化的容器管理,或者说docker命令相当于ansible命令,那么
docker compose文件,就相当于Ansible对应的playbook的 yaml 文件

8.2 多机容器编排工具

当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是多主机容器编排引擎
容器编排通常包括容器管理、调度、集群定义和服务发现等功能常见容器编排工具:

  • Docker swarm: docker 开发的容器编排引擎
  • Mesos+Marathon: Mesos是Apache下的开源分布式资源管理框架,最初是由加州大学伯克利分校的AMPLab开发的,后在Twitter得到广泛使用。通用的集群组员调度平台,mesos(资源分配)与marathon(容器编排平台)一起提供容器编排引擎功能
  • Kubernetes:Google领导开发的容器编排引擎,内部项目为Borg,目前已成为行业标准

    8.3 利用 docker compose 部署 Wordpress

    8.3.1 一键安装脚本实现部署 docker compose

    ```bash

    !/bin/bash

DOCKER_VERSION=”20.10.10”

UBUNTU_DOCKER_VERSION=”5:${DOCKER_VERSION}~3-0~lsb_release -si-lsb_release -cs

DOCKER_COMPOSE_VERSION=1.29.2 DOCKER_COMPOSE_FILE=docker-compose-Linux-x86_64

COLOR_SUCCESS=”echo -e \033[1;32m” COLOR_FAILURE=”echo -e \033[1;31m” END=”\033[m”

. /etc/os-release

color () { RES_COL=60 MOVE_TO_COL=”echo -en \033[${RES_COL}G” SETCOLOR_SUCCESS=”echo -en \033[1;32m” SETCOLOR_FAILURE=”echo -en \033[1;31m” SETCOLOR_WARNING=”echo -en \033[1;33m” SETCOLOR_NORMAL=”echo -en \E[0m” echo -n “$1” && $MOVE_TO_COL echo -n “[“ if [ $2 = “success” -o $2 = “0” ] ;then ${SETCOLOR_SUCCESS} echo -n $” OK “
elif [ $2 = “failure” -o $2 = “1” ] ;then ${SETCOLOR_FAILURE} echo -n $”FAILED” else ${SETCOLOR_WARNING} echo -n $”WARNING” fi ${SETCOLOR_NORMAL} echo -n “]” echo }

install_docker(){ if [ $ID = “centos” -o $ID = “rocky” ];then if [ $VERSION_ID = “7” ];then cat > /etc/yum.repos.d/docker.repo <<EOF [docker] name=docker gpgcheck=0

baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/

baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/ EOF else
cat > /etc/yum.repos.d/docker.repo <<EOF [docker] name=docker gpgcheck=0

baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/

baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/8/x86_64/stable/ EOF fi yum clean all ${COLOR_FAILURE} “Docker有以下版本”${END} yum list docker-ce —showduplicates ${COLOR_FAILURE}”5秒后即将安装: docker-“${DOCKER_VERSION}” 版本…..”${END} ${COLOR_FAILURE}”如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行”${END} sleep 5 yum -y install docker-ce-$DOCKER_VERSION docker-ce-cli-$DOCKER_VERSION \ || { color “Base,Extras的yum源失败,请检查yum源配置” 1;exit; } else dpkg -s docker-ce &> /dev/null && $COLOR”Docker已安装,退出” 1 && exit apt update || { color “更新包索引失败” 1 ; exit 1; }
apt -y install apt-transport-https ca-certificates curl software-properties-common || \ { color “安装相关包失败” 1 ; exit 2; }
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add - add-apt-repository “deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable” apt update ${COLOR_FAILURE} “Docker有以下版本”${END} apt-cache madison docker-ce ${COLOR_FAILURE}”5秒后即将安装: docker-“${UBUNTU_DOCKER_VERSION}” 版本…..”${END} ${COLOR_FAILURE}”如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行”${END} sleep 5 apt -y install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION} fi if [ $? -eq 0 ];then color “安装软件包成功” 0 else color “安装软件包失败,请检查网络配置” 1 exit fi

mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'

{ “registry-mirrors”: [“https://si7y70hh.mirror.aliyuncs.com“], “insecure-registries”:[“harbor.kubesphere.com:80”] } EOF systemctl daemon-reload systemctl enable docker systemctl restart docker docker version && color “Docker 安装成功” 0 || color “Docker 安装失败” 1 echo ‘alias rmi=”docker images -qa|xargs docker rmi -f”‘ >> ~/.bashrc echo ‘alias rmc=”docker ps -qa|xargs docker rm -f”‘ >> ~/.bashrc }

install_docker_compose(){ if [ $ID = “centos” -o $ID = “rocky” ];then ${COLOR_SUCCESS}”开始安装 Docker compose…..”${END} sleep 1 if [ ! -e ${DOCKER_COMPOSE_FILE} ];then curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/${DOCKER_COMPOSE_FILE} -o /usr/bin/docker-compose else mv ${DOCKER_COMPOSE_FILE} /usr/bin/docker-compose fi chmod +x /usr/bin/docker-compose else apt -y install docker-compose fi if docker-compose —version ;then ${COLOR_SUCCESS}”Docker Compose 安装完成”${END} else ${COLOR_FAILURE}”Docker compose 安装失败”${END} exit fi }

install_docker install_docker_compose

```bash
#!/bin/bash

. /etc/init.d/functions
COLOR="echo -e \\E[1;32m"
END="\\E[Om"
DOCKER_VERSION="-19.03.8-3.e17"
COMPOSE_VERSION=1.25.5
COMPOSE_FILE=docker-compose-Linux-x86_64

function check()  {
    [ -f "$COMPOSE_FILE" ] || { action "Docker安装失败,文件$COMPOSE_FILE不存在"false ;exit; }
}

function install_docker() {
    ${cOLOR}"开始安装 Docker. . . .. "${END}
    sleep 1

    wget -P /etc/yum.repos.d/ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoll{${COLOR}"互联网连接失败,请检查网络! "${END};exit; }
    yum clean all
    dnf -y install https://mirrors.aliyun.com/ docker-ce/Tinux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.1.e17.x86_64.rpm
    yum -y install docker-ce$DOCKER_VERSION docker-ce-cli$DOCKER_VERSTON \
    || { ${COLOR} "Base,Extras的yum源失败,请检查yum源配置"${END} ; exit; }
    mkdir -p /etc/docker
    cat > /etc/docker /daemon .json <<EOF
{
    "registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"]
}
EOF
    systemctl restart docker
    docker version && ${COLOR} "Docker安装成功"${END} || ${COLOR} "Docker安装失败"${END}
}

function install_docker_compose() {
    ${COLOR}"开始安装 Docker compose......"${END}
    sleep 1

    #curl -L https://github.com/docker/compose/releases/download/1.25.3/docker-compose-Linux-x86_64 -o /usr/bin/docker-compose
    cp $COMPOSE_FILE /usr/bin/docker-compose
    chmod +x /usr/bin/docker-compose
    docker-compose --version && action "Docker Compose 安装完成" || { action"Docker compose安装失败" false; exit; }
}

check
rpm -q docker &> /dev/null && action "Docker已安装" || install_docker
docker-compose --version &> /dev/null && action "Docker compose已安装" || install_docker_compose

8.3.2 利用 docker compose部署wordpress

~ mkdir -pv wordpress_docker_compose/mysql
~ cat > wordpress_docker_compose/mysql/mysql_test.cnf <<EOF
[mysqld]
server-id=100
log-bin=mysql-bin
EOF

#准备docker-compose文件
cat > wordpress_docker_compose/docker-compose.yml <<EOF
version: '3.0'

services:
  mysql:
    image: mysql:5.7.30
    volumes:
      - /data/mysql:/var/lib/mysql
      - /root/wordpress_docker_compose/mysql/:/etc/mysql/conf.d
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: wppass

  wordpress:
    depends_on:
      - mysql
    image: wordpress:latest
    ports:
      - "80:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: mysql:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wppass
      WORDPRESS_TABLE_PREFIX: wp_
    volumes:
      - /data/wp-content:/var/www/html/wp-content
EOF

~ tree wordpress_docker_compose/
wordpress_docker_compose/
├── docker-compose.yml
└── mysql
    └── mysql_test.cnf

1 directory, 2 files

#准备相关目录
~ mkdir -pv /data/wp-content/
~ setfacl -Rm u:33:rwx /data/wp-content/

#运行docker-compose
~ cd wordpress_docker_compose/
~ docker-compose up -d

#查看容器启动情况
~ docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS         PORTS                               NAMES
e42f17336ad1   wordpress:latest   "docker-entrypoint.s…"   48 seconds ago   Up 2 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   wordpress_docker_compose_wordpress_1
c6161180efd8   mysql:5.7.30       "docker-entrypoint.s…"   50 seconds ago   Up 3 seconds   3306/tcp, 33060/tcp                 wordpress_docker_compose_mysql_1

#浏览器访问主机,可以查看以下界面

image.png
image.png

根据文档就可以使用 Wordpress 博客系统了。

image.png