通过前面几次的实验,大家已经基本熟悉Docker、Dockerfile、Docker Compose的相关操作,从本次实验开始,将结合此前相关课程内容,安排一些相关技术专题实践:
(1)使用Docker-compose实现Tomcat+Nginx负载均衡
-
理解nginx反向代理原理;
-
nginx代理tomcat集群,代理2个以上tomcat;
-
了解nginx的负载均衡策略,并至少实现nginx的2种负载均衡策略;
参考:
nginx配置详解
Nginx服务器之负载均衡策略
1.nginx反向代理原理:总结一句话:正向代理代理客户端,反向代理代理服务器。
2.nginx代理tomcat集群
-
下载tomcat
-
建立一下配置文件目录
-
编写配置文件
default.conf
upstream Tomcatweb{
server ruinTom1:8080 max_fails=3 fail_timeout=60s; #允许失败三次,失败60s后再来
server ruinTom2:8080 max_fails=3 fail_timeout=60s;
server ruinTom3:8080 max_fails=3 fail_timeout=60s;
}
server {
listen 2506;
server_name localhost;
location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
proxy_pass http://Tomcatweb; #访问nginx,实在访问代理服务器,
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
docker-compose.yml
version: '3.3'
services:
nginx:
image: nginx
container_name: ruinnginx
ports:
- 80:2506
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on: #设置了upstream,则nginx依赖以下三个
- tomcat1
- tomcat2
- tomcat3
tomcat1:
image: tomcat
container_name: ruinTom1
volumes:
- ./tomcat1:/usr/local/tomcat/webapps/ROOT
tomcat2:
image: tomcat
container_name: ruinTom2
volumes:
- ./tomcat2:/usr/local/tomcat/webapps/ROOT
tomcat3:
image: tomcat
container_name: ruinTom3
volumes:
- ./tomcat3:/usr/local/tomcat/webapps/ROOT
index.html
I am Tomcat1! #index.html的三个界面
I am Tomcat2!
I am Tomcat3!
docker-compose up
轮询策略测试
权重策略测试
server ruinTom1:8080 weight=3 max_fails=3 fail_timeout=60s; #权重越大,相应被访问的服务器次数越多
server ruinTom2:8080 weight=2 max_fails=3 fail_timeout=60s;
server ruinTom3:8080 weight=1 max_fails=3 fail_timeout=60s;
}
(2) 使用Docker-compose部署javaweb运行环境
要求:
- 分别构建tomcat、数据库等镜像服务;
- 成功部署Javaweb程序,包含简单的数据库操作;
- 为上述环境添加nginx反向代理服务,实现负载均衡。
参考资料:
使用docker-compose部署Javaweb项目
tomcat+nginx-mysql
编写配置文件
- default.conf
server ruintomcat:8080;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://tomweb;
}
}
- docker-compose.yml
services:
tomcat:
image: tomcat
hostname: hostname
container_name: ruintomcat
ports:
- "5050:8080"
volumes:
- "$PWD/webapps:/usr/local/tomcat/webapps"
networks:
webnet:
ipv4_address: 15.22.0.15
mymysql:
build: .
image: mymysql:test
container_name: mymysql
ports:
- "3306:3306"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci'
]
environment:
MYSQL_ROOT_PASSWORD: "123456"
networks:
webnet:
ipv4_address: 15.22.0.6
networks:
webnet:
driver: bridge
ipam:
config:
- subnet: 15.22.0.0/24
gateway: 15.22.0.2
- docker-entrypoint.sh
mysql -uroot -p123456 << EOF
source /usr/local/grogshop.sql;
- Dockerfile
FROM registry.saas.hand-china.com/tools/mysql:5.7.17
# mysql的工作位置
ENV WORK_PATH /usr/local/
# 定义会被容器自动执行的目录
ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
#复制gropshop.sql到/usr/local
COPY grogshop.sql /usr/local/
#把要执行的shell文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个shell
COPY docker-entrypoint.sh $AUTO_RUN_DIR/
#给执行文件增加可执行权限
RUN chmod a+x $AUTO_RUN_DIR/docker-entrypoint.sh
# 设置容器启动时执行的命令
#CMD ["sh", "/docker-entrypoint-initdb.d/import.sh"]
- 修改连接数据库的IP
启动容器
docker-compose up
(4) 浏览页面
利用界面对数据库操作(增删改查)
#利用sql语句,在终端查询
select * from room
(3)使用Docker搭建大数据集群环境
直接用机器搭建Hadoop集群,会因为不同机器配置等的差异,遇到各种各样的问题;也可以尝试用多个虚拟机搭建,但是这样对计算机的性能要求比较高,通常无法负载足够的节点数;使用Docker搭建Hadoop集群,将Hadoop集群运行在Docker容器中,使Hadoop开发者能够快速便捷地在本机搭建多节点的Hadoop集群。
- 完成hadoop分布式集群环境配置,至少包含三个节点(一个master,两个slave);
- 成功运行hadoop 自带的测试实例。
pull nginx镜像
docker pull nginx
- 在个人文件夹下创建一个build目录,存放hadoop压缩文件(待会要用),用于向docker内部的ubuntu系统传输文件,在docker上运行ubuntu系统,在该镜像上运行容器
docker ruin -it -v /home/ruin-master/build:/root/build --name ubuntu ubuntu
安装并更新
apt-get update
apt-get install vim
apt-get install ssh #安装sshd服务,用于连接slave
/etc/init.d/ssh start #开启sshd服务
vim ~/.bashrc
添加 /etc/init.d/ssh start
添加vim后,立即换源
vim /etc/apt/sources.list
配置ssh 免密登录localhost
cd ~/.ssh
ssh-keygen -t rsa #一直按回车
cat id_rsa.pub >> authorized_keys
安装JDK
apt-get update
apt-get install openjdk-8-jdk
vim ~/.bashrc #添加以下两行
export JAVA_HOME=/usr/lib/jvm/openjdk-8-jdk-amd64/
expori PATH=$PATH:$JAVA_HOME/bin
source ~/.bashrc #使生效
配置完成后,把ubuntu容器生成镜像,将里面操作保存
#开另一个终端
docker ps #c查id
docker commit 容器id ubuntu:jdk8
sudo docker run -it -v /home/ruin-master/build:/root/build --name hadoop_ubuntu ubuntu:jdk8 #新生成的镜像上在运行一个hadoop_ubuntu容器
装上hadoop
cd root/build #进入build文件
tar -zxvf hadoop-3.1.3.tar.zip -C /usr/local #解压文件到/usr/local
cd /usr/local/hadoop
.bin/hadoop version #检测是否安装成功
各配置文件的修改
- hadoop-env.sh
cd /usr/local/hadoop-3.1.3/etc/hadoop #进入hadoop的各配置文件存放目录
vim hadoop-env.sh
export JAVA_HOME=/usr/lib/jvm/openjdk-8-jdk-amd64/ #添加该行
- core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://Master:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop-3.1.3/tmp</value>
<description>A base for other temporary directories.</description>
</property>
</configuration>
- hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/local/hadoop-3.1.3/tmp/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/localhadoop-3.1.3/tmp/dfs/data</value>
</property>
</configuration>
- mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>Master:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>Master:19888</value>
</property>
<property>
<name>mapreduce.application.classpath</name>
<value>/usr/local/hadoop-3.1.3/share/hadoop/mapreduce/lib/*,/usr/local/hadoop-3.1.3/share/hadoop/mapreduce/*</value>
</property>
<configuration>
- yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>Master</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.5</value>
</property>
</configuration>
-
修改配置文件[参照这里]
-
修改start-dfs.sh stop-dfs.sh
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
- 修改start-yarn.sh stop-yarn.sh
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
保存镜像
docker ps
docker commit 容器id hadoop_ubuntu:jdk8
运行hadoop集群
- 基于hadoop_ubuntu:jdk8,三个终端分别启动三个容器,Master,slave1,slave2
第一个终端
sudo docker run -it -h Master --name Master hadoop_ubuntu:jdk8 #注意这里名字要和配置文件中一样
第二个终端
sudo docker run -it -h slave1 --name slave1 hadoop_ubuntu:jdk8
第三个终端
sudo docker run -it -h slave2 --name slave2 hadoop_ubuntu:jdk8
分别进入各个容器中修改/etc/hosts
#要根据里面具体ip修改,都修改成以下的样子
vim /etc/hosts
127.17.0.3 Master
127.17.0.4 slave1
127.17.0.5 slave2
- Master里面修改
cd /usr/local/hadoop-3.1.3/etc/hadoop #进入Master的该目录修改workers文件
vim workers #把localhost换成以下两行
slave1
slave2
- Master尝试连接slave1和slave2,是否免密,登录完千万记得exit!
ssh slave1
exit
ssh slave2
exit
测试hadoop集群
cd /usr/local/hadoop-3.1.3
bin/hdfs dfs namenode -format #第一次启动hadoop要格式化,后面不能轻易格式化,特别是在工作中
sbin/start-all.sh
- 格式化成功标志
- jps各节点查看是否启动,以下启动成功标志
- 前期工作
bin/hdfs dfs -mkdir /user
bin/hdfs dfs -mkdir /user/root #根目录下,因为hdfs相对路径就是根目录下的文件
bin/hdfs dfs -mkdir /user/root/input
- 拷贝测试文件到input下
bin/hdfs dfs -put ~/text.txt input #呼应以上:hdfs相对路径就是根目录下的文件
- 运行hadoop自带的例子wordcount
bin/hadoop jar /usr/local/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount input output
- 在input同目录下生成了output,把output cat出来
- 执行成功!
总结
遇到的问题
(1)做第一个实验时,启动容器始终启动不起来,查看log或者页面,报一下错误:
解决方式 :发现在配置文件中upstream 中定义了“Tomcat_web”,“_”是一个无效字符,要把它删去
(2)做第三个实验时,启动容器报以下错误
解决方式:在三个终端上配置Master、slave的ip时候要把有点"::"的语句都删除
总结:四个字:心力交瘁!花的时间很多,三天左右,真的太难了,最恐怖的是连做梦都梦见我在搭建容器。只能说自己知识实在太弱了,道路还很长啊!