介绍对于企业应用架构来说,绝对不局限于一台服务器。按照我的想法:至少有一台部署后台界面的服务器;部署前端页面的服务器;充当代理的服务器;加载数据库等的服务器,这不包括某些应用程序的负载平衡。但是大方的徐姓朋友只能赞助我一台服务器,这时候我就想到了Docker。我只要多开几个容器,就可以模拟多个服务器,对应多个IP。所以本章首先讲解了如何安装Docker,然后举例说明了如何在Docker容器中安装和配置Nginx、Tomcat和MySQL。本来打算用Oracle做数据库,但是因为服务器配置太低,每次运行Oracle容器都会导致服务器崩溃,只好换成MySQL。考虑到Docker容器每次重启都会从镜像中初始化,所以本文会大量使用挂载,具体原理会在最后一章讲解。Docker安装1、使用uname-r查看系统内核。Docker要求CentOS系统内核版本高于3.10[root@VM_60_202_centos~]#uname-r3.10.0-862.9.1.el7.x86_642。准备好并确认yum更新到最新,没有安装老版本的Docker[root@VM_60_202_centos~]#yumupdate--最新版本的yumpackage[root@VM_60_202_centos~]#yumremovedockerdocker-clientdocker-client-latestdocker-commondocker-latestdocker-latest-logrotatedocker-logrotatedocker-selinuxdocker-engine-selinuxdocker-enginedocker.io--删除老版本的Docker3,安装需要的软件包,yum-util提供yum-config-manager函数,另外两个是devicemapper驱动依赖[root@VM_60_202_centos~]#yuminstall-yyum-utilsdevice-mapper-persistent-datalvm24,最新版本的Docker分为两个版本,docker-ce(社区版)和docker-ee(企业版)。CE版本是免费的,如果我们学习或者一般应用,CE就够了。我们安装社区版。下面可以设置数据源仓库,可以选择Docker官方数据源或者阿里云数据源:[root@VM_60_202_centos~]#yum-config-manager--add-repohttps://download.docker.com/linux/centos/docker-ce.repo--添加官方数据源[root@VM_60_202_centos~]#yum-config-manager--add-repohttps://mirrors.aliyun.com/docker-ce/linux/centos/码头工人。repo--添加阿里云数据源5.安装Docker[root@VM_60_202_centos~]#yumlistdocker-ce--showduplicates|sort-r--列出可以安装的docker版本[root@VM_60_202_centos~]#yuminstalldocker-ce--下载最新版本[root@VM_60_202_centos~]#yuminstall-ydocker-ce-18.03.1.ce-1.el7.centos--安装指定版本6,启动Docker[root@VM_60_202_centos~]#systemctlstartdocker--start[root@VM_60_202_centos~]#systemctlstopdocker--close[root@VM_60_202_centos~]#systemctlrestartdocker--restart7、验证安装[root@VM_60_202_centos~]#docker--version--view安装的docker版本[root@VM_60_202_centos~]#dockerrunhello-worldTomcat容器1.从中找到Tomcat镜像数据源。一般下载Starts最高的官方镜像。[root@VM_60_202_centos~]#dockersearchtomcat--查询tomcat官方镜像[root@VM_60_202_centos~]#dockerpulltomcat--下载名为“tomcat”的镜像[root@VM_60_202_centos~]#dockerimages--查看全部本地镜像2.在宿主机上创建挂载目录,启动Tomcat容器[root@VM_60_202_centos~]#mkdir-p/u01/tomcat/webapps/tomcat1--createadirectory/u01/tomcat/webapps/tomcat1用于挂载Tomcat的[root@VM_60_202_centos~]#mkdir-p/u01/tomcat/webapps/tomcat2--创建目录/u01/tomcat/webapps/tomcat2,用于挂载Tomcat--并分别在/u01/tomcat中放置不同的准备/webapps/tomcat1和/u01/tomcat/webapps/tomcat2中的war包(虽然都是kerryNginxServlet.war,但是内容不一样)[root@VM_60_202_centos~]#dockerrun--name=my_tomcat1-v/u01/tomcat/webapps/tomcat1:/usr/local/tomcat/webapps-p8001:8080-dtomcat--启动一个名为my_tomcat1的Tomcat容器;将容器的8080端口映射到宿主机的8001端口--将宿主机的/u01/tomcat/webapps/tomcat1目录挂载到容器的/usr/local/tomcat/webapps目录下[root@VM_60_202_centos~]#dockerrun--name=my_tomcat2-v/u01/tomcat/webapps/tomcat2:/usr/local/tomcat/webapps-p8002:8080-dtomcat--运行另一个Tomcat容器,命名为my_tomcat2,用于负载均衡3.验证Tomcat容器[root@VM_60_202_centos~]#curlhttp://localhost:8001/kerryNginxServlet/servletA
helloIamKerry!
这是servlet测试A!
[root@VM_60_202_centos~]#curlhttp://localhost:8002/kerryNginxServlet/servletA
你好我是Kerry!
这是servlet测试B!
Nginxcontainer1.同理,从数据源中搜索Nginx镜像,一般下载Starts最高的官方镜像。[root@VM_60_202_centos~]#dockersearchnginx--查询nginx官方镜像[root@VM_60_202_centos~]#dockerpullnginx--下载名为“nginx”的镜像[root@VM_60_202_centos~]#dockerimages--查看所有本地镜像2.在主机上创建挂载目录,编辑配置文件[root@VM_60_202_centos~]#mkdir-p/u01/nginx[root@VM_60_202_centos~]#mkdir-p/u01/nginx/conf.d[root@VM_60_202_centos~]#touch/u01/nginx/nginx.conf[root@VM_60_202_centos~]#touch/u01/nginx/conf.d/default.confvi编辑/u01/nginx/nginx.conf文件用户root;worker_processes1;error_log/var/log/nginx/error.logwarn;pid/var/run/nginx.pid;events{worker_connections1024;}http{include/etc/nginx/mime.types;default_type应用程序/八位字节流;log_formatmain'$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.logmain;发送文件在;#tcp_nopush上;keepalive_timeout65;#gzip上;包括/etc/nginx/conf.d/*.conf;上游tomcatServer{servert1:8080;服务器t2:8080;}}编辑/u01/nginx/conf.d/default.conf文件服务器{listen80;服务器名称本地主机;location/{proxy_passhttp://tomcatServer;}}3.启动Nginx容器[root@VM_60_202_centos~]#dockerrun--name=my_nginx1--link=my_tomcat1:t1--link=my_tomcat2:t2-v/u01/nginx/nginx.conf:/etc/nginx/nginx.conf-v/u01/nginx/conf.d:/etc/nginx/conf.d-p8000:80-dnginx--运行Nginx的容器,命名为my_nginx1--分别是my_tomcat1和my_tomcat2容器的别名,t1,t2(会在my_nginx1的/etc/hosts文件中自动配置)--挂载/u01/nginx/nginx.conf文件和/u01/nginx/conf.d目录--映射容器的80端口号到主机的8000端口[root@VM_60_202_centos~]#curlhttp://localhost:8000/kerryNginxServlet/servletA
你好我是Kerry!
这是servlet测试A!
[root@VM_60_202_centos~]#curlhttp://localhost:8000/kerryNginxServlet/servletA
你好我是Kerry!
这里是servlet测试B!
因为配置了负载均衡,访问http://localhost:8000/kerryNginxServlet/servletA时,会访问http://localhost:8001/kerryNginxServlet/servletA和http://localhost:8002/kerryNginxServlet/servletAMySQL容器平均概率1.从数据源中找到MySQL镜像,一般下载Starts最高的官方镜像。[root@VM_60_202_centos~]#dockersearchmysql--查询mysql官方镜像[root@VM_60_202_centos~]#dockerpullmysql--下载名为“mysql”的镜像[root@VM_60_202_centos~]#dockerimages--查看全部本地镜像2.创建挂载目录[root@VM_60_202_centos~]#mkdir-p/u01/mysql/data/u01/mysql/logs/u01/mysql/conf--data目录将映射到mysql容器配置数据文件存放path--logs目录会映射到mysql容器的log目录--conf目录下的配置文件会映射到mysql容器的配置文件3.启动MySQL容器dockerrun-p3306:3306--namemy_mysql1-v/u01/mysql/conf:/etc/mysql/conf.d-v/u01/mysql/logs:/logs-v/u01/mysql/data:/var/lib/mysql-eMYSQL_ROOT_PASSWORD=kerry-dmysql-p3306:3306:将容器的3306端口映射到宿主机的3306端口。-v挂载。-eMYSQL_ROOT_PASSWORD=kerry:初始化root用户的密码。4、远程连接数据库这时候如果远程连接数据库,可能会报错:ERROR2059(HY000):Authenticationplugin'caching_sha2_password'cannotbeloaded。如果在安装mysql8的时候选择密码加密,那么使用navicate等客户端连接,客户端会提示连接caching-sha2-password,因为客户端不支持这个插件,可以在下面修改方式:1)进入容器dockerexec-itmy_mysql1bash2)进入mysqlmysql-uroot-pkerry3)修改用户登录权限信息先查询用户信息mysql>selecthost,user,plugin,authentication_stringfrommysql.user;+----------+-----------------+----------------------+------------------------------------------------------------------------+|主持人|用户|插件|authentication_string|+------------+----------------+-----------------------+-----------------------------------------------------------------------+|%|根|缓存_sha2_密码|*B9C0EAD50A12474280CBCFD8CFB40DF416A93E02||本地主机|mysql.信息模式|缓存_sha2_密码|$A$005$这个组合没有任何不能使用的有效盐和密码||本地主机|mysql.会话|缓存_sha2_密码|$A$005$这是一个绝不能使用的无效盐和密码的组合||本地主机|mysql.sys|缓存_sha2_密码|$A$005$这是一个绝不能使用的无效盐和密码的组合||本地主机|根|mysql_native_password|*B9C0EAD50A12474280CBCFD8CFB40DF416A93E02|+------------+----------------+----------------------+----------------------------------------------------------------------+5rowsinset(0.00sec)hostis%表示unlimitediplocalhost表示这台机器使用mysql_native_password以外的插件,需要修改密码上面可以看出root用户没有限制ip,但是需要修改插件。当然,为了应对各种应用场景,可以统一执行如下SQL:ALTERUSER'root'@'%'IDENTIFIEDBY'kerry'PASSWORDEXPIRENEVER;ALTERUSER'root'@'%'IDENTIFIEDWITHmysql_native_passwordBY'kerry';冲洗特权;#更改刷新权限后,就可以使用其他客户端连接数据库了。此时查询数据库的用户信息为:mysql>selecthost,user,plugin,authentication_stringfrommysql.user;+------------+-------------------+--------------------+--------------------------------------------------------------------+|主持人|用户|插件|authentication_string|+------------+----------------+------------------------+----------------------------------------------------------------------+|%|根|mysql_native_password|*B9C0EAD50A12474280CBCFD8CFB40DF416A93E02||本地主机|mysql.信息模式|缓存_sha2_密码|$A$005$这是一个绝不能使用的无效盐和密码的组合||本地主机|mysql.会话|缓存_sha2_密码|$A$005$这是一个绝不能使用的无效盐和密码的组合||本地主机|mysql.sys|缓存_sha2_密码|$A$005$这是一个无效盐和PA的组合绝不能使用的SSWORD||本地主机|根|mysql_native_password|*B9C0EAD50A12474280CBCFD8CFB40DF416A93E02|+------------+----------------+-----------------------+----------------------------------------------------------------------+其他1.Docker中的挂载原理文件系统的工作原理Docker镜像存储在一个一系列只读层。当我们启动一个容器时,Docker读取只读镜像并在上面添加一个读写层。如果正在运行的容器修改了现有文件,则该文件将从最底层的只读层复制到最顶层的读写层。读写层文件的旧版本隐藏在这个文件下,但它并不是坚不可摧的——它仍然存在于镜像下。当一个Docker容器被删除,然后图像被重新启动时,一个新的容器被启动而没有任何更改——那些更改丢失了。这个只读层和上面的读写层的组合就是Docker所说的联合文件系统。为了在容器之间保存(持久化)数据和共享数据,Docker提出了Volumes的概念。很简单,卷是默认联合文件系统外部的目录(或文件)或主机文件系统中存在的普通目录和文件。2、MySQL表数据等,本地主机上的存储策略不完整,后面会单独增加一章,以实际项目为例。