對於企業應用架構來講,確定不侷限於一臺服務器,按照個人設想:至少一臺部署後臺接口的服務器;一臺部署前端頁面的服務器;一臺作代理的服務器;一臺裝載數據庫的服務器等等,這還不包括對某些應用作負載均衡。
但是慷慨的許姓朋友只能贊助我一臺服務器,這時候我就想到了Docker。只要我多開幾個容器,就能模擬分出多個服務器,對應多個IP。
因此本章首先是講解安裝Docker,其次是一一示例如何在Docker容器中安裝配置Nginx、Tomcat和MySQL。原計劃數據庫使用Oracle,可是因爲服務器配置過低,每次Oracle容器運行起來後都會致使服務器宕機,因此不得不改成MySQL。
因爲考慮到Docker容器每次重啓都會從鏡像中初始化,文章中會大量使用到掛載,具體原理最後章節會講。前端
一、使用uname -r 查看系統內核,Docker 要求CentOS系統的內核版本高於 3.10mysql
[root@VM_60_202_centos ~]# uname -r 3.10.0-862.9.1.el7.x86_64
二、作好準備,確認yum更新到最新,沒有安裝過舊版本Dockerlinux
[root@VM_60_202_centos ~]# yum update --最新版yum包 [root@VM_60_202_centos ~]# yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine docker.io --刪除舊版本Docker
三、安裝須要的軟件包, yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的nginx
[root@VM_60_202_centos ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
四、最新版本的 Docker 分兩個版本,docker-ce(Community Edition)和docker-ee(Enterprise Edition)。CE版本是免費的,若是咱們學習或者通常應用,CE足夠。咱們安裝社區版。下面能夠設置數據源倉庫,能夠選用Docker官方數據源或者阿里雲數據源:web
[root@VM_60_202_centos ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo --添加官方數據源 [root@VM_60_202_centos ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo --添加阿里雲數據源
五、安裝Dockersql
[root@VM_60_202_centos ~]# yum list docker-ce --showduplicates | sort -r --列出能夠安裝的docker版本 [root@VM_60_202_centos ~]# yum install docker-ce --下載最新版本 [root@VM_60_202_centos ~]# yum install -y docker-ce-18.03.1.ce-1.el7.centos --安裝指定版本
六、啓動Dockerdocker
[root@VM_60_202_centos ~]# systemctl start docker --啓動 [root@VM_60_202_centos ~]# systemctl stop docker --關閉 [root@VM_60_202_centos ~]# systemctl restart docker --重啓
七、驗證安裝狀況數據庫
[root@VM_60_202_centos ~]# docker --version --查看安裝的docker版本 [root@VM_60_202_centos ~]# docker run hello-world
一、從數據源中查找Tomcat鏡像。通常下載官方的鏡像Starts最高的那個。centos
[root@VM_60_202_centos ~]# docker search tomcat --查詢tomcat官方鏡像 [root@VM_60_202_centos ~]# docker pull tomcat --下載下來其中的名爲「tomcat」的鏡像 [root@VM_60_202_centos ~]# docker images --查看本地全部的鏡像
二、宿主機建立掛載目錄,啓動Tomcat容器tomcat
[root@VM_60_202_centos ~]# mkdir -p /u01/tomcat/webapps/tomcat1 --建立目錄/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 ~]# docker run --name=my_tomcat1 -v /u01/tomcat/webapps/tomcat1:/usr/local/tomcat/webapps -p 8001:8080 -d tomcat --啓動一個Tomcat容器,命名爲my_tomcat1;將容器的8080端口映射到宿主機的8001 --將宿主機的/u01/tomcat/webapps/tomcat1 目錄掛載到容器上的/usr/local/tomcat/webapps 目錄 [root@VM_60_202_centos ~]# docker run --name=my_tomcat2 -v /u01/tomcat/webapps/tomcat2:/usr/local/tomcat/webapps -p 8002:8080 -d tomcat --再運行一個Tomcat容器,命名my_tomcat2,用於作負載均衡
三、驗證Tomcat容器
[root@VM_60_202_centos ~]# curl http://localhost:8001/kerryNginxServlet/servletA <h2> hello I am Kerry!</h2><h1>This is the servlet test A!</h1> [root@VM_60_202_centos ~]# curl http://localhost:8002/kerryNginxServlet/servletA <h2> hello I am Kerry!</h2><h1>This is the servlet test B!</h1>
一、一樣,從數據源中查找Nginx鏡像。通常下載官方的鏡像Starts最高的那個。
[root@VM_60_202_centos ~]# docker search nginx --查詢nginx官方鏡像 [root@VM_60_202_centos ~]# docker pull nginx --下載下來其中的名爲「nginx」的鏡像 [root@VM_60_202_centos ~]# docker images --查看本地全部的鏡像
二、宿主機建立掛載目錄,編輯配置文件
[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.conf
而後vi 編輯 /u01/nginx/nginx.conf 文件
user root; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; 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; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; upstream tomcatServer { server t1:8080; server t2:8080; } }
編輯 /u01/nginx/conf.d/default.conf 文件
server { listen 80; server_name localhost; location / { proxy_pass http://tomcatServer; } }
三、啓動Nginx容器
[root@VM_60_202_centos ~]# docker run --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 -p 8000:80 -d nginx --運行Nginx的容器,命名爲my_nginx1 --給my_tomcat一、my_tomcat2容器分別起別名,t一、t2(會在my_nginx1的/etc/hosts文件中自動配置) --掛載/u01/nginx/nginx.conf文件和/u01/nginx/conf.d目錄 --將容器的端口號80映射到宿主機的8000端口 [root@VM_60_202_centos ~]# curl http://localhost:8000/kerryNginxServlet/servletA <h2> hello I am Kerry!</h2><h1>This is the servlet test A!</h1> [root@VM_60_202_centos ~]# curl http://localhost:8000/kerryNginxServlet/servletA <h2> hello I am Kerry!</h2><h1>This is the servlet test B!</h1>
由於配置了負載均衡,因此在訪問http://localhost:8000/kerryNginxServlet/servletA時,會有平均機率地訪問http://localhost:8001/kerryNginxServlet/servletA 和 http://localhost:8002/kerryNginxServlet/servletA
一、從數據源中查找MySQL鏡像。通常下載官方的鏡像Starts最高的那個。
[root@VM_60_202_centos ~]# docker search mysql --查詢mysql官方鏡像 [root@VM_60_202_centos ~]# docker pull mysql --下載下來其中的名爲「mysql」的鏡像 [root@VM_60_202_centos ~]# docker images --查看本地全部的鏡像
二、建立掛載目錄
[root@VM_60_202_centos ~]# mkdir -p /u01/mysql/data /u01/mysql/logs /u01/mysql/conf --data目錄將映射爲mysql容器配置的數據文件存放路徑 --logs目錄將映射爲mysql容器的日誌目錄 --conf目錄裏的配置文件將映射爲mysql容器的配置文件
三、啓動MySQL容器
docker run -p 3306:3306 --name my_mysql1 -v /u01/mysql/conf:/etc/mysql/conf.d -v /u01/mysql/logs:/logs -v /u01/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=kerry -d mysql -p 3306:3306:將容器的 3306 端口映射到主機的 3306 端口。 -v 掛載。 -e MYSQL_ROOT_PASSWORD=kerry:初始化 root 用戶的密碼。
四、遠程鏈接數據庫
這時遠程來鏈接該數據庫,可能會報錯:
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded
在安裝mysql8的時候若是選擇了密碼加密,以後用客戶端鏈接好比navicate,會提示客戶端鏈接caching-sha2-password,是因爲客戶端不支持這種插件,能夠經過以下方式進行修改:
1)進入容器
docker exec -it my_mysql1 bash
2)進入mysql
mysql -uroot -pkerry
3)修改用戶登陸權限信息
先查詢用戶信息
mysql> select host,user,plugin,authentication_string from mysql.user; +-----------+------------------+-----------------------+------------------------------------------------------------------------+ | host | user | plugin | authentication_string | +-----------+------------------+-----------------------+------------------------------------------------------------------------+ | % | root | caching_sha2_password | *B9C0EAD50A12474280CBCFD8CFB40DF416A93E02 | | localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | mysql_native_password | *B9C0EAD50A12474280CBCFD8CFB40DF416A93E02 | +-----------+------------------+-----------------------+------------------------------------------------------------------------+ 5 rows in set (0.00 sec)
host爲 % 表示不限制ip localhost表示本機使用 plugin非mysql_native_password 則須要修改密碼。
上文中能夠見,root用戶不限制ip,但須要修改 plugin。固然,若是爲了應對各類應用場景,能夠統一執行下列SQL:
ALTER USER 'root'@'%' IDENTIFIED BY 'kerry' PASSWORD EXPIRE NEVER; ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'kerry'; FLUSH PRIVILEGES; #刷新權限
改完以後,就能夠用其餘客戶端鏈接該數據庫了。此時查詢數據庫的用戶信息爲:
mysql> select host,user,plugin,authentication_string from mysql.user; +-----------+------------------+-----------------------+------------------------------------------------------------------------+ | host | user | plugin | authentication_string | +-----------+------------------+-----------------------+------------------------------------------------------------------------+ | % | root | mysql_native_password | *B9C0EAD50A12474280CBCFD8CFB40DF416A93E02 | | localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | root | mysql_native_password | *B9C0EAD50A12474280CBCFD8CFB40DF416A93E02 | +-----------+------------------+-----------------------+------------------------------------------------------------------------+
一、掛載的原理Docker內的文件系統工做狀況。Docker鏡像被存儲在一系列的只讀層。當咱們開啓一個容器,Docker讀取只讀鏡像並添加一個讀寫層在頂部。若是正在運行的容器修改了現有的文件,該文件將被拷貝出底層的只讀層到最頂層的讀寫層。在讀寫層中的舊版本文件隱藏於該文件之下,但並無被不破壞 - 它仍然存在於鏡像如下。當Docker的容器被刪除,而後從新啓動鏡像時,將開啓一個沒有任何更改的新的容器 - 這些更改會丟失。此只讀層及在頂部的讀寫層的組合被Docker稱爲Union File System(聯合文件系統)。爲了可以保存(持久)數據以及共享容器間的數據,Docker提出了Volumes的概念。很簡單,volumes是目錄(或者文件),它們是外部默認的聯合文件系統或者是存在於宿主文件系統正常的目錄和文件。二、MySQL的表數據等,在本地宿主機上存儲的策略尚不完整,後續會另起篇幅,拿實際項目舉例說明。