zoukankan      html  css  js  c++  java
  • 系统综合实践3:基于Docker compose的多容器协同

    系统综合实践——第3次实践作业:基于Docker compose的多容器协同

    本课程最终的应用需要组装多个容器提供的多个服务,Docker compose是作为定义和运行多容器的工具, 用户可以使用 YML 文件来配置应用程序需要的所有服务。

    一、实践记录

    1.实践问答

    (1)时间记录

    - 开始时间——2021/04/16 19:00
    - 结束时间——2021/04/25 22:00
    - 有效时长——15h
    

    (2)难易程度

    - B.比较困难
    

    2.实验环境

    • VisualBox_6.1虚拟机
    • Ubuntu 18.04.5 Desktop amd64 的虚拟机系统;

    【软件工具】

    3.实验任务

    学习使用Docker compose构建相应的服务:

    (1)使用Docker-compose 实现LNMP的Web服务。

    (2)使用Docker-compose实现 Tomcat+Nginx负载均衡。



    二、实践1——LNMP服务

    Web服务需要完成,web服务器、数据库、开发程序等服务的组装,典型的如 LNMP(Linux+Nginx+Mysql+PHP)。

    1.环境准备

    (1)安装Docker-compose

    sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose	//建立同步链接
    

    测试:

    sudo docker-compose --version
    

    (2)拉取镜像

    sudo docker images
    sudo docker pull php:7.4-fpm
    

    (3)建立工作目录

    cd /home/ubuntu/lancl/docker_build	
    mkdir compose_docker
    cd /home/ubuntu/lancl/docker_build/compose_docker
    mkdir web
    mkdir mysql_data
    

    2.编写配置文件

    (1)Nginx:default.conf

    sudo nano default.conf

    server {
    	listen       9191;        #修改映射端口
    	server_name  localhost;
    
    	location / {
      		root   /web/html;     #修改工作目录/home/ubuntu/lancl/docker_build/compose_docker/web
        	index  index.html index.htm;	#index.html int
    	}
    	# error_page   404                /404.html;
    	# redirect server error pages to the static page  /50x.html;
    	error_page   500 502 503 504  /50x.html;
    	location = /50x.html {
        	root   /usr/share/nginx/html;
    	}
    
    	location ~ .php$ {
        	root           /web/php;   #修改工作(代码)目录
        	fastcgi_pass   php_container_92135:9000;   #修改为容器名phpfpm
        	fastcgi_index  index.php;
        	fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; 
        	include        fastcgi_params;
    	}
    }
    

    (2)yml文件

    sudo nano docker-compose.yml

    version: "3"
    services:
    nginx:
    	image: nginx_image_92135                          #指定镜像名
    	container_name: nginx_container_92135     #指定容器名
    	build:
      		context: .
      		dockerfile: dockerfile_nginx      #指定dockerfile文件
    	ports:
      		- "9191:9191"                       #修改端口映射,宿主机:容器
    	volumes:
     		- ./web:/web/html                 #挂载容器卷,本地/容器内修改文件后,另一方都会同步更新;
      		- ./default.conf:/etc/nginx/conf.d/default.conf     #挂载配置文件
    php:
    	image: php_image_92135 
    	container_name: php_container_92135
    	build:
      		context: .
      		dockerfile: dockerfile_php 
    	environment:
      		MYSQL_PASSWORD: 123456         #设置好环境变量,在php代码中使用变量名直接引用
    	volumes:
      		- ./web:/web/php                  #挂载工作目录到本机web目录
    
    mysql:
    	image: mysql_image_92135 
    	container_name: mysql_container_92135
    	build:
    		context: .
    		dockerfile: dockerfile_mysql
    	ports:
    		- "3306:3306"
    	volumes:
    		- ./mysql_data:/var/lib/mysql       #挂载容器卷,实现数据同步,防止数据丢失
    

    (3)Dockerfile文件

    ① sudo nano dockerfile_mysql

    #基础镜像
    FROM mysql:5.7
    #镜像作者
    MAINTAINER 032092135
    #设置不允许免密登录并设置root密码
    ENV MYSQL_ALLOW_EMPTY_PASSWORD no
    ENV MYSQL_ROOT_PASSWORD=123456
    

    ② sudo nano dockerfile_nginx

    #基础镜像
    FROM nginx
    #作者信息
    MAINTAINER 032092135
    #声明暴露端口
    EXPOSE 9191
    

    ③ sudo nano dockerfile_php

    #基础镜像
    FROM php:7.4-fpm
    #作者信息
    MAINTAINER 032092135
    #安装扩展pdo
    #COPY sources.list /etc/apt
    RUN apt-get update && apt-get install -y 
        libfreetype6-dev 
        libjpeg62-turbo-dev 
        libpng-dev 
    	&& docker-php-ext-install pdo_mysql 
    	&& docker-php-ext-configure gd --with-freetype --with-jpeg 
    	&& docker-php-ext-install -j$(nproc) gd
    

    (4)测试文件

    cd /home/ubuntu/lancl/docker_build/compose_docker/web

    ① sudo nano index.html

    <!DOCTYPE html>
    <html>
    
    <head>
    	<meta charset="utf-8" />
    	<title>032092135-lancl</title>
    </head>
    
    <body>
    	<h1> NGINX SUCCESS </h1>
    	<p>docker-compose --build successfully! </p>
    	<p>hello_world!!!</p>
    </body>
    
    </html>
    

    ② sudo nano index.php

    <?php phpinfo();?>
    

    (5)工作空间一览

    sudo apt install tree
    cd /home/ubuntu/lancl/docker_build/compose_docker
    tree
    

    3.实验过程——连接测试

    (1)执行docker-compose文件

    cd /home/ubuntu/lancl/docker_build/compose_docker
    sudo docker-compose up -d --build	//-d后台运行
    

    (2)浏览器连接

    打开浏览器,在地址栏输入:localhost:9191/index.php

    localhost/index.html
    localhost/index.php		//- 80端口
    http://localhost:9191/index.php
    http://localhost:9191/index.html	//- 9191端口
    

    (3)docker-compose相关操作

    需要在yml文件所在目录下执行,

    sudo docker-compose ps	//列出所有docker-compose容器
    sudo docker-compose down	//停止并删除运行中的 Compose 应用(容器和网络)
    sudo docker-compose up	//重新部署
    sudo docker-compose stop	//停止
    sudo docker-compose restart	//重新运行
    

    4.实验过程——LNMP服务测试

    (1)web端连接数据库服务器

    修改index.php文件

    <?php
    $servername = "mysql_container_92135";  	#用自定义的MySQL容器名
    $username = "root";
    $password = "123456";   
    
    try {
    	$conn = new PDO("mysql:host=$servername", $username, $password);
    	echo "连接成功!"; 
    }
    catch(PDOException $e)
    {
    	echo $e->getMessage();
    }
    ?>
    

    打开浏览器,在地址栏输入:localhost:9191/index.php

    (2)创建自定义数据库

    sudo nano createMyDB.php

    <?php
    $servername = "mysql_container_92135";  	#用自定义的MySQL容器名
    $username = "root";
    $password = "123456";
     
    try {
    	$conn = new PDO("mysql:host=$servername", $username, $password);
    	echo "连接成功!<br>"; 
    	
    	// 设置PDO错误模式为异常
    	$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	// sql语句
    	$sql0 = "DROP DATABASE myDB";
    	$sql = "CREATE DATABASE myDB";
    
    	// 使用 exec() ,因为没有结果返回
    	$conn->exec($sql0);
    	$conn->exec($sql);
    
    	echo "数据库myDB,创建成功!<br>";
    }
    catch(PDOException $e)
    {
    	echo $sql . "<br>" . $e->getMessage();
    }
    $conn = null;
    ?>
    

    打开浏览器,在地址栏输入:localhost:9191/createMyDB.php

    进入mysql容器,再进入数据库并查询数据库myDB是否存在

    格式: mysql -h主机地址 -u用户名 -p用户密码 -P端口

    sudo docker exec -it  mysql_container_92135 /bin/bash
    mysql -u root -p	//密码:123456	
    show databases;
    use myDB
    show tables;
    select * from user;
    exit/quit	//退出数据库
    exit		//退出容器
    

    (3)数据库操作

    sudo nano createTable.php

    <?php
    $servername = "mysql_container_92135";
    $username = "root";
    $password = "123456";
    $dbname="myDB";
     
    try {
    	$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    	echo "连接成功!<br>";
    	$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	$sql = "CREATE TABLE user(
    	id INT(8) UNSIGNED PRIMARY KEY, 
    	name VARCHAR(30) NOT NULL,
    	age INT DEFAULT NULL
    		)";
    	$conn->exec($sql);
    	echo "user表创建成功";
    }
    catch(PDOException $e)
    {
    	echo $sql . "<br>" . $e->getMessage();
    }
     
    $conn = null;
    ?>
    

    sudo nano insertTable.php

    <?php
    $servername = "mysql_container_92135";
    $username = "root";
    $password = "123456";
    $dbname="myDB";
     
    try {
    	$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    	echo "连接成功!<br>";
    	
    	$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	// 开始事务
    	$conn->beginTransaction();
    	// SQL 语句
    	$conn->exec("INSERT INTO user (id,name,age) 
    	VALUES (032092135, 'LCL',21)");
    	$conn->exec("INSERT INTO user (id,name,age) 
    	VALUES (032092133, 'GYL',22)");
    	$conn->exec("INSERT INTO user (id,name,age) 
    	VALUES (032092131, 'LHH',20)");
     
    	// 提交事务
    	$conn->commit();
    	echo "新记录插入成功!";
    }
    catch(PDOException $e)
    {
    	// 如果执行失败回滚
    	$conn->rollback();
    	echo $sql . "<br>" . $e->getMessage();
    }
         
    $conn = null;
    
    ?>
    

    sudo nano deleteFromTable.php

    <?php
    $servername = "mysql_container_92135";
    $username = "root";
    $password = "123456";
    $dbname="myDB";
     
    try {
    	$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    	echo "连接成功!<br>";
    	
    	$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	// 开始事务
    	$conn->beginTransaction();
    	// SQL 语句
    	$conn->exec("DELETE FROM user where id=032092133");
    
    	// 提交事务
    	$conn->commit();
    	echo "记录删除成功!";
    }
    catch(PDOException $e)
    {
    	// 如果执行失败回滚
    	$conn->rollback();
    	echo $sql . "<br>" . $e->getMessage();
    }
     
    $conn = null;
    ?>
    

    5.可视化操作——phpmyadmin

    (1)拉取镜像

    sudo docker pull phpmyadmin/phpmyadmin:latest
    

    (2)修改配置文件

    sudo nano dockerfile_phpmyadmin

    #基础镜像
    FROM phpmyadmin/phpmyadmin
    #作者信息
    MAINTAINER 032092135   
    #声明暴露的端口
    EXPOSE 8080
    

    在yml文件中添加容器映射:

    phpmyadmin:
    	image: phpmyadmin_image_92135 
    	container_name: phpmyadmin_container_92135
    	build: 
    		context: .
    		dockerfile: dockerfile_phpmyadmin
    	ports: 
    		- "8080:80" 	# phpmyadmin默认监听80
    	environment:
    		PMA_HOST: mysql_container_92135 #指定mysql服务所在的host
    

    (3)重启容器镜像

    sudo docker-compose up
    sudo docker-compose restart
    

    登录界面

    • 用户:root
    • 密码:123456

    控制界面

    • 左边数据库栏,上方图标:(小房子)主页、退出等选项;

    三、实践2——Tomcat+Nginx负载均衡

    • 使用Compose实现nginx代理tomcat集群,代理2个以上tomcat;
    • 编写简易的html页面和jsp页面,测试验证nginx确实将请求转发到了不同的tomcat上;

    1.创建文件目录,添加配置文件

    cd lancl/docker_build
    mkdir load_blance
    cd /home/ubuntu/lancl/docker_build/load_blance
    

    (1)创建docker-compose.yml

    sudo nano docker-compose.yml

    version: "3"
    
    services:
    
      nginx:
    
        image: nginx_image_lb       #指定容器运行的镜像。镜像名error:nginx_image_LB,lowercasse
        container_name: nginx_container_LB #指定容器名
        build:
          context: ./nginx
          dockerfile: dockerfile_nginx          #指定dockerfile文件
    
        restart: always#容器重启策略
    
        #ports用于映射端口的标签:HOST:CONTAINER;只是指定容器(container)的端口,宿主机(host)会随机映射端口。
        ports:
          - "9292:9292"
    
    			
        #将其它容器的ip记录到本容器中:链接到其它服务中的容器。使用服务名称(同时作为别名),或者“服务名称:服务别名”.
        links:
    
          - tomcat1:tomcat1
    			
          - tomcat2:tomcat2
    			
          - tomcat3:tomcat3
    
        volumes:
    
          - ./webServer:/webserver
    			
          - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    			
          - ./etc/localtime:/etc/localtime
    
        depends_on:             #指定依赖关系,先启用tomcat1/2,才会启用nginx
    		
          - tomcat1
    		
          - tomcat2
    		
          - tomcat3
    
      tomcat1:
    
        hostname: tomcat1
    		
        build: ./tomcat         #指定为构建镜像上下文路径:XXX/Dockerfile 所构建的镜像
    		
        ports:
          - "8051:8080"
    		
        volumes:
    		
          - ./webServer/tomcatA:/usr/local/apache-tomcat-8.5.65/webapps/ROOT
    		
          - ./etc/localtime:/etc/localtime
    		
      tomcat2:
    		
        hostname: tomcat2
    		
        build: ./tomcat
    		
        ports:
          - "8052:8080"
    		
        volumes:
    		
          - ./webServer/tomcatB:/usr/local/apache-tomcat-8.5.65/webapps/ROOT
    		
          - ./etc/localtime:/etc/localtime
    
      tomcat3:
    
        hostname: tomcat3
    		
        build: ./tomcat
    		
        ports:
          - "8053:8080"
    		
        volumes:
    		
          - ./webServer/tomcatC:/usr/local/apache-tomcat-8.5.65/webapps/ROOT
    		
          - ./etc/localtime:/etc/localtime
    

    (2)创建etc

    让docker容器使用主机系统时间(挂入/etc/localtime)

    (3)创建nginx

    sudo nano dockerfile_nginx

    #基础镜像
    FROM nginx
    
    #作者信息
    MAINTAINER 032092135
    
    #定义工作目录
    ENV WORK_PATH /etc/nginx
    
    #定义conf文件名
    ENV CONF_FILE_NAME nginx.conf
    
    #删除原有配置文件
    RUN rm $WORK_PATH/$CONF_FILE_NAME
    
    #复制新的配置文件
    COPY ./$CONF_FILE_NAME $WORK_PATH/
    
    #给shell文件赋读权限
    RUN chmod a+r $WORK_PATH/$CONF_FILE_NAME
    
    #声明暴露端口
    EXPOSE 9292
    

    sudo nano nginx.conf

    #【全局块】:配置影响nginx全局的指令。
    user  nginx;	#配置用户/组,默认为nobody
    
    worker_processes  1;	#允许生成的进程数,默认为1
    
    error_log  /var/log/nginx/error.log warn;	 #制定日志路径,级别依次为:debug|info|notice|warn|error|crit|alert|emerg
    
    pid/var/run/nginx.pid;	#nginx进程pid存放路径
    
    #【events块】:配置影响nginx服务器或与用户的网络连接。
    events {
    
      worker_connections  1024;	#最大连接数,默认为512
    
    }![](https://img2020.cnblogs.com/blog/2147268/202104/2147268-20210427221940736-1446911854.jpg)
    
    
    
    #【http块】:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
    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;
    
      client_max_body_size 10m;	#每个进程每次调用传输数量上限
    
      sendfile  on;          #允许sendfile方式传输文件,默认为off
    
      #tcp_nopush on;
    
      keepalive_timeout  65;	#连接超时时间,默认为75s
    
      #gzip  on;
    
      upstream tomcat_client {
    
        server tomcat1:8080 weight=1;		#1-使用weight配置负载均衡,weight默认为1,权重越高,处理请求越多
    
        server tomcat2:8080 weight=1;		#2-如果权重都是1,那么各个端口将会启用——轮询机制,8051/2/3???
    
        server tomcat3:8080 weight=2;	
    
      }
    
      server {		#【server块】:配置虚拟主机的相关参数
    
        server_name "";		#自定义域名host_name,localhost?
    
        listen   9292;#修改映射端口
        listen [::]:9292 ipv6only=on;
    
        #listen 80 default_server;
    
        #listen [::]:80 default_server ipv6only=on;
    
        location / {		#location块:配置请求的路由,以及各种页面的处理情况。
    
          proxy_pass http://tomcat_client;		#3-IP监听跳转,代理指向
    
          proxy_redirect default;
    
          proxy_set_header Host $host;
    
          proxy_set_header X-Real-IP $remote_addr;
    
        }
    
      }
    
    }
    

    (4)创建tomcat

    sudo nano Dockerfile

    FROM ubuntu
    
    ADD jdk-8u211-linux-x64.tar.gz /usr/local
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_211
    
    ADD apache-tomcat-8.5.65.tar.gz /usr/local
    
    EXPOSE 8080
    
    ENTRYPOINT ["/usr/local/apache-tomcat-8.5.65/bin/catalina.sh", "run"]
    

    apache-tomcat-8.5.65.tar.gz

    jdk-8u211-linux-x64.tar.gz

    (5)创建webServer

    mkdir tomcatA   
    mkdir tomcatB
    mkdir tomcatC
    

    cd /home/ubuntu/lancl/docker_build/load_blance/webServer/tomcatA

    sudo nano index.jsp

    welcome to tomcat-A server
    

    cd tomcatB/

    sudo nano index.jsp

    welcome to tomcat-B server...
    

    cd tomcatC/

    sudo nano index.jsp

    welcome to tomcat-C server...lalala
    

    《Tips》

    针对实践任务中遇到的各类问题和解决办法进行总结(不少于5条)。

    1.实验心得

    1.镜像膨胀问题?

    • Dockerfile 的RUN指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。
    • 以 && 符号连接命令,串联成一行,这样执行后,只会创建-1层镜像。
    • 通过&&运算符,一行结束位置加上 符号,融合命令后,能够降低镜像的体积。

    2.挂载test

    • docker本身提供了一种机制,可以将主机上的某个目录与容器的某个目录(称为挂载点、或者叫卷)关联起来;
    • 修改主机上该目录的内容时,不需要同步容器,对容器来说是立即生效的;并且,挂载点可以让多个容器共享。
    • 参考:https://www.cnblogs.com/51kata/p/5266626.html

    3.ports -vs - expose

    • 不管是否指定主机端口,使用ports都会将端口暴露给主机。
    • expose不会将端口暴露给主机。

    4.配置路径混乱

    5.sudo gedit

    • open操作+/路径/文件名及后缀
    • 即可利用Ubuntu自带的文本编辑器gedit进行复制粘贴快速修改文件了

    6.查看端口占用

    sudo netstat -anp |grep 9292

    7.GitHub配置问题

    sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    

    2.问题记录

    1.PHP连接MySQL

    • pdo与mysqli有什么区别吗?
  • 相关阅读:
    hdu5728 PowMod
    CF1156E Special Segments of Permutation
    CF1182E Product Oriented Recurrence
    CF1082E Increasing Frequency
    CF623B Array GCD
    CF1168B Good Triple
    CF1175E Minimal Segment Cover
    php 正则
    windows 下安装composer
    windows apache "The requested operation has failed" 启动失败
  • 原文地址:https://www.cnblogs.com/lance-haha/p/14711139.html
Copyright © 2011-2022 走看看