docker 配置可以运行spark的容器并运行

来源:互联网 发布:淘宝零点抢购怎么抢 编辑:程序博客网 时间:2024/05/29 17:12

在前面,我们已经讲述了如何在Ubantu下配置docker以及如何运行spark连接本机的mysql进行增删改查的操作。
下面我们将手把手搭建一个docker容器来运行spark并分享我所遇到的问题和解决方法。
首先我先参照spark官网上docker setup写了一个hello world。
在官网上可以看出docker中images的创建需要创建Dockerfile
文件,官网上Dockerfile

FROM java:8 //从哪个镜像里面继承而来,已经是官网配置的可以run的程序,可以以为它是已经是一个完整的系统镜像# Install maven//下载mavenRUN apt-get updateRUN apt-get install -y mavenWORKDIR /code//这里就是我们运行spark给本机配置的一个程序# Prepare by downloading dependenciesADD pom.xml /code/pom.xml//添加当前目录的pom.xml到docker中的/code文件夹下,名字一样RUN ["mvn", "dependency:resolve"]//运行命令,就类似于在终端上运行命令“,”表示终端中的空格RUN ["mvn", "verify"]# Adding source, compile and package into a fat jarADD src /code/src//添加一个文件夹RUN ["mvn", "package"]EXPOSE 4567//打开端口CMD ["/usr/lib/jvm/java-8-openjdk-amd64/bin/java", "-jar", "target/sparkexample-jar-with-dependencies.jar"]//配置这条命令是每次打开容器,启动容器的时候都会运行这条命令,而上面的run就只会在创建的时候运行一次而已

当你用docker build -t xzj/spark:01 . (参照docker中保存镜像的格式,注意还有一个点)的时候,你就会发现,在 为容器下载maven的时候,运行好久都没过,很纠结。这时,是你被墙,不是你的代码又问题。

我的由于我已经清楚了Dockerfile的应用,
所以我直接用docker命令下载已经配置后的官网的镜像
命令:docker pull giantswarm/sparkexample

下载了官网上的镜像,接下来我要做的就是在容器里配置mysql以及ssh,方便登陆接口进入容器中直接配置。
接下来我的Dockerfile为

FROM giantswarm/sparkexample  从官网上容器里面继承WORKDIR /codeWORKDIR /code# Prepare by downloading dependenciesADD pom.xml /code/pom.xmlRUN ["mvn", "dependency:resolve"]RUN ["mvn", "verify"]# Adding source, compile and package into a fat jarADD src /code/srcRUN ["mvn", "package"]# 注意这里要更改系统的时区设置,因为在 web 应用中经常会用到时区这个系统变量,默认的 ubuntu 会让你的应用程序发生不可思议的效果哦ENV DEBIAN_FRONTEND noninteractive# 清空ubuntu更新包RUN sudo rm -rf /var/lib/apt/lists/*# 一次性安装vim,wget,curl,ssh server等必备软件# RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe"> /etc/apt/sources.listRUN sudo apt-get updateRUN sudo apt-get install -y vim wget curl openssh-server sudoRUN sudo mkdir -p /var/run/sshd# 将sshd的UsePAM参数设置成noRUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config# 添加测试用户admin,密码admin,并且将此用户添加到sudoers里RUN useradd adminRUN echo "admin:admin" | chpasswdRUN echo "admin   ALL=(ALL)       ALL" >> /etc/sudoers#为admin用户赋予sudo权限# 把admin用户的shell改成bash,否则SSH登录Ubuntu服务器,命令行不显示用户名和目录 RUN usermod -s /bin/bash admin# 安装supervisor工具RUN sudo apt-get install -y supervisorRUN sudo mkdir -p /var/log/supervisor# 添加 supervisord 的配置文件,并复制配置文件到对应目录下面。(supervisord.conf文件和Dockerfile文件在同一路径)COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf# 容器需要开放SSH 22端口EXPOSE 22# 容器需要开放SSH 4567端口EXPOSE 4567# 执行supervisord来同时执行多个命令,使用 supervisord 的可执行路径启动服务。CMD ["/usr/bin/supervisord"]

在这里我体会到了supervisord的强大,可以在程序启动的时候运行,相当于脚本却又比脚本高几个档次,直接创造进程,对进程进行了保护,保护进程不被创建时删除。

supervisor配置文件内容

# 配置文件包含目录和进程# 第一段 supervsord 配置软件本身,使用 nodaemon 参数来运行。# 第二段包含要控制的 2 个服务。每一段包含一个服务的目录和启动这个服务的命令。[supervisord]nodaemon=true[program:sshd]//运行进程command=/usr/sbin/sshd -D

运行docker build -t xzj/spark:01
创建第一个镜像。

运行docker run -p 9999:22 -p 4567:4567 -t -i xzj/spark:01
创建第一个容器并运行,-p 9999:22是打开端口9999:02

此时查看宿主机的9999端口,已经处于监听状态:

$ netstat -aunpt

再查看一下宿主机的IP地址,我这里的IP地址是172.17.0.1

$ ifconfig

登陆,通过ssh控制容器
ssh admin@172.17.0.1 -p 9999
进入后

root@xzj /home/xzj$ ssh admin@172.17.0.1 -p 9999admin@172.17.0.1's password: Last login: Thu May 18 08:46:49 2017 from 172.17.0.1Could not chdir to home directory /home/admin: No such file or directoryTo run a command as administrator (user "root"), use "sudo <command>".See "man sudo_root" for details.admin@860485568fbf:/$ 

然后在这里直接下载mysql为容器配置

sudo apt-get install mysql-server mysql-client

然后运行docker ps 查看正在运行的容器
用docker stop 860485568fbf 查看到的容器的id
用docker commit 860(id的前3位) xzj/spark:02
保存配置

再次建立容器docker run -p 9999:22 -p 4567:4567 -t -i xzj/spark:02

再次用ssh控制容器,发现在终端中并不能打开mysql的server

后来发现,原来是没有打开mysql server
运行sevices mysql start即可运行

然后我就想到我应该在打开容器的时候就要打开服务
所以我进一步想在supervisord.conf里面添加
添加
[program:mysql]
command=/usr/bin/pidproxy /var/run/mysqld/mysqld.pid /usr/sbin/mysqld
autorestart=true

后来才发现supervisord的配置是用python写的,想想还是有点小激动。

接下来就可以在终端运行mysql的server

然后接下来就是运行我在之前自己改的spark to mysql 程序

于是,在载入进入的时候,然后我又想在容器开始的时候就运行此后台程序。然而官网上的执行用的是java -jar ×××.jar
我就想效法它的方法,然后我就改我的pom.xml文件
将其打包为可以直接运行的jar文件,不用用maven运行
代码如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>me.tomassetti</groupId>    <artifactId>BlogService</artifactId>    <packaging>jar</packaging>    <version>1.0-SNAPSHOT</version>    <name>BlogService</name>    <url>http://maven.apache.org</url>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    </properties>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.12</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>com.sparkjava</groupId>            <artifactId>spark-core</artifactId>            <version>2.3</version>        </dependency>        <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-core</artifactId>            <version>2.6.4</version>        </dependency>        <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-databind</artifactId>            <version>2.6.4</version>        </dependency>        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <version>1.16.6</version>            <scope>provided</scope>        </dependency>        <dependency>            <groupId>org.sql2o</groupId>            <artifactId>sql2o</artifactId>            <version>1.5.4</version>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>          <version>5.1.17</version>        </dependency>        <dependency>            <groupId>org.postgresql</groupId>            <artifactId>postgresql</artifactId>            <version>9.4-1206-jdbc42</version>        </dependency>        <dependency>            <groupId>com.google.guava</groupId>            <artifactId>guava</artifactId>            <version>19.0</version>        </dependency>        <dependency>            <groupId>org.easymock</groupId>            <artifactId>easymock</artifactId>            <version>3.4</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>com.google.code.gson</groupId>            <artifactId>gson</artifactId>            <version>2.5</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>com.beust</groupId>            <artifactId>jcommander</artifactId>            <version>1.48</version>        </dependency>        <dependency>            <groupId>com.sparkjava</groupId>            <artifactId>spark-template-freemarker</artifactId>            <version>2.3</version>        </dependency>        <dependency>            <groupId>com.j2html</groupId>            <artifactId>j2html</artifactId>            <version>0.7</version>        </dependency>    </dependencies>    <build>    <plugins>      <plugin>        <groupId>org.apache.maven.plugins</groupId>        <artifactId>maven-jar-plugin</artifactId>        <version>2.4</version>        <configuration>          <finalName>BlogService</finalName>          <archive>            <manifest>              <addClasspath>true</addClasspath>              <mainClass>me.tomassetti.BlogService</mainClass>              <classpathPrefix>dependency-jars/</classpathPrefix>            </manifest>          </archive>        </configuration>      </plugin>      <plugin>        <groupId>org.apache.maven.plugins</groupId>        <artifactId>maven-compiler-plugin</artifactId>        <version>3.1</version>        <configuration>          <source>1.8</source>          <target>1.8</target>        </configuration>      </plugin>      <plugin>        <groupId>org.apache.maven.plugins</groupId>        <artifactId>maven-assembly-plugin</artifactId>        <executions>          <execution>            <goals>              <goal>attached</goal>            </goals>            <phase>package</phase>            <configuration>              <finalName>BlogService</finalName>              <descriptorRefs>                <descriptorRef>jar-with-dependencies</descriptorRef>              </descriptorRefs>              <archive>                <manifest>                  <mainClass>me.tomassetti.BlogService</mainClass>                </manifest>              </archive>            </configuration>          </execution>        </executions>      </plugin>    </plugins>  </build>      </project>

最后生成
BlogService-jar-with-dependencies.jar在target
之中,可以直接运行

后来发现用postma测试的时候连接不上mysql
显示是no suitable driver
后来发现需要在pom.xml里面载入mysql-connect环境
加入

mysql
mysql-connector-java
5.1.17

此时又一次感觉到可maven的强大,可以最便利得根据依赖关系配置相应的环境。

我进一步再supervisord中加入运行spark程序的命令

[program:sparkexample]
command=/usr/lib/jvm/java-8-oracle/bin/java -jar /code/target/BlogService-jar-with-dependencies.jar
autorestart=true

重新构建一个镜像就可以运行了。

成功图示

这里写图片描述

原创粉丝点击