一次有趣的 Kubernetes 面试:如何在一小时内完成 WordPress 部署!

微信扫一扫,分享到朋友圈

一次有趣的 Kubernetes 面试:如何在一小时内完成 WordPress 部署!

本文是作者在一次面试中遇到的问题:如何在一小时内完成 WordPress 部署!

作者:木子(才云)

编辑:bot(才云)

校对:星空下的文仔(才云)

今天收到一份面试题:

1. CentOS7,nginx 最新版,php 7.x,mysql 不做要求 + wordpress

2. 以文件的方式创建并挂载 2G 的 swap 分区

请把学习记录以 URL、截图等方式保留。最终,我在手机上可以看到 wordpress 站点就好。时间 1 小时以内,方法方式不限。

虽然内容看似简单,比如用 
docker-compose
 一键就能完成部署。不过为了把部署过程中遇到的一些问题详细记录下来,以及梳理过程中参考的一些文档等,我觉得通过一篇正式博客,把我解决这个问题的流程展现出来,效果会好一些。
同时
作为完美主义者,我也

望能
再做一些额外的优化
:joy:。


另外值得一提的是,如果你希望深入理解 LNMP 技术栈的话, 还是推荐使用传统的方式
,比如 yum 安装或源码编译安装,那样你能理解这些服务之间的工作流程,会对整个系统有深入的了解。

而 
docker-compose
 以简单粗暴的方式屏蔽了这些细节,会让我们放弃思考这些底层细节,对于学习这门技术栈来讲,还是弊大于利。

不过今天为了快速部署,本文还是选用 
docker-compose
 吧 !:joy:


K8sMeetup

WordPress

Get WordPress Use the software that powers over 35% of the web.

WordPress 想必大家都很熟悉啦,毕竟是全球内容管理系统里的老大哥,常年占据第一的位置(占有率 35%)。官网: wordpress.org


K8sMeetup

任务二 以文件的方式创建并挂载 2G 的 swap 分区

这个任务与 WordPress 不太相关,所以我们先从完成它开始。

拿到机器后 ssh 登录到系统,先使用常用的命令看一下服务器的信息,另外在自己的域名上添加了 A 记录 
wordpress.k8s.li
 到这台服务器 IP ,并开启 HTTPS ,防止被 DDOS 攻击,毕竟有 CloudFlare 的 Anycast CDN 给我们在前头扛一把:joy:,还是不错滴。

[root@interview ~]# uname -a

Linux interview 3.10.0-1062.12.1.el7.x86_64 #1 SMP Tue Feb 4 23:02:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

[root@interview ~]# cat /proc/cpuinfo

processor : 0

vendor_id : GenuineIntel

cpu family : 6

model : 45

model name : Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz

stepping : 7

microcode : 0x710

cpu MHz : 2594.123

cache size : 20480 KB

physical id : 0

siblings : 1

core id : 0

cpu cores : 1

apicid : 0

initial apicid : 0

fpu : yes

fpu_exception : yes

cpuid level : 13

wp : yes

flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush mmx fxsr sse sse2 syscall nx rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes hypervisor lahf_lm

bogomips : 5187.68

clflush size : 64

cache_alignment : 64

address sizes : 46 bits physical, 48 bits virtual

power management:


[root@interview ~]# free -h

total used free shared buff/cache available

Mem: 985M 150M 451M 12M 382M 680M

Swap: 0B 0B 0B

  • unanme -a
     查看一下系统内核版本 ,
    3.10.0-1062
     的内核看样子是 CentOS7.7;

  • cat /proc/cpuinfo
     查看一下 CPU 的信息,E5-2670 的 CPU ,属于 Intel 第六代 CPU 系列;

  • free
     查看一下内存的情况,1GB 的小内存:joy:。

Q2 以文件的方式创建并挂载 2G 的 swap 分区

这个问题比较简单,之前我自己的 GCE 小鸡 512M 内存上也是使用文件的方式创建 2GB 的交换分区,所以我对这个步骤早就熟记于心,不需要搜索就能搞定:yum:。

使用 dd 命令即可生成一个 2GB 大小的文件:

[root@interview ~]# dd if=/dev/zero of=/swapfile bs=4M count=500

500+0 records in

500+0 records out

2097152000 bytes (2.1 GB) copied, 11.0648 s, 190 MB/s

2097152000 bytes (2.1 GB) copied, 11.0648 s, 190 MB/s
 怎么会是 2.1 GB 呢?多出来 0.1GB ,强迫症受不了!
想起来了,可能是 
bs=4M
 参数的问题。于是我在我的 debian 机器上测试了一下

顺带 man 一下 dd 看看 bs 参数是怎么定义的:

bs=BYTES read and write up to BYTES bytes at a time (default: 512); overrides ibs and obs

╭─debian@debian ~

╰─$ dd if=/dev/zero of=./test bs=4MB count=4

4+0 records in

4+0 records out

16000000 bytes (16 MB, 15 MiB) copied, 0.0147078 s, 1.1 GB/s

原因是文件大小单位不同,一个是 
MB
 另一个是 
MiB
。我在 Google 上搜索了一下 ,看到一个回答
What is the difference between 1 MiB and 1 MB and why should we care
,也想起了前两天看到的
面向信仰编程
大佬的一则推文:

接下来使用 
mkswap
 命令将刚刚创建好的 
/swapfile
 文件格式化为交换分区所需要的格式,并修改一下文件权限为 600 ,即只能由 root 用户读。默认的 755 会被其他用户看到,由于里面的内容是内存里的信息,安全起见还是需要修改一下权限。

[root@interview ~]# mkswap /swapfile

Setting up swapspace version 1, size = 2047996 KiB

no label, UUID=a4eab465-75d1-4830-b870-c222c7e2e87b

[root@interview ~]#

[root@interview ~]# chmod 600 /swapfile

[root@interview ~]# swapon !$

swapon /swapfile

[root@interview ~]# free -h

total used free shared buff/cache available

Mem: 985M 212M 140M 12M 633M 612M

Swap: 2.0G 0B 2.0G

至此任务二完成了,接下来就是题目的核心——安装 WordPress 啦!


K8sMeetup

install

刚开始我打算使用常规的方法来部署 WordPress,使用 Google 搜索关键字 CentOS install WordPress,可以找到 DigitalOcean 官方博客里的
How To Install WordPress on CentOS 7
。里面提到:

Additionally, you’ll need to have a LAMP (Linux, Apache, MySQL, and PHP) stack installed on your CentOS 7 server. If you don’t have these components already installed or configured, you can use this guide to learn how to install LAMP on CentOS 7.

虽然 WordPress 官方没有给出详细的搭建步骤,但我们可以参考 DigitalOcean 官方的内容,毕竟公有云服务提供商的技术专家写的博客更可靠一些。由于要求的是 nginx 最新版本,yum 安装的 nginx 版本可能会旧一些。

[root@interview wordpress]# yum list nginx

Loaded plugins: fastestmirror, langpacks

Loading mirror speeds from cached hostfile

* base: centos-distro.1gservers.com

* epel: d2lzkl7pfhq30w.cloudfront.net

* extras: mirror.dal.nexril.net

* updates: mirror.dal10.us.leaseweb.net

Available Packages

nginx.x86_64 1:1.16.1-1.el7 epel

yum list nginx
 里的信息显示 nginx 版本为 1.16.1,并不是官网上的最新版 
1.17.10
 。


前天我看到一篇推文说使用 GCP 的小鸡编译 nginx 大概花了 3 个小时:joy:,而我面试规定的时间是 1 个小时内解决,我担心 源码编译的时间可能会有点长
。但我又想要最新版的 nginx ,那么看来只用 docker 的方式安装 nginx 了 ,使用 nginx 官方的镜像 nginx:latest 即为 nginx 最新的版本。

Google 搜索 
docker hub nginx
 来到 docker 官方的 nginx 镜像仓库
nginx
。我哭了,虽然是 1.17 版本,但它是 1.17.9 版本而不是 1.17.10 ,就差了一点点啊(将就着用吧,虽然差了那么一点点)!

事实证明我推断错了,第二天我在另一台机器上编译 nginx 花了不到 1 分钟,感觉被大佬坑惨了:在 GCE 小鸡上编译 nginx 根本不可能需要 3 小时吧,3 分钟才对的吧!一开始我其实怀疑过编译 nginx 需要 3个小时有点问题,但并没有亲自去验证,还是自己不够细致,一知半解真是很危险的事儿!


K8sMeetup

install docker

安装 docker 的方式再熟悉不过了,使用一个 curl 命令就能搞定: 
curl -fsSL https://get.docker.com | bash -s docker

如果在国内环境的话,后面加上 
--mirror Aliyun
 参数就能使用阿里云的镜像站,这样会更快一些,即 
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

不过我还是从初学者来安装 docker ,Google 搜索 
centos install docker
 ,点击进入官网
Install Docker Engine on CentOS
,为了节省时间,我没有按照官网的步骤来,而是使用官方的一键脚本来安装:

[root@interview ~]# curl -fsSL https://get.docker.com -o get-docker.sh

[root@interview ~]# ls

get-docker.sh

[root@interview ~]# chmod +x get-docker.sh

[root@interview ~]# ./get-docker.sh

安装完成之后,使用 
docker info

 查看 docker 信息。需要注意的是: 目前最新版本的 docker 默认优先采用 overlay2 的存储驱动
,对于已支持该驱动的 Linux 发行版,不需要任何进行任何额外的配置。另外需要注意的是 

devicemapper
 存储驱动已经在 docker 18.09 版本中被废弃,docker 官方推荐使用 
overlay2
 替代 
devicemapper

[root@interview ~]# docker info

Client:

Debug Mode: false

Server:

Containers: 0

Running: 0

Paused: 0

Stopped: 0

Images: 0

Server Version: 19.03.8

Storage Driver: overlay2

Backing Filesystem: <unknown>

Supports d_type: true

Native Overlay Diff: true

Logging Driver: json-file

Cgroup Driver: cgroupfs

Plugins:

Volume: local

Network: bridge host ipvlan macvlan null overlay

Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog

Swarm: inactive

Runtimes: runc

Default Runtime: runc

Init Binary: docker-init

containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429

runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd

init version: fec3683

Security Options:

seccomp

Profile: default

Kernel Version: 3.10.0-1062.12.1.el7.x86_64

Operating System: CentOS Linux 7 (Core)

OSType: linux

Architecture: x86_64

CPUs: 1

Total Memory: 985.3MiB

Name: interview

ID: YSZO:TT5U:GDLH:3FYT:LFGP:NLOS:L4YI:5LFU:3EAV:KHP2:F746:I5P3

Docker Root Dir: /var/lib/docker

Debug Mode: false

Registry: https://index.docker.io/v1/

Labels:

Experimental: false

Insecure Registries:

127.0.0.0/8

Live Restore Enabled: false


K8sMeetup

install docker-compose

安装完 docker 之后,接下来是安装 docker-compose ,使用 Google 搜索 
centos install docker-compose
,进入官网 
Install Docker Compose

[root@interview ~] sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

[root@interview ~]# docker-compose version

bash: /usr/local/bin/docker-compose: Permission denied

[root@interview ~]# chmod +x /usr/local/bin/docker-compose

[root@interview ~]# docker-compose version

docker-compose version 1.25.4, build 8d51620a

docker-py version: 4.1.0

CPython version: 3.7.5

OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019

遇到了 
Permission denied
 问题,原来是忘记加权限了,
chmod +x /usr/local/bin/docker-compose
 一下即可。


K8sMeetup

WordPress

官方
Quickstart: Compose and WordPress
的 
docker-compose.yaml
 中的 web 服务器是使用的 apache 而不是 nginx ,因此要使用第三方的 docker-compose.yaml。

前段时间在折腾 Webp Server Go 时,我遇到过这种需求,于是在 GitHub 上搜索 
wordpress nginx docker-compose
,找到了合适的 repo 即
wordpress-nginx-docker
。看一下 docker-compose.yaml 文件:

version: '3.6'

services:


wordpress:

image: wordpress:${WORDPRESS_VERSION:-php7.3-fpm}

container_name: wordpress

volumes:

- ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini

- ./wordpress:/var/www/html

environment:

- WORDPRESS_DB_NAME=${WORDPRESS_DB_NAME:-wordpress}

- WORDPRESS_TABLE_PREFIX=${WORDPRESS_TABLE_PREFIX:-wp_}

- WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-mysql}

- WORDPRESS_DB_USER=${WORDPRESS_DB_USER:-root}

- WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD:-password}

depends_on:

- mysql

restart: always


mysql:

image: mariadb:${MARIADB_VERSION:-latest}

container_name: mysql

volumes:

- ./mysql:/var/lib/mysql

environment:

- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-password}

- MYSQL_USER=${MYSQL_USER:-root}

- MYSQL_PASSWORD=${MYSQL_PASSWORD:-password}

- MYSQL_DATABASE=${MYSQL_DATABASE:-wordpress}

restart: always


nginx:

image: nginx:${NGINX_VERSION:-latest}

container_name: nginx

ports:

- '80:80'

- '443:443'

volumes:

- ${NGINX_CONF_DIR:-./nginx}:/etc/nginx/conf.d

- ${NGINX_LOG_DIR:-./logs/nginx}:/var/log/nginx

- ${WORDPRESS_DATA_DIR:-./wordpress}:/var/www/html

- ${SSL_CERTS_DIR:-./certs}:/etc/letsencrypt

- ${SSL_CERTS_DATA_DIR:-./certs-data}:/data/letsencrypt

depends_on:

- wordpress

restart: always


adminer:

image: adminer

restart: always

links:

- mysql

ports:

- 8080:8080

共有 4 个容器:wordpress、mysql、nginx、adminer。这些容器默认不需要修改既可以部署起来,adminer 是个 web 端管理 MySQL 数据库的,可以删掉。

由于默认的系统不带 git ,所以需要安装一下 git 
yum install git
,然后把 repo clone 下来。

git clone https://github.com/mjstealey/wordpress-nginx-docker

cd wordpress-nginx-docker

docker-compose up

这样使用 
docker-compose up
 命令就能启动一个 WordPress 站点了。通过访问域名
wordpress.k8s.li
即可访问刚刚创建好的网站。


K8sMeetup

Webp Server

为了优化博客图片静态资源的加载速度,我们可以为 WordPress 加上一个 Webp Server 服务,将原图片压缩为 webp 格式。需要修改一下 nginx 的配置文件,添加内容如下:

location ^~ /wp-content/uploads/ {

proxy_pass http://webp-server:3333;

}

在 docker-compose.yaml 文件中加入 webp server 的容器:

version: '3.6'

services:


wordpress:

image: wordpress:${WORDPRESS_VERSION:-php7.3-fpm}

container_name: wordpress

volumes:

- ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini

- ./wordpress:/var/www/html

environment:

- WORDPRESS_DB_NAME=${WORDPRESS_DB_NAME:-wordpress}

- WORDPRESS_TABLE_PREFIX=${WORDPRESS_TABLE_PREFIX:-wp_}

- WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-mysql}

- WORDPRESS_DB_USER=${WORDPRESS_DB_USER:-root}

- WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD:-password}

depends_on:

- mysql

restart: always


mysql:

image: mariadb:${MARIADB_VERSION:-latest}

container_name: mysql

volumes:

- ./mysql:/var/lib/mysql

environment:

- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-password}

- MYSQL_USER=${MYSQL_USER:-root}

- MYSQL_PASSWORD=${MYSQL_PASSWORD:-password}

- MYSQL_DATABASE=${MYSQL_DATABASE:-wordpress}

restart: always


nginx:

image: nginx:${NGINX_VERSION:-latest}

container_name: nginx

ports:

- '80:80'

- '443:443'

volumes:

- ${NGINX_CONF_DIR:-./nginx}:/etc/nginx/conf.d

- ${NGINX_LOG_DIR:-./logs/nginx}:/var/log/nginx

- ${WORDPRESS_DATA_DIR:-./wordpress}:/var/www/html

- ${SSL_CERTS_DIR:-./certs}:/etc/letsencrypt

- ${SSL_CERTS_DATA_DIR:-./certs-data}:/data/letsencrypt

depends_on:

- wordpress

restart: always


webp-server:

image: webpsh/webps:latest

restart: always

container_name: webp-server

volumes:

- ./webp-server/config.json:/etc/config.json

- ./wordpress:/var/www/html

ports:

- 3333:3333

修改好 docker-compose.yaml 文件之后,我们还需要为 webp-server 准备一个 config.json 文件,存放在 
./webp-server/config.json
 下,内容如下:

{

"HOST": "0.0.0.0",

"PORT": "3333",

"QUALITY": "80",

"IMG_PATH": "/var/www/html",

"EXHAUST_PATH": "",

"ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif"]

}

接下来我们使用 
docker-compose restart
 命令重启容器,之后在 WordPress 端上传一张图片测试一下。上传完成之后,拿到图片的 url ,然后使用 wget 命令测试一下,显示 
Length: 102288 (100K) [image/webp]
 就说明我们的 webp server 已经成功运行啦:joy:。

完整的 repo 在我的 GitHub 上:
github.com/muzi502/Wwordpress
,欢迎来食用呀:yum:!

╭─root@sg-02 /opt/wordpress-nginx-docker ‹master›

╰─# wget http://dl.amd64.xyz/wp-content/uploads/2020/04/74898710_p21.jpg

--2020-04-17 01:06:29-- http://dl.amd64.xyz/wp-content/uploads/2020/04/74898710_p21.jpg

Resolving dl.amd64.xyz (dl.amd64.xyz)... 3.1.38.108

Connecting to dl.amd64.xyz (dl.amd64.xyz)|3.1.38.108|:80... connected.

HTTP request sent, awaiting response... 200 OK

Length: 102288 (100K) [image/webp]

Saving to: ‘74898710_p21.jpg’


74898710_p21.jpg 100%[=======>] 99.89K --.-KB/s in 0.001s


2020-04-17 01:06:29 (130 MB/s) - ‘74898710_p21.jpg’ saved [102288/102288]


K8sMeetup

End

至此部署一个 WordPress 的流程就结束啦,为了追求速度,我放弃了对一些细节的深究。虽然
有些内容看似简单,但想把这个过程中遇到的问题以及想法落笔成字,形成一篇博客,还是一个挑战,所以最后,我还是建议感兴趣的读者动手实践一番,或许会有更多文章未涉及的新发现。

推荐阅读:

在看点一下

儿童夏季忌大补,试试这5大保健心法

上一篇

你也可能喜欢

一次有趣的 Kubernetes 面试:如何在一小时内完成 WordPress 部署!

长按储存图像,分享给朋友