一、docker不是虚拟机 docker有别于传统虚拟化,他不是一个虚拟机,而是容器,本质就是在主机上运行的一个特殊的进程。所以docker比虚拟机更轻、启动更快、调用底层更直接。 关于docker容器和虚拟机的更多对比,可以参考以下一些文章:虚拟机与Docker有何不同? 反思|容器与虚拟机的真正区别在哪里?
二、开始使用docker 在ubuntu下安装docker 添加使用HTTPS传输的安全依赖和CA证书软件
1 sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
使用阿里的源安装
1 2 3 4 5 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ $(lsb_release -cs) \ stable"
腾讯云的源
1 2 3 4 5 curl -fsSL https://mirrors.cloud.tencent.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.cloud.tencent.com/docker-ce/linux/ubuntu \ $(lsb_release -cs) \ stable"
华为云源
1 2 3 4 5 curl -fsSL https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu \ $(lsb_release -cs) \ stable"
以上命令会添加稳定版本的 Docker CE APT 镜像源,如果需要最新版本的 Docker CE 请将 stable 改为 edge 或者 test。从 Docker 17.06 开始,edge test 版本的 APT 镜像源也会包含稳定版本的 Docker。
安装docker-ce
1 2 sudo apt update sudo apt-get install docker-ce
经过以上步骤,docker最新版就安装好了。 也可以安装指定版本,使用命令查看可用版本:
1 2 3 4 5 6 7 8 ubuntu@wx:/etc/kubernetes$ apt-cache madison docker-ce docker-ce | 17.09.0~ce-0~ubuntu | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages docker-ce | 17.06.2~ce-0~ubuntu | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages docker-ce | 17.06.1~ce-0~ubuntu | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages docker-ce | 17.06.0~ce-0~ubuntu | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages docker-ce | 17.03.2~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
使用命令安装指定版本:
1 sudo apt-get install docker-ce=<VERSION>
使用systemctl命令查看docker进程是active状态
1 2 3 4 5 6 7 8 9 ubuntu@ubuntu1:~$ systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since 五 2017-10-20 17:01:59 CST; 28min ago Docs: https://docs.docker.com Main PID: 8530 (dockerd) CGroup: /system.slice/docker.service ├─8530 /usr/bin/dockerd -H fd:// └─8538 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout
docker的镜像 docker官方仓库也有很多镜像可以选择,使用docker search命令可以搜索到. 例如我搜索ubuntu镜像,结果显示有很多,其中有官方的也有第三方build的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ubuntu@wx:~/compose-hadoop-spark/hadoop$ docker search ubuntu NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Ubuntu is a Debian-based Linux operating s... 6677 [OK] dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC 136 [OK] rastasheep/ubuntu-sshd Dockerized SSH service, built on top of of... 108 [OK] ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 87 [OK] ubuntu-upstart Upstart is an event-based replacement for ... 80 [OK] neurodebian NeuroDebian provides neuroscience research... 40 [OK] ubuntu-debootstrap debootstrap --variant=minbase --components... 31 [OK] nuagebec/ubuntu Simple always updated Ubuntu docker images... 22 [OK] tutum/ubuntu Simple Ubuntu docker images with SSH access 18 1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 16 [OK] ppc64le/ubuntu Ubuntu is a Debian-based Linux operating s... 11 aarch64/ubuntu Ubuntu is a Debian-based Linux operating s... 9 i386/ubuntu Ubuntu is a Debian-based Linux operating s... 8 codenvy/ubuntu_jdk8 Ubuntu, JDK8, Maven 3, git, curl, nmap, mc... 3 [OK] darksheer/ubuntu Base Ubuntu Image -- Updated hourly 3 [OK] 1and1internet/ubuntu-16-apache-php-7.0 ubuntu-16-apache-php-7.0
使用docker pull ubuntu:version命令,可以把镜像下载下来使用。 第一步我们需要下载一个ubuntu 16的镜像:
1 sudo docker pull ubuntu:16.04
三、使用dockerfile构建镜像 我们的目标是吧hadoop+spark集成环境构建成自己的镜像,使用镜像搭建3节点的spark集群。 在这个过程中学习使用dockerfile,dockerfile定义了很多命令,我们下面会介绍我们使用到的命令,更多命令用法可以参考官方文档。
FROM FROM意思是使用一个镜像做基础,我们使用刚刚下载的ubuntu镜像
USER USER意思是切换用户,必须要用户存在才可以,后续操作就使用这个用户执行
RUN RUN是运行命令的意思,构建镜像就是在原有镜像基础进行定制化,必须会运行一些命令,例如新建帐户、改权限、下载安装包等 示例:新建hadoop用户并赋予sudo免密权限
1 2 3 4 5 RUN groupadd hadoop \ && useradd -g hadoop -G sudo -m hadoop \ && chmod u+w /etc/sudoers \ && echo 'hadoop ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers \ && chmod u-w /etc/sudoers
ENV ENV是添加环境变量,对后续操作生效,例如JAVA_HOME
1 ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
后续的RUN命令可以使用$JAVA_HOME
WORKDIR 指定容器启动后的工作目录,可以把程序或脚本放在这个目录
COPY COPY是复制文件,可以把文件复制进镜像,这里我们把hadoop的配置文件预先写好一并复制进镜像
1 COPY ./*-site.xml $HADOOP_PREFIX/etc/hadoop/
CMD CMD是启动镜像默认运行的命令,如果docker run指定了其他命令则CMD会忽略。 需要注意进程不要后台运行,后台运行的命令在容器看来驻留后台的时候就已经结束了,记住docker是容器。所以要保持容器运行,命令需要前台运行。
1 CMD [ "sh", "-c", "sudo service ssh start; bash"]
ENTRYPOINT ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行,ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。
1 ENTRYPOINT ["/bin/echo", "Hello"]
如果同时存在ENTRYPOINT和CMD,CMD会被当作参数传入ENTRYPOINT,docker run运行时指定的命令会作为参数覆盖CMD,传入ENTRYPOINT成为新参数。
k8s中,在pod定义command和args会覆盖镜像的ENTRYPOINT和CMD参数
Image Entrypoint
Image Cmd
Container command
Container args
Command run
[/ep-1]
[foo bar]
[ep-1 foo bar]
[/ep-1]
[foo bar]
[/ep-2]
[ep-2]
[/ep-1]
[foo bar]
[zoo boo]
[ep-1 zoo boo]
[/ep-1]
[foo bar]
[/ep-2]
[zoo boo]
[ep-2 zoo boo]
更完整的定义参考Dockerfile介绍
完整的dockerfile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 FROM ubuntu:16.04 USER root # install base tools RUN apt update \ && apt install -y curl tar sudo openssh-server openssh-client rsync openjdk-8-jdk ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 PATH=$PATH:$JAVA_HOME/bin # add hadoop user and passwordless ssh RUN groupadd hadoop \ && useradd -g hadoop -G sudo -m hadoop \ && chmod u+w /etc/sudoers \ && echo 'hadoop ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers \ && chmod u-w /etc/sudoers USER hadoop RUN ssh-keygen -q -N "" -t rsa -f ~/.ssh/id_rsa \ && cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys \ && echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCfyJOeBBSHCQVu6/ ubuntu@wx" >> ~/.ssh/authorized_keys \ && chmod 600 ~/.ssh/authorized_keys \ && echo 'StrictHostKeyChecking no' > ~/.ssh/config # download and config hadoop RUN curl -s http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.8.1/hadoop-2.8.1.tar.gz |sudo tar -xz -C /usr/local/ \ && sudo chown -R hadoop:hadoop /usr/local/hadoop-2.8.1 \ && sudo ln -s /usr/local/hadoop-2.8.1 /usr/local/hadoop \ && mkdir /usr/local/hadoop/tmp ENV HADOOP_PREFIX /usr/local/hadoop RUN sudo sed -i '/^export JAVA_HOME/ s:.*:export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64\nexport HADOOP_PREFIX=/usr/local/hadoop\nexport HADOOP_HOME=/usr/local/hadoop\n:' $HADOOP_PREFIX/etc/hadoop/hadoop-env.sh \ && sudo sed -i '/^export HADOOP_CONF_DIR/ s:.*:export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop/:' $HADOOP_PREFIX/etc/hadoop/hadoop-env.sh COPY ./*-site.xml $HADOOP_PREFIX/etc/hadoop/ COPY ./slaves $HADOOP_PREFIX/etc/hadoop/slaves # download and config spark RUN curl -s https://d3kbcqa49mib13.cloudfront.net/spark-2.2.0-bin-hadoop2.7.tgz |sudo tar -xz -C /usr/local/ \ && sudo chown -R hadoop:hadoop /usr/local/spark-2.2.0-bin-hadoop2.7 \ && sudo ln -s /usr/local/spark-2.2.0-bin-hadoop2.7 /usr/local/spark ENV SPARK_HOME /usr/local/spark COPY ./slaves $SPARK_HOME/conf/slaves RUN echo 'export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop' >> $SPARK_HOME/conf/spark-env.sh COPY ./start-service.sh /home/hadoop/start-service.sh RUN sudo chmod +x /home/hadoop/start-service.sh CMD [ "sh", "-c", "sudo service ssh start; bash"]
build镜像 使用命令docker build构建镜像,进入Dockerfile所在目录,运行如下命令
1 sudo docker build -t spark:0.1 .
需要注意命令中’.’代表当前目录,这影响到Dockerfile中的参数环境。 -t 镜像名称:版本
四、网络 搭建3节点集群需要把节点放在同一个虚拟网络环境下,节点间通过hostname可以互联。docker在这方面提供了方便的实现,我们通过简单的命令创建一个叫net1的网络环境。
1 sudo docker network create --driver=bridge net1
使用docker network查看当前存在的网络
1 2 3 4 5 6 ubuntu@wx:~/dockerimg/hadoop$ sudo docker network ls NETWORK ID NAME DRIVER SCOPE bbc1b008d971 bridge bridge local 6c90e7d1cdd9 host host local 2d74b1e3b79d net1 bridge local e4753da64f2b none null local
五、启动 我们先启动2个slave节点,使用如下命令
1 sudo docker run -itd --rm --net=net1 -v /data/hadoop/slave1/tmp:/usr/local/hadoop/tmp -h hadoop-slave1 --name hadoop-slave1 spark:0.1
-v 把本地目录/data/hadoop/slave1/tmp 挂在到容器目录/usr/local/hadoop/tmp –rm 当容器进程退出就删除容器 –it 交互模式 -d 后台运行 -h hostname slave1改成slave2启动节点2
启动master节点
1 sudo docker run -it --rm --net=net1 -p 8080:8080 -p 8020:8020 -p 50070:50070 -v /data/hadoop/master/tmp:/usr/local/hadoop/tmp -h hadoop-master --name hadoop-master spark:v0.3
-p 端口映射 本地端口:容器端口
master容器启动后直接就进入了bash交换操作,然后像一般集群那样运行start-all.sh启动hadoop和spark
六、后记 docker学习下来比传统虚拟机有很多不一样,像kvm这种虚拟机需要底层硬件支持才能发挥更好性能,可以说全面虚拟了一个服务器,包括硬件。容器就完全在软件方面做功夫,把利用LXC把资源给隔离出来,使进程跑在独立的环境上。 你要虚拟出一个Windows?docker帮不了你。 接下来会继续玩docker-compose。