Docker之LNMP分布式容器部署-(4)


Docker之LNMP分布式容器部署

一、项目模拟

1. 项目环境

公司在实际的生产环境中,需要使用Docker技术在一台主机上创建LNMP服务并运行Wordpress网站平台。然后对此服务进行相关的性能调优和管理工作。

 

2. 服务器环境

容器

操作系统

IP地址

主要软件

nginx

CentOS 7.9 x86_64

172.111.0.10

Docker-Nginx

mysql

Centos 7.9 x86_64

172.111.0.20

Docker-Mysql

php

Centos 7.9 x86_64

172.111.0.30

Docker-php

3. 任务需求

(1)使用Docker构建LNMP环境并运行Wordpress网站平台。

(2)限制Nginx容器最多使用500Mb的内存和1G的Swap。

(3)限制Mysql容器写 /dev/sda 的速率为 10 MB/s。

(4)将所有容器进行快照,然后将Docker镜像打包成tar包备份到本地。

 

二、Linux系统基础镜像

[root@docker ~]# systemctl disable --now firewalld

[root@docker ~]# setenforce 0

setenforce: SELinux is disabled

[root@docker ~]# docker pull centos:7

#从公有仓库中下载centos 7作为系统基础镜像

[root@docker ~]# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

centos 7 eeb6ee3f44bd 4 weeks ago 204MB

三、Nginx

1. 建立工作目录

[root@docker ~]# mkdir /opt/nginx

[root@docker ~]# cd /opt/nginx

[root@docker nginx]# rz -E

rz waiting to receive.

上传nginx安装包nginx-1.20.2.tar.gz

[root@docker nginx]# rz -E

rz waiting to receive.

#上传wordpress服务包wordpress-4.9.4-zh_CN.tar.gz

2. 编写Dockerfile脚本

[root@docker nginx]# vim Dockerfile

 

FROM centos:7

MAINTAINER this is nginx image

RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make;useradd -M -s /sbin/nologin nginx

ADD nginx-1.20.2.tar.gz /usr/local/src/

WORKDIR /usr/local/src/nginx-1.20.2

RUN ./configure \

--prefix=/usr/local/nginx \

--user=nginx \

--group=nginx \

--with-http_stub_status_module;make -j4 && make install

ENV PATH /usr/local/nginx/sbin:$PATH

ADD nginx.conf /usr/local/nginx/conf/

ADD wordpress-4.9.4.tar.gz /usr/local/nginx/html

RUN chmod 777 -R /usr/local/nginx/html/

EXPOSE 80

VOLUME [ "/usr/local/nginx/html/" ]

CMD [ "/usr/local/nginx/sbin/nginx","-g","daemon off;" ]

3. 准备nginx.conf配置文件

[root@docker nginx]# ls

Dockerfile nginx-1.20.2.tar.gz nginx.conf wordpress-4.9.4.tar.gz

[root@docker nginx]# egrep -v "^(.)*#(.)*$" nginx.conf | grep -v "^$"

worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application/octet-stream;

sendfile on;

keepalive_timeout 65;

server {

listen 80;

server_name localhost;

charset utf-8;

location / {

root html;

index index.html index.php;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

location ~ \.php$ {

root html;

fastcgi_pass 172.111.0.30:9000;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;

include fastcgi_params;

}

}

}

4. 生成镜像

[root@docker nginx]# docker build -t nginx:lnmp .

[root@docker nginx]# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

nginx lnmp 35a6404fcfa1 5 seconds ago 522MB

centos 7 eeb6ee3f44bd 4 weeks ago 204MB

5. 创建自定义网络

[root@docker nginx]# docker network create --subnet=172.111.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork

0cbe1bd0bd782bf1c8e69916d99427970196de22deb312f970e01030406d9b45

[root@docker nginx]# docker network ls

NETWORK ID NAME DRIVER SCOPE

dd7a55d01f86 bridge bridge local

63ddf1e359e9 host host local

0cbe1bd0bd78 mynetwork bridge local

a4b66a8a6cd2 none null local

[root@docker nginx]# ifconfig docker1

docker1: flags=4099 mtu 1500

inet 172.111.0.1 netmask 255.255.0.0 broadcast 172.111.255.255

ether 02:42:40:dc:e8:1d txqueuelen 0 (Ethernet)

RX packets 0 bytes 0 (0.0 B)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 0 bytes 0 (0.0 B)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

6. 启动镜像容器

[root@docker nginx]# docker run -d --name nginx -p 80:80 -m 500m --memory-swap 1g --net mynetwork --ip 172.111.0.10 nginx:lnmp

57616d4ea225c82a50b731472b003dabfd681e8dc6c6ef85a9bb2f665354334b

[root@docker nginx]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

57616d4ea225 nginx:lnmp "/usr/local/nginx/sb…" 13 seconds ago Up 12 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp nginx

[root@docker nginx]# docker inspect nginx

······

"IPv4Address": "172.111.0.10"

······

7. 验证nginx

[root@docker nginx]# curl http://192.168.10.2:80

Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and

working. Further configuration is required.

 

For online documentation and support please refer to

nginx.org.

Commercial support is available at

nginx.com.

 

Thank you for using nginx.

三、Mysql

1. 建立工作目录

[root@docker nginx]# mkdir /opt/mysql

[root@docker nginx]# cd /opt/mysql/

[root@docker mysql]# rz -E

rz waiting to receive.

#传入mysql安装包mysql-boost-5.7.34.tar.gz

2. 编写Dockerfile

[root@docker mysql]# vim Dockerfile

 

FROM centos:7

MAINTAINER this is mysql image

RUN yum -y install ncurses ncurses-devel bison make cmake git openssl-devel perl-Data-Dumper libtirpc-devel pcre-devel zlib-devel gcc gcc-c++ ;useradd -M -s /sbin/nologin mysql

ADD mysql-boost-5.7.34.tar.gz /usr/local/src/

WORKDIR /usr/local/src/mysql-5.7.34/

RUN cmake \

-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \

-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \

-DSYSCONFDIR=/etc \

-DSYSTEMD_PID_DIR=/usr/local/mysql \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DWITH_EXTRA_CHARSETS=all \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_ARCHIVE_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \

-DMYSQL_DATADIR=/usr/local/mysql/data \

-DWITH_BOOST=boost \

-DWITH_SYSTEMD=1;make -j4;make install

ADD my.cnf /etc/my.cnf

EXPOSE 3306

RUN chown -R mysql:mysql /usr/local/mysql/;chown mysql:mysql /etc/my.cnf

WORKDIR /usr/local/mysql/bin/

RUN ./mysqld \

--initialize-insecure \

--user=mysql \

--basedir=/usr/local/mysql \

--datadir=/usr/local/mysql/data;cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/;systemctl enable mysqld

ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH

VOLUME [ "/usr/local/mysql" ]

CMD ["/usr/sbin/init"]

3. 准备my.cnf文件

[root@docker mysql]# vim my.cnf

 

[client]

port = 3306

socket=/usr/local/mysql/mysql.sock

 

[mysqld]

user = mysql

basedir=/usr/local/mysql

datadir=/usr/local/mysql/data

port = 3306

character-set-server=utf8

pid-file = /usr/local/mysql/mysqld.pid

socket=/usr/local/mysql/mysql.sock

bind-address = 0.0.0.0

skip-name-resolve

max_connections=2048

default-storage-engine=INNODB

max_allowed_packet=16M

server-id = 1

 

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES

4. 生成镜像

[root@docker mysql]# docker build -t mysql:lnmp .

[root@docker mysql]# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

mysql lnmp 49da8f7299af 3 minutes ago 9.98GB

nginx lnmp 35a6404fcfa1 17 minutes ago 522MB

centos 7 eeb6ee3f44bd 4 weeks ago 204MB

5. 启动镜像容器

[root@docker mysql]# docker run --name=mysql -d --privileged --device-write-bps /dev/sda:10M -v /usr/local/mysql --net mynetwork --ip 172.111.0.20 mysql:lnmp

ebafbdc1c4dcfc49406a7db8ee5a2afc54f5b4203d11ad374dba885ec4ef5afd

[root@docker mysql]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

ebafbdc1c4dc mysql:lnmp "/usr/sbin/init" 11 seconds ago Up 10 seconds 3306/tcp mysql

57616d4ea225 nginx:lnmp "/usr/local/nginx/sb…" 17 minutes ago Up 17 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp nginx

6. 验证mysql

[root@docker mysql]# docker exec -it mysql bash

[root@ebafbdc1c4dc bin]# systemctl status mysqld

● mysqld.service - MySQL Server

Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)

Active: activating (start) since Sun 2021-10-17 05:54:59 UTC; 42s ago

······

四、Php

1. 建立工作目录

[root@docker mysql]# mkdir ../php

[root@docker mysql]# cd ../php/

[root@docker php]# rz -E

rz waiting to receive.

#传入php安装包php-7.4.27.tar.gz

2. 编写Dockerfile脚本

[root@docker php]# vim Dockerfile

 

FROM centos:7

MAINTAINER this is php image

ADD oniguruma-6.7.0-1.el7.x86_64.rpm /usr/local/src/

WORKDIR /usr/local/src/

RUN rpm -ivh oniguruma-6.7.0-1.el7.x86_64.rpm

ADD oniguruma-devel-6.7.0-1.el7.x86_64.rpm /usr/local/src/

WORKDIR /usr/local/src/

RUN rpm -ivh oniguruma-devel-6.7.0-1.el7.x86_64.rpm

RUN yum install -y gd \

sqlite sqlite-devel \

libjpeg libjpeg-devel \

libpng libpng-devel \

freetype freetype-devel \

libxml2 libxml2-devel \

zlib zlib-devel \

curl curl-devel \

openssl openssl-devel \

gcc gcc-c++ make pcre-devel;useradd -M -s /sbin/nologin nginx

ADD php-7.4.27.tar.gz /usr/local/src/

WORKDIR /usr/local/src/php-7.4.27

RUN ./configure \

--prefix=/usr/local/php \

--with-mysql-sock=/usr/local/mysql/mysql.sock \

--with-mysqli \

--with-zlib \

--with-curl \

--with-gd \

--with-jpeg-dir \

--with-png-dir \

--with-freetype-dir \

--with-openssl \

--enable-fpm \

--enable-mbstring \

--enable-xml \

--enable-session \

--enable-ftp \

--enable-pdo \

--enable-tokenizer \

--enable-zip ; make -j 4 ; make install

ENV PATH /usr/local/php/bin:/usr/local/php/sbin:$PATH

ADD php.ini /usr/local/php/lib/

ADD php-fpm.conf /usr/local/php/etc/

ADD www.conf /usr/local/php/etc/php-fpm.d/

EXPOSE 9000

CMD /usr/local/php/sbin/php-fpm -F

3. 准备php.ini、php-fpm.conf、www.conf配置文件

从其他机器安装php后,scp配置文件到容器宿主机并进行修改

 

3.1 php.ini

该配置文件模板位于安装目录的php-7.4.27/php.ini-development位置

 

[root@docker php]# vim php.ini

 

#939行,取消注释,修改

date.timezone = Asia/Shanghai

#1170行,修改

mysqli.default_socket = /usr/local/mysql/mysql.sock

[root@docker php]# egrep -v "^;" php.ini | egrep -v "^$"

[PHP]

engine = On

short_open_tag = Off

precision = 14

output_buffering = 4096

zlib.output_compression = Off

implicit_flush = Off

unserialize_callback_func =

serialize_precision = -1

disable_functions =

disable_classes =

zend.enable_gc = On

expose_php = On

max_execution_time = 30

max_input_time = 60

memory_limit = 128M

error_reporting = E_ALL

display_errors = On

display_startup_errors = On

log_errors = On

log_errors_max_len = 1024

ignore_repeated_errors = Off

ignore_repeated_source = Off

report_memleaks = On

track_errors = On

html_errors = On

variables_order = "GPCS"

request_order = "GP"

register_argc_argv = Off

auto_globals_jit = On

post_max_size = 8M

auto_prepend_file =

auto_append_file =

default_mimetype = "text/html"

default_charset = "UTF-8"

doc_root =

user_dir =

enable_dl = Off

file_uploads = On

upload_max_filesize = 2M

max_file_uploads = 20

allow_url_fopen = On

allow_url_include = Off

default_socket_timeout = 60

[CLI Server]

cli_server.color = On

[Date]

date.timezone = Asia/Shanghai

[filter]

[iconv]

[intl]

[sqlite3]

[Pcre]

[Pdo]

[Pdo_mysql]

pdo_mysql.cache_size = 2000

pdo_mysql.default_socket=

[Phar]

[mail function]

SMTP = localhost

smtp_port = 25

mail.add_x_header = On

[SQL]

sql.safe_mode = Off

[ODBC]

odbc.allow_persistent = On

odbc.check_persistent = On

odbc.max_persistent = -1

odbc.max_links = -1

odbc.defaultlrl = 4096

odbc.defaultbinmode = 1

[Interbase]

ibase.allow_persistent = 1

ibase.max_persistent = -1

ibase.max_links = -1

ibase.timestampformat = "%Y-%m-%d %H:%M:%S"

ibase.dateformat = "%Y-%m-%d"

ibase.timeformat = "%H:%M:%S"

[MySQLi]

mysqli.max_persistent = -1

mysqli.allow_persistent = On

mysqli.max_links = -1

mysqli.cache_size = 2000

mysqli.default_port = 3306

mysqli.default_socket = /usr/local/mysql/mysql.sock

mysqli.default_host =

mysqli.default_user =

mysqli.default_pw =

mysqli.reconnect = Off

[mysqlnd]

mysqlnd.collect_statistics = On

mysqlnd.collect_memory_statistics = On

[OCI8]

[PostgreSQL]

pgsql.allow_persistent = On

pgsql.auto_reset_persistent = Off

pgsql.max_persistent = -1

pgsql.max_links = -1

pgsql.ignore_notice = 0

pgsql.log_notice = 0

[bcmath]

bcmath.scale = 0

[browscap]

[Session]

session.save_handler = files

session.use_strict_mode = 0

session.use_cookies = 1

session.use_only_cookies = 1

session.name = PHPSESSID

session.auto_start = 0

session.cookie_lifetime = 0

session.cookie_path = /

session.cookie_domain =

session.cookie_httponly =

session.serialize_handler = php

session.gc_probability = 1

session.gc_divisor = 1000

session.gc_maxlifetime = 1440

session.referer_check =

session.cache_limiter = nocache

session.cache_expire = 180

session.use_trans_sid = 0

session.sid_length = 26

session.trans_sid_tags = "a=href,area=href,frame=src,form="

session.sid_bits_per_character = 5

[Assertion]

zend.assertions = 1

[COM]

[mbstring]

[gd]

[exif]

[Tidy]

tidy.clean_output = Off

[soap]

soap.wsdl_cache_enabled=1

soap.wsdl_cache_dir="/tmp"

soap.wsdl_cache_ttl=86400

soap.wsdl_cache_limit = 5

[sysvshm]

[ldap]

ldap.max_links = -1

[mcrypt]

[dba]

[opcache]

[curl]

[openssl]

3.2 php-fpm.conf

该配置文件位于/usr/local/php/etc/php-fpm.conf.default

 

[root@docker php]# vim php-fpm.conf

 

#17行,删除注释符号";"

pid = run/php-fpm.pid

[root@docker php]# egrep -v "^;" php-fpm.conf | egrep -v "^$"

[global]

pid = run/php-fpm.pid

include=/usr/local/php/etc/php-fpm.d/*.conf

3.3 www.conf

该配置文件位于usr/local/php/etc/php-fpm.d/www.conf.default

 

[root@docker php]# vim www.conf

 

#23、24行,修改用户和组

user = nginx

group = nginx

#36行,修改监听IP和端口为容器IP:9000端口

listen = 172.111.0.30:9000

[root@docker php]# egrep -v "^;" www.conf | egrep -v "^$"

[www]

user = nginx

group = nginx

listen = 172.111.0.30:9000

pm = dynamic

pm.max_children = 5

pm.start_servers = 2

pm.min_spare_servers = 1

pm.max_spare_servers = 3

4. 生成镜像

[root@docker php]# docker build -t php:lnmp .

[root@docker php]# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

php lnmp 985842f961f1 About a minute ago 1.2GB

mysql lnmp 49da8f7299af 12 minutes ago 9.98GB

nginx lnmp 35a6404fcfa1 26 minutes ago 522MB

centos 7 eeb6ee3f44bd 4 weeks ago 204MB

5. 启动镜像容器

[root@docker php]# docker run -itd --name php --net mynetwork --ip 172.111.0.30 -p 9000:9000 --volumes-from nginx --volumes-from mysql php:lnmp

954d8ecdd6c7d47270fe15ce4ad6db9c4a5396f42f9d111315ecee69358a9566

[root@docker php]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

954d8ecdd6c7 php:lnmp "/bin/sh -c '/usr/lo…" 15 seconds ago Up 14 seconds 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp php

ebafbdc1c4dc mysql:lnmp "/usr/sbin/init" 8 minutes ago Up 8 minutes 3306/tcp mysql

57616d4ea225 nginx:lnmp "/usr/local/nginx/sb…" 26 minutes ago Up 26 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp nginx

6. 验证php

[root@docker php]# docker exec -it php bash

[root@954d8ecdd6c7 php-7.4.27]# ps -aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.0 113028 9536 pts/0 Ss+ 06:00 0:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)

nginx 7 0.0 0.0 113028 5780 pts/0 S+ 06:00 0:00 php-fpm: pool www

nginx 8 0.0 0.0 113028 5784 pts/0 S+ 06:00 0:00 php-fpm: pool www

root 9 0.2 0.0 11828 1888 pts/1 Ss 06:01 0:00 bash

root 23 0.0 0.0 51732 1728 pts/1 R+ 06:01 0:00 ps -aux

五、启动wordpress服务

1. mysql授权

docker exec -it mysql bash

[root@ebafbdc1c4dc bin]# mysql -u root -p

Enter password:

#初始密码为空

mysql> create database wordpress;

Query OK, 1 row affected (0.00 sec)

 

mysql> grant all privileges on wordpress.* to 'wordpress'@'%' identified by '123456';

Query OK, 0 rows affected, 1 warning (0.00 sec)

 

mysql> grant all privileges on *.* to 'root'@'%' identified by '123456';

Query OK, 0 rows affected, 1 warning (0.00 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

2. 浏览器访问测试

访问http://192.168.10.2/wordpress/index.php

3. 备份镜像至本地(先检查宿主机还有多少空间,如果不够就不用了)

[root@docker php]# mkdir /opt/lnmp_images

[root@docker php]# cd $?

-bash: cd: 0: 没有那个文件或目录

[root@docker php]# cd /opt/lnmp_images/

[root@docker lnmp_images]# docker save -o nginx.tar nginx:lnmp

[root@docker lnmp_images]# docker save -o mysql.tar mysql:lnmp

[root@docker lnmp_images]# docker save -o php.tar php:lnmp