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/