Docker&K8s&Hadoop
阅读:Docker相关文献
Docker及容器技术简介
Docker是一款以容器虚拟化技术为基础的软件,使用
Google公司推出的Go语言进行开发实现,基于Linux内核cgroup,
namespace,以及AUFS类的Union
FS等技术,对进程进行封装隔离。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
所谓容器技术,指的是操作系统自身支持一些接口,能够让应用程序间可以互不干扰的独立运行,并且能够对其在运行中所使用的资源进行干预。在运行效率上与真实运行在物理平台上的应用程序不相上下。
容器技术是一种全新意义上的虚拟化技术,按分类或者实现方式来说,其应该属于操作系统虚拟化的范畴,也就是在由操作系统提供虚拟化的支持。其实Docker并不做指令转换,也没有解决程序跨平台兼容的问题,但是它提供了相对独立的应用程序运行的环境,也提供了资源控制的功能。
Docker与传统虚拟化技术的差别
传统虚拟化技术的实现方式
使用虚拟机运行多个相互隔离的应用时,如下图:
基础设施(Infrastructure)。它可以是你的个人电脑,数据中心的服务器,或者是云主机。
主操作系统(Host Operating
System)。你的个人电脑之上,运行的可能是MacOS,Windows或者某个Linux发行版。
虚拟机管理系统(Hypervisor)。利用Hypervisor,可以在主操作系统之上运行多个不同的从操作系统。类型1的Hypervisor有支持MacOS的HyperKit,支持Windows的Hyper-V以及支持Linux的KVM。类型2的Hypervisor有VirtualBox和VMWare。
从操作系统(Guest Operating
System)。假设需要运行3个相互隔离的应用,则需要使用Hypervisor启动3个从操作系统,也就是3个虚拟机。这些虚拟机都非常大,也许有700MB,这就意味着它们将占用2.1GB的磁盘空间。更糟糕的是,它们还会消耗很多CPU和内存。
各种依赖。每一个从操作系统都需要安装许多依赖。如果你的的应用需要连接PostgreSQL的话,则需要安装libpq-dev;如果你使用Ruby的话,应该需要安装gems;如果使用其他编程语言,比如Python或者Node.js,都会需要安装对应的依赖库。
应用。安装依赖之后,就可以在各个从操作系统分别运行应用了,这样各个应用就是相互隔离的。
Docker的实现方式
使用Docker容器运行多个相互隔离的应用时,如下图:
不难发现,相比于虚拟机,Docker要简洁很多。因为不需要运行一个臃肿的从操作系统了。Docker使用Linux在2.4版本以后的命名空间来实现计算机资源的切割划分。
基础设施(Infrastructure)。同上。
主操作系统(Host Operating
System)。所有主流的Linux发行版都可以运行Docker。对于MacOS和Windows,也有一些办法”运行”Docker。
Docker守护进程(Docker
Daemon)。Docker守护进程取代了Hypervisor,它是运行在操作系统之上的后台进程,负责管理Docker容器。
各种依赖。对于Docker,应用的所有依赖都打包在Docker镜像中,Docker容器是基于Docker镜像创建的。
应用。应用的源代码与它的依赖都打包在Docker镜像中,不同的应用需要不同的Docker镜像。不同的应用运行在不同的Docker容器中,它们是相互隔离的。
Docker和虚拟化技术的区别
Docker 扩展了 Linux 容器(Linux Containers),或着说 LXC,通过一个高层次的 API
为进程单独提供了一个轻量级的虚拟环境。Docker 利用了 LXC, cgroups 和 Linux
自己的内核。和传统的虚拟机不同的是,一个 Docker
容器并不包含一个单独的操作系统,而是基于已有的基础设施中操作系统提供的功能来运行的。
Docker类似虚拟机的概念,但是与虚拟化技术的不同点在于下面几点:
1.虚拟化技术依赖物理CPU和内存,是硬件级别的;而Docker构建在操作系统上,利用操作系统的containerization技术,所以Docker甚至可以在虚拟机上运行。
2.虚拟化系统一般都是指操作系统镜像,比较复杂,称为“系统”;而Docker开源而且轻量,称为“容器”,单个容器适合部署少量应用,比如部署一个redis、一个memcached。
3.传统的虚拟化技术使用快照来保存状态;而Docker在保存状态上不仅更为轻便和低成本,而且引入了类似源代码管理机制,将容器的快照历史版本一一记录,切换成本很低。
4.传统的虚拟化技术在构建系统的时候较为复杂,需要大量的人力;而Docker可以通过Dockfile来构建整个容器,重启和构建速度很快。更重要的是Dockfile可以手动编写,这样应用程序开发人员可以通过发布Dockfile来指导系统环境和依赖,这样对于持续交付十分有利。
5.Dockerfile可以基于已经构建好的容器镜像,创建新容器。Dockerfile可以通过社区分享和下载,有利于该技术的推广。
Docker
会像一个可移植的容器引擎那样工作。它把应用程序及所有程序的依赖环境打包到一个虚拟容器中,这个虚拟容器可以运行在任何一种
Linux
服务器上。这大大地提高了程序运行的灵活性和可移植性,无论需不需要许可、是在公共云还是私密云、是不是裸机环境等等。
Docker也是一个云计算平台,它利用Linux的LXC、AUFU、Go语言、cgroup实现了资源的独立,可以很轻松的实现文件、资源、网络等隔离,其最终的目标是实现类似PaaS平台的应用隔离。
Docker与传统虚拟化技术的性能对比
在性能对比中,使用MySQL的吞吐量作为性能评判的依据。使用固定的机器配置运行MySQL
SysBench OLTP基准测试,并得到了以下的结果:
可以看到,Native模式无疑是性能最好的,其吞吐量随着负载的增加而增加,直到机器饱和,然后在过载时由于争用而减少一些损失。
Docker在使用不同硬盘及网络的挂载方式,其性能大致相当,且具有与本地类似的性能。而使用虚拟机,其性能就要差很多。
实践:利用DockerFile部署Hadoop集群
编写DockerFile生成Image
需要使用DockerFile,定制自己的Hadoop Image,从而达到Hadoop的快速部署。
带有注释的DockerFile如下所示:
FROM ubuntu:14.04
WORKDIR /root
# 安装openssh、jdk、wget软件
RUN apt-get update && apt-get install -y openssh-server openjdk-7-jdk wget
# 安装 hadoop 2.7.2
RUN wget
https://github.com/kiwenlau/compile-hadoop/releases/download/2.7.2/hadoop-2.7.2.tar.gz
&& \\
tar -xzvf hadoop-2.7.2.tar.gz && \\
mv hadoop-2.7.2 /usr/local/hadoop && \\
rm hadoop-2.7.2.tar.gz
# 设置环境变量
ENV JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
ENV HADOOP_HOME=/usr/local/hadoop
ENV PATH=\$PATH:/usr/local/hadoop/bin:/usr/local/hadoop/sbin
# 设置ssh免密码登录
RUN ssh-keygen -t rsa -f \~/.ssh/id_rsa -P '' && \\
cat \~/.ssh/id_rsa.pub \>\> \~/.ssh/authorized_keys
# 创建相关文件
RUN mkdir -p \~/hdfs/namenode && \\
mkdir -p \~/hdfs/datanode && \\
mkdir \$HADOOP_HOME/logs
# 拷贝配置文件到Image内
COPY config/\* /tmp/
# 在Image内将配置文件置于Hadoop文件目录下
RUN mv /tmp/ssh_config \~/.ssh/config && \\
mv /tmp/hadoop-env.sh /usr/local/hadoop/etc/hadoop/hadoop-env.sh && \\
mv /tmp/hdfs-site.xml \$HADOOP_HOME/etc/hadoop/hdfs-site.xml && \\
mv /tmp/core-site.xml \$HADOOP_HOME/etc/hadoop/core-site.xml && \\
mv /tmp/mapred-site.xml \$HADOOP_HOME/etc/hadoop/mapred-site.xml && \\
mv /tmp/yarn-site.xml \$HADOOP_HOME/etc/hadoop/yarn-site.xml && \\
mv /tmp/slaves \$HADOOP_HOME/etc/hadoop/slaves && \\
mv /tmp/start-hadoop.sh \~/start-hadoop.sh && \\
mv /tmp/run-wordcount.sh \~/run-wordcount.sh
# 给予脚本运行权限
RUN chmod +x \~/start-hadoop.sh && \\
chmod +x \~/run-wordcount.sh && \\
chmod +x \$HADOOP_HOME/sbin/start-dfs.sh && \\
chmod +x \$HADOOP_HOME/sbin/start-yarn.sh
# 初始化Hadoop Hdfs namenode
# format namenode
RUN /usr/local/hadoop/bin/hdfs namenode -format
# 容器启动时的命令
CMD [ "sh", "-c", "service ssh start; bash"]
在编写好DockerFile之后,将其置于./hadoop文件夹下,运行以下命令构建Hadoop镜像:
docker build -t hadoop:latest ./hadoop
运用生成的镜像文件,生成三个容器实例,其中一个为master,另外两个为slave。
<br></br># 创建Docker子网,方便三个容器间进行通信。
docker network create --driver=bridge hadoop
#
创建master容器,运行在hadoop子网上,并映射两个端口50070,8088两个端口到本地主机
docker run -itd --net=hadoop -p 50070:50070 -p 8088:8088 --name hadoop-master
--hostname hadoop-master hadoop:latest
# 创建两个slave容器,同样运行到hadoop子网上,slave不需要映射端口
docker run -itd --net=hadoop --name hadoop-slave1 --hostname hadoop-slave1
hadoop:latest
docker run -itd --net=hadoop --name hadoop-slave2 --hostname hadoop-slave2
hadoop:latest
# 进入master容器的bash
docker exec -it hadoop-master bash
进入master容器的bash后,运行./start-hadoop.sh,开启hadoop程序。
hadoop运行成功,在浏览器中访问localhost:8088可以看到hadoop的监控情况:
运行./run-wordcount.sh,可以运行Hadoop官方示例wordcount程序,统计词频。
输入和运行结果:
可以看到通过简单几步,就完成了三节点Hadoop环境的搭建。Docker大大简化的软件部署的流程。Docker的官方仓库也提供了大量构建好的Image,通过这些Image可以达到快速部署应用的目的。
阅读:Kubernetes相关文献
什么是KUBERNETES(k8s)
Kubernetes(简称k8s)是由Google公司团队开发的自动化容器操作的开源平台,能够实现大量容器之间的编排管理。可以将Docker看成Kubernetes内部使用的低级别组件。使用Kubernetes可以:
- 自动化容器的部署和复制
- 随时扩展或收缩容器规模
- 将容器组织成组,并且提供容器间的负载均衡
- 很容易地升级应用程序容器的新版本
- 提供容器弹性,如果容器失效就替换它,等等…
k8s集群是一组节点,这些节点可以是物理服务器或者虚拟机,之上安装了Kubernetes平台。一个典型的k8s架构图如下所示:
Pod:
Pod(上图绿色方框)安排在节点上,包含一组容器和卷。同一个Pod里的容器共享同一个网络命名空间,可以使用localhost互相通信。
Node:
节点(上图橘色方框)是物理或者虚拟机器,作为Kubernetes
worker,通常称为Minion。每个节点都运行如下Kubernetes关键组件:
- Kubelet:是主节点代理。
- Kube-proxy:Service使用其将链接路由到Pod,如上文所述。
- Docker或Rocket:Kubernetes使用的容器技术来创建容器。
Kubernetes Master:
集群拥有一个Kubernetes Master(紫色方框)。Kubernetes
Master提供集群的独特视角,并且拥有一系列组件,比如Kubernetes API Server。API
Server提供可以用来和集群交互的REST端点。
负载均衡:
k8s内置一个特殊Service,称为’LoadBalancer’,作为外部负载均衡器使用,它会自动开启,在一定数量的Pod之间均衡流量。
实践:K8S实现容器的批量编排与管理
实践目标
在本次实践中,将使用官方的 MySQL 和 WordPress
镜像,利用k8s部署一个数据库和应用分离的k8s集群服务。将使用:
- Persistent Volumes 定义持久化磁盘(磁盘生命周期不和 Pods 绑定)。
- Services 使得 Pods 能够找到其它 Pods。
- External Load Balancers 对外暴露 Services。
- Deployments 确保 Pods 持续运行。
- Secrets 保存敏感密码信息。
实践步骤
安装Minikube
由于k8s集群需要大量的机器来部署,这里使用Minikube搭建k8s服务。Minikube是k8s社区开发的单机版k8s,通过在本地计算机上创建虚拟机并部署只包含单个节点的简单集群。可以实现一种轻量级的Kubernetes集群。
下载 minikube-windows-amd64.exe 文件,并重命名为 minikube.exe。
https://github.com/kubernetes/minikube/releases/download/v0.32.0/minikube-windows-amd64
放在c盘下创建一个文件夹Kubernetes,放到Kubernetes下,同时下载kubectl。
https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/windows/amd64/kubectl.exe
kubectl即kubernetes的客户端,通过他可以进行类似docker run等容器管理操作。
下载minikube和kubectl放到PATH路径下:
打开Hyper-V管理器创建一个外部虚拟交换机
安装启动Minikube
.\minikube.exe start –registry-mirror=https://registry.docker-cn.com
–vm-driver=”hyperv” –memory=4096 –hyperv-virtual-switch=”minikubeSwitch”
在本地运行minikube dashboard 会在本地弹出浏览器,就是Kubernetes的dashboard。
使用k8s部署Wordpress和MySQL
开启minikube
创建密码
使用yaml配置文件部署MySQL和WordPress ,相关yaml文档可以查看附件。
查看部署情况:
可以看到WordPress已经成功部署。使用k8s的好处是可以动态的调节容器的数量以提高app的性能,k8s将自动进行流量的负载均衡。
参考资料
O’Gara, Maureen. Ben Golub, Who Sold Gluster to Red Hat, Now Running dotCloud.
SYS-CON Media. 26 July 2013 [2013-08-09].
Merkel, Dirk. “Docker: lightweight linux containers for consistent development
and deployment.” Linux Journal2014.239 (2014): 2.
Felter, Wes, et al. “An updated performance comparison of virtual machines and
linux containers.” Performance Analysis of Systems and Software (ISPASS), 2015
IEEE International Symposium On. IEEE, 2015.
Dua, Rajdeep, A. Reddy Raja, and Dharmesh Kakadia. “Virtualization vs
containerization to support paas.” Cloud Engineering (IC2E), 2014 IEEE
International Conference on. IEEE, 2014.
Bernstein, David. “Containers and cloud: From lxc to docker to
kubernetes.” IEEE Cloud Computing 3 (2014): 81-84.
https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/