• 第四次实践作业


    通过前面几次的实验,大家已经基本熟悉Docker、Dockerfile、Docker Compose的相关操作,从本次实验开始,将结合此前相关课程内容,安排一些相关技术专题实践:

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

    要求:
    理解nginx反向代理原理;
    nginx代理tomcat集群,代理2个以上tomcat;
    了解nginx的负载均衡策略,并至少实现nginx的2种负载均衡策略;
    参考资料:
    Docker下Nginx+Tomcat实现负载均衡
    使用docker-compose搭建反向代理nginx+tomcat页面
    实战docker,构建nginx反向代理tomcat,学习link和docker-compose
    nginx使用Upstream实现负载均衡
    浅谈docker-compose网络设置之networks

    一:

    正向代理
    正向代理服务器位于客户端和服务器之间,为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里客户端是要进行一些正向代理的设置的。
    反向代理
    反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

    二:

    首先,从docker仓库中拉取nginx和tomcat镜像

    docker pull nginx
    docker pull tomcat
    

    创建工程目录

    然后编写nginx.conf和dockerfile_nginx
    dockerfile_nginx

    FROM docker.io/nginx
    #使用的原镜像	
    ENV WORK_PATH /etc/nginx
    #设置变量	WORK_PATH= /etc/nginx
    WORKDIR /etc/nginx
    #设置默认当前路径为/etc/nginx
    ENV NGINX_FILE_CONF nginx.conf
    #设置变量NGINX_FILE_CONF=nginx.conf
    RUN rm  $NGINX_FILE_CONF
    #删除原有的nginx.conf文件
    COPY nginx.conf .
    #把目录下的 nginx.conf复制到容器当前
    

    nginx.conf

    user  nginx;
    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 tomcat_client {
             server tomcat1:8080 weight=1;
             server tomcat2:8080 weight=1;
    	 server tomcat3:8080 weight=1;
        } 
    
        server {
            server_name "";
            listen 80 default_server;
            listen [::]:80 default_server ipv6only=on;
    
            location / {
                proxy_pass http://tomcat_client;
                proxy_redirect default;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
            }
        }
    }
    

    编写docker-compose.yml

    version: "3"
    services:
      tomcat1:
        image: tomcat:latest
        volumes:
          - ./tomcat1/:/usr/local/tomcat/webapps/ROOT/
        restart: "always"
        container_name: tomcat1
      tomcat2:
        image: tomcat:latest
        volumes:
          - ./tomcat2/:/usr/local/tomcat/webapps/ROOT/
        container_name: tomcat2
        restart: "always"
      tomcat3:
        image: tomcat:latest
        volumes:    
          - ./tomcat3/:/usr/local/tomcat/webapps/ROOT/
        container_name: tomcat3
        restart: "always"
      nginx:
        image: nginx:latest
        volumes:
          - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        ports:
          - "80:80"
        links:
          - tomcat1:t1
          - tomcat2:t2
          - tomcat3:t3
    

    运行docker-compose.yml

    轮询策略(就是upstream默认的策略)


    权重策略(修改nginx.conf,为t1,t2,t3选择合适的权重值,nginx会根据权重来选择访问的服务器,权重越高越优先)

    可以看到tomcat3出现的次数明显更多

    (2) 使用Docker-compose部署javaweb运行环境
    要求:
    分别构建tomcat、数据库等镜像服务;
    成功部署Javaweb程序,包含简单的数据库操作;
    为上述环境添加nginx反向代理服务,实现负载均衡。

    工程目录

    其中nginx与tomcat的配置几乎没变,这里就不贴出来了

    dockerfile_mysql

    FROM mysql:5.7
    MAINTAINER wcx
    WORKDIR /usr/local/
    ENV MYSQL_ROOT_PASSWORD 123456
    ENV MYSQL_ALLOW_EMPTY_PASSWORD no
    
    COPY schema.sql /usr/local/
    COPY setup.sh /usr/local/
    RUN chmod a+x /usr/local/setup.sh
    ENTRYPOINT ["/usr/local/setup.sh"]
    EXPOSE 80
    

    setup.sh

    #!/bin/bash
    set -e
     
    #查看mysql服务的状态,方便调试,这条语句可以删除
    echo `service mysql status`
     
    echo '1.启动mysql....'
    #启动mysql
    service mysql start
    sleep 3
    echo `service mysql status`
     
    echo '2.开始导入数据....'
    #导入数据
    mysql < /usr/local/schema.sql
    echo '3.导入数据完毕....'
     
    sleep 3
    echo `service mysql status`
    #sleep 3
    echo `service mysql status`
    echo `mysql容器启动完毕,且数据导入成功`
    
    sleep 3
    echo `重新启动mysql服务`
    service mysql restart
    tail -f /dev/null
    

    schema.sql

    CREATE database `testDatabase` default character set utf8 collate utf8_general_ci;
    use testDatabase;
    DROP TABLE IF EXISTS testTable;
    CREATE TABLE testTable(
      `id` varchar(20) UNIQUE,
      `name` varchar(10) NOT NULL,
      `sex` varchar(1) NOT NULL,
      PRIMARY KEY (`id`)
    )ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    INSERT INTO testTable
     VALUES 
      ('1','testname','m'),('2','test1','w');
    

    docker-compose.yml

    version: '2'
    services:
     mysql:
      image: mysqlimage
      container_name: mysqlimage
      build:
       context: ./mysql/
       dockerfile: dockerfile_mysql
      volumes:
       - ./mysql:/usr/local/
      restart: always
     tomcat1:
      image: tomcat:latest
      volumes:
       - ./tomcat1/:/usr/local/tomcat/webapps/
      restart: "always"
      container_name: tomcat1
      links:
       - mysql:mysql
     tomcat2:
      image: tomcat:latest
      volumes:
       - ./tomcat2/:/usr/local/tomcat/webapps/
      links:
       - mysql:mysql
      container_name: tomcat2
      restart: "always"
     tomcat3:
      image: tomcat:latest
      volumes:    
       - ./tomcat3/:/usr/local/tomcat/webapps/
      links:
       - mysql:mysql
      container_name: tomcat3
      restart: "always"
     nginx:
      image: nginx
      build:
       context: ./nginx
       dockerfile: dockerfile_nginx
      volumes:
       - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      ports:
       - "80:80"
      links:
       - tomcat1:t1
       - tomcat2:t2
       - tomcat3:t3
    

    增加数据

    更新数据

    删除数据

    参考资料:
    使用docker-compose部署Javaweb项目
    手把手搭建javaweb项目,适合新手
    tomcat+nginx-mysql
    (3)使用Docker搭建大数据集群环境
    直接用机器搭建Hadoop集群,会因为不同机器配置等的差异,遇到各种各样的问题;也可以尝试用多个虚拟机搭建,但是这样对计算机的性能要求比较高,通常无法负载足够的节点数;使用Docker搭建Hadoop集群,将Hadoop集群运行在Docker容器中,使Hadoop开发者能够快速便捷地在本机搭建多节点的Hadoop集群。
    要求:
    完成hadoop分布式集群环境配置,至少包含三个节点(一个master,两个slave);
    成功运行hadoop 自带的测试实例。

    一、构建ubuntu:hadoop
    工程目录

    dockerfile

    FROM ubuntu:18.04
    MAINTAINER wcx
    COPY hadoop.zip /usr/local/
    COPY sources.list /etc/apt/
    
    RUN apt-get update && apt-get install -y 
    	vim 
    	openjdk-8-jdk 
            ssh
    
    EXPOSE 80
    

    source.list是国内源文件
    hadoop.zip是hadoop3.1.3的压缩包
    使用docker build -t ubuntu:hadoop .构建镜像

    docker build -t ubuntu:hadoop .
    

    进入ubuntu:hadoop镜像

    docker run -it ubuntu:hadoop /bin/bash
    

    在该镜像中解压/usr/local/hadoop.zip(apt-get install unzip)

    unzip hadoop.zip
    

    配置java,hadoop的环境变量

    vim ~/.bashrc
    添加如下代码
    export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
    export PATH=$PATH:$JAVA_HOME/bin
    export HADOOP_HOME=/usr/local/hadoop
    export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
    export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin:$JAVA_HOME/bin
    然后source  ~/.bashrc使之生效
    


    检验hadoop和java

    配置ssh免密登陆

    ssh-keygen -t rsa # 一直按回车即可
    cd  ~/.ssh
    cat id_rsa.pub >> authorized_keys
    


    输入ssh localhost验证一下

    此时可以进入到下一个阶段:hadoop文件配置
    首先进入hadoop/etc/hadoop

    配置hadoop-env

    配置core-site.xml
    标签中添加

    	<property>
    		<name>hadoop.tmp.dir</name>
    		<value>file:/usr/local/hadoop/tmp</value>
    	</property>
    	<property>
    		<name>fs.defaultFS</name>
    		<value>hdfs://localhost:9000</value>
    	</property>
    

    配置hdfs-site.xml
    标签中添加

    	<property>
    		<name>dfs.replication</name>
    		<value>1</value>
    	</property>
    	<property>
    		<name>dfs.namenode.name.dir</name>
    		<value>file:/usr/local/hadoop/tmp/dfs/name</value>
    	</property>
    	<property>
    		<name>dfs.datanode.data.dir</name>
    		<value>file:/usr/local/hadoop/tmp/dfs/data</value>
    	</property>
    

    配置mapred-site.xml
    标签中添加

        <property>
            <name>mapreduce.framework.name</name>
            <value>yarn</value>
        </property>
        <property>
            <name>yarn.app.mapreduce.am.env</name>
            <value>HADOOP_MAPRED_HOME=/usr/local/hadoop</value>
        </property>
        <property>
            <name>mapreduce.map.env</name>
            <value>HADOOP_MAPRED_HOME=/usr/local/hadoop</value>
        </property>
        <property>
            <name>mapreduce.reduce.env</name>
            <value>HADOOP_MAPRED_HOME=/usr/local/hadoop</value>
        </property>
    

    配置yarn-site.xml
    操作同上

          <property>
                 <name>yarn.nodemanager.aux-services</name>
                 <value>mapreduce_shuffle</value>
          </property>
          <property>
                 <name>yarn.resourcemanager.hostname</name>
                 <value>Master</value>
          </property>
          <property>
                 <name>yarn.nodemanager.vmem-pmem-ratio</name>
                 <value>2.5</value>
          </property>
    


    进入hadoop脚本目录(sbin)
    配置start-dfs.sh 和stop-dfs.sh

    HDFS_DATANODE_USER=root
    HADOOP_SECURE_DN_USER=hdfs
    HDFS_NAMENODE_USR=root
    HDFS_SECONDARYNAMENODE_USER=root
    

    配置start-yarn.sh和stop-yarn.sh

    YARN_RESOURCEMANAGER_USER=root
    HADOOP_SECURE_DN_USER=yarn
    YARN_NODEMANAGER_USER=root
    

    退出容器,接着用该容器构建新的镜像ubuntu-hadoop

    docker commit 容器ID 新镜像名
    

    运行三个终端,

    docker run -it -h 主机名 --name 容器名 镜像名
    




    查看三个主机的ip地址

    sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' 名字
    

    进入master容器,配置/usr/local/hadoop/etc/hadoop/workers(将localhost删去,改为slave1和slave2)

    分别对三个主机的/etc/hosts进行修改,添加如下内容

    172.17.0.2      master
    172.17.0.3      slave1
    172.17.0.4      slave2
    


    互相ssh测试



    差不多就能确定可以互相登陆
    进入master主机,初始化namenode等

    hdfs namenode -format #初始化namenode
    start-dfs.sh      #启动HDFS
    start-yarn.sh      #启动YARN
    


    到此hdfs完全分布式环境已搭建完毕
    运行案例grep
    在master上执行如下命令

    hdfs dfs -mkdir -p /user/root/input    #新建input文件夹
    hdfs dfs -put /usr/local/hadoop/etc/hadoop/*s-site.xml input  #将部分文件放入input文件夹
    hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep input output 'dfs[a-z.]+'    #运行示例程序grep
    hdfs dfs -cat output/*  
    

    参考资料:
    Hadoop 参考文档
    使用Docker搭建Hadoop分布式集群

    (4)遇到的问题


    这个是因为在nginx的配置项extnetwork:中的ipv4_address的' : '后没加空格,属于格式问题
    2.

    这个是因为没用sudo执行docker-compose命令


    首先,查看docker images和docker container ,发现mysql镜像已经成功创建,而相应容器却仍停留在created状态,说明容器虽能创建成功,却无法启动。
    尝试进入该容器,成功。检查要上传的文件(setup.sh等),发现已存在在该容器中。尝试手动在该容器中运行setup.sh,发现schema.sql中存在语法问题。修正schema.sql,重新compose up,却依旧是出现同样的错误。经老师与同学的帮助,在dockrfile中用ENTRYPOINT命令代替CMD命令为setup.sh赋予权限,并在本地也赋予setup.sh的权限。再次compose up,容器启动成功。但当进入mysql容器时,每次都会执行setup.sh,且执行完无响应,即无法进入容器的命令行界面。于是猜测是setup.sh的问题,经过尝试,在setup.sh中增加一句service mysql restart后容器运行正常。(不是很懂这个,有知道的大佬可以评论一下咩╮(╯_╰)╭)

    又是这个。。。这个是因为master节点执行了多次hdfs namenode -format导致clusterID与slave1和slave2的不同,因此打开master的hdfs-site.xml文件查看namenode的存放文件,再进入该文件中,找到current/VESION,cat一下,复制里面的clusterID,然后进入slave节点,同上找到datanode的存放目录,找到current/VERSION,将里面的clusterID改为master的clusterID后,执行stop-dfs.sh等命令重启hdfs集群,再重新建立相应的输入输出文件夹,执行测试程序,便可成功运行。
    5.
    执行测试程序时界面卡在Job running这句。
    解决方法:
    将mapred-site.xml中的

    <property>
           <name>mapreduce.framework.name</name>
           <value>yarn</value>
    </property>
    

    替换为

    <property>
          <name>mapreduce.job.tracker</name>
          <value>hdfs://此处为自己的电脑IP:8001</value>
          <final>true</final>
     </property>
    

    替换后程序运行飞快,很流畅。

  • 相关阅读:
    A Tour of Go For continued
    A Tour of Go For
    Request对象的主要方法
    JAVA中的异常疑点解析
    用JDBC如何调用存储过程
    字节流与字符流的区别
    js判断第二个日期比第一个日期大
    JAVA中会存在内存泄露吗
    mysql 建库建表建用户
    mysql 的数据类型
  • 原文地址:https://www.cnblogs.com/wuchangxing/p/12894969.html
Copyright © 2020-2023  润新知