拉开大变革序幕(中):Docker 场景化尝试

来源:互联网 发布:php招聘 编辑:程序博客网 时间:2024/04/30 12:46

runC 进行时

由Docker公司和CoreOS,加上一些顶牛的大公司,如Google,IBM,Microsoft,EMC,Amazon,思科,华为等等,在Linux基金会的支持下于2015年6月份创立的一个统一容器标准的组织。

许多厂商会在Docker和CoreOS之间犹豫不决,观望对工业界来说是个明智之举也是个掣肘之举,谁也不敢冒进。统一标准,意义重大。

OCP的一大产物就是runC,它跟docker一样也是用来大量生产和运行容器(containers)的,不过它是遵循OCP规范的,它与Docker的另一个不同在于它不需要守护进程,只需要一个配置文件一个开放的文件夹,一个进程就可以跑。不过docker镜像可以用runC来运行。
Github: https://github.com/opencontainers/runc

下面是runC官网给出的示例,我感觉要比网上其他博客和教程说得清晰:

这里写图片描述

这样这个容器就运行起来了,不过它就不需要与daemon打交道了。不过在这之前我们仍然用到了docker hub,以及docker技术这个生态圈。我想这样引入runC的愿景就是

Docker来,run Docker;其它containers来,run 其它。

当然runC仍处于研制阶段,现在还不能看出和实践出它的魅力。

所以我们队runC的态度是观望,目前还谈不上期待。


MSP 与云计算

Managed Service Provider (MSP)

管理服务(managed service)是云计算最古老的形式之一。说白了,就是我作为MSP提供商可以让企业成为我的客户,帮助企业运维应用,或者提供给企业一些保障信息安全的服务。

时至今天,回归原始,还原如火如荼的云计算的本质。

我想目前的云计算最大的受众还是企业。


HAProxy 负载均衡

“HAProxy(High Available Proxy)是基于四层和七层的高可用负载均衡代理服务器,配置简单、支持多达上万条并发请求。很多web站点都用HAProxy来作为七层负载均衡解决方案”

友情链接
keepalived + haproxy 实现web 双主模型的高可用负载均衡
Haproxy、Keepalived双主高可用负载均衡
haproxy+keepalived实现高可用负载均衡

这个是HAProxy官方给出的架构图。


这里写图片描述

下面是使用HAProxy的探索。

这里写图片描述

安装配置HAProxy:

#cd /usr/local/src#wget http://www.haproxy.org/download/1.7/src/devel/haproxy-1.7-dev0.tar.gz (截止到2015/11/5 这是最新版本)#tar xf haproxy-1.7-dev0.tar.gz#cd haproxy-1.7-dev0#make TARGET=linux26 ARCH=x86_64#TARGET是指定内核版本(我的内核是3.10,这里也选择linux26),ARCH指定CPU架构,我使用的是64bit系统#make install

创建配置文件和启动文件:

#mkdir /etc/haproxy#cp examples/haproxy.init /etc/init.d/haproxy#chmod +x /etc/init.d/haproxy#ln -s /usr/local/sbin/haproxy /usr/sbin/ (创建启动文件)#mkdir /usr/share/haproxy

编辑配置文件:

vim /etc/haproxy/haproxy.cfg

global    log 127.0.0.1   local0  #日志输出配置,所有日志都记录在本机,通过local0输出    log 127.0.0.1   local1 notice    #log loghost    local0 info    maxconn 4096                #最大连接数    chroot /usr/share/haproxy   #改变当前工作目录    uid root                  #所属用户的uid    gid root                  #所属运行的gid    daemon                  #以后台形式运行haproxy    #debug    #quietdefaults    log global    mode    http  #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK    option  httplog    option  dontlognull    option  redispatch  #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器    option  abortonclose  #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接    retries 3               #两次连接失败就认为是服务器不可用    maxconn 2000            #默认的最大连接数  #timeout http-keep-alive 10s  # timeout queue 1m    contimeout  5000        #连接超时    clitimeout  50000       #客户端超时    srvtimeout  50000       #服务器超时    timeout check 5s            #心跳检测超时    stats refresh 30s           #统计页面自动刷新时间    stats uri  /stats           #统计页面url    stats realm baison-test-Haproxy         #统计页面密码框上提示文本    stats auth admin:admin123           #统计页面用户名和密码设置    stats hide-version                  #隐藏统计页面上HAProxy的版本信息frontend www    bind *:80   #这里建议使用bind *:80的方式,要不然做集群高可用的时候有问题,vip切换到其他机器就不能访问了    acl web hdr(host) -i ip_0   #acl后面是规则名称,-i是要访问的域名,如果访问ip_0这个域名就分发到下面的webserver 的作用域。    use_backend webserver if webbackend webserver                   #webserver作用域    mode http    balance   roundrobin   #banlance roundrobin 轮询,balance source 保存session值,支持static-rr,leastconn,first,uri等参数    #option  httpchk /index.html    server     web01 ip_1:port_1  check inter 2000 fall 3 weight 30    server     web01 ip_2:port_2  check inter 2000 fall 3 weight 20    server     web01 ip_3:port_3  check inter 2000 fall 3 weight 10

最后启动服务并查看:

/usr/sbin/haproxy  -f /etc/haproxy/haproxy.cfg

浏览器访问: x1.x2.x3.x4/stats
这里写图片描述


Docker Swarm 容器集群管理

参考
http://dockerpool.com/static/books/docker_practice/swarm/usage.html

第一步,安装swarm

# docker pull swarm

验证

# docker run --rm swarm -v

出现

swarm version 0.4.0 (d647d82)

成功!

如果出现不成功,就一直重复执行命令,甚至可以reboot系统,暴力一些。如果还不行,我采取的方法是在已经有swarm镜像的机器上使用命令docker save 和 docker load对镜像进行tar打包然后传到要安装swarm的机器上进行load,在开源里混要经得住折腾啊 :)


ubuntu install docker 通过Docker源安装最新版本

# apt-get install apt-transport-https# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9# bash -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"# apt-get update# apt-get install lxc-docker

On swarm master node (123 REHL docker 1.8.2)

<REHL># vim /usr/lib/systemd/system/docker.service<Enter vim>#ExecStart=/usr/bin/docker daemon -H fd://# for swarm usingExecStart=/usr/bin/docker -d -H 0.0.0.0:2375 -H unix:///var/run/docker.sock<Exit vim># systemctl daemon-reload# service docker restart

On swarm other nodes (110 Ubuntu docker 1.7.1, 64 Ubuntu docker 1.8.1)

<Ubuntu>DOCKER_OPTS="-H 0.0.0.0:2375 -H unix:///var/run/docker.sock" (vim /etc/default/docker)# service docker restart

Notes:

1) docker -d 启动一个后台daemon进程

2) 运行Docker守护进程时,可以用-H标志调整守护进程绑定监听接口的方式。

3) 关于/var/run/docker.sock
当Docker软件包安装完毕后,默认会立即启动Docker守护进程。守护进程监听/var/run/docker.sock“这个Unix套接字文件,来获取来自客户端的Docker请求
如果出现/var/run/docker.sock的报错,解决方法是尝试用root用户身份去操作


Docker 集群管理需要使用服务发现功能。
这里我们不选择DockerHub 提供的服务发现功能(因为经过实践检验,会出现问题,在join时会出现fatal的错误导致无法使用DockerHub提供的服务发现),而是使用本地文件

第一步:
On 123(swarm manager),把集群中各个机器的ip写入到管理节点上的一个文件中,示例如下

# echo ip1:2375 >> cluster# echo ip2:2375 >> cluster# echo ip3:2375 >> cluster# cat clusterip1:2375ip2:2375ip3:2375

第二步:

# docker run -d -p 2376:2375 -v $(pwd)/cluster:/tmp/cluster swarm manage file:///tmp/cluster

出现

c36af6dd8b0279f4c5c2f49570563f2d61c1a5e23cd630e81d91b444039c9b00

docker ps后发现

CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
c36af6dd8b02 swarm “/swarm manage file:/” 37
seconds ago Up 36 seconds 0.0.0.0:2376->2375/tcp
mad_yalow

可以看到,此时整个集群已经启动成功。
接下来的就可以在任何一台安装了docker的机器上面通过命令使用集群,如在64机器上运行

# docker -H swarm_manager_ip:2376 info

就会显示集群中的机器信息。


Spark on Docker

参见 https://github.com/sequenceiq/docker-spark

只需执行

# docker pull sequenceiq/spark:1.5.1

就会得到spark on docker的image,然后运行

# docker run -it -p 8088:8088 -p 8042:8042 -h sandbox sequenceiq/spark:1.5.1 bash

就会启动容器,我们就在机器上用docker来运行spark了。

# docker run -it -p 8088:8088 -p 8042:8042 -h sandbox sequenceiq/spark:1.5.1 bash
/
Starting sshd: [ OK ]
Starting namenodes on [sandbox]
sandbox: starting namenode, logging to /usr/local/hadoop/logs/hadoop-root-namenode-sandbox.out
localhost: starting datanode, logging to /usr/local/hadoop/logs/hadoop-root-datanode-sandbox.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /usr/local/hadoop/logs/hadoop-root-secondarynamenode-sandbox.out
starting yarn daemons
starting resourcemanager, logging to /usr/local/hadoop/logs/yarn–resourcemanager-sandbox.out
localhost: starting nodemanager, logging to /usr/local/hadoop/logs/yarn-root-nodemanager-sandbox.out


Docker Hub

自己特制了一个ubuntu镜像,其中包含着jdk1.7和JMeter,用作测试,现在准备将它推送到自己的Docker Hub上:

在Docker Hub上注册自己的账户,我的username是qiushan。这里我同时创建了一个repository,叫ubuntuj。

在本地机器上,通过docker commit在本地构建了所需的镜像并命名为ubuntu/jmeter,标签为v1。

先运行docker images命令,找到镜像ubuntu/jmeter的ID为b12279f9de5a,然后运行下面命令:

docker tag b12279f9de5a qiushan/ubuntuj:v1

其实这就指定了之后我们push该镜像的目的地,因为之前我们在注册docker hub的时候已经构建了一个repository叫ubuntuj在qiushan下。

登录docker hub:

 docker login --username=qiushan --password=****** --email=xxxxxx

显示Succeed后,开始push:

docker push qiushan/ubuntuj

等待上传成功。

成功后在docker hub上就可以看到这个镜像了,之后就可以通过pull命令来随时随地下载它:

docker pull qiushan/ubuntuj

在本地我们已经build好一个镜像叫mymongodb,我们如果不想采用上述方式将镜像上传到docker hub,可以将镜像保存成tar包,存在本地或上传到github,要重新build镜像时,就把这个tar包用docker load 命令加载即可。

打成tar包:

docker save mymongodb > mymongodb.tar# 其中 mymongodb是镜像名

加载tar包生成镜像:

docker load < mymongodb.tar

Tips

获取容器的id,我们都知道docker ps后可以看到正在运行容器的container id等信息,不过还有一个容器id是出现在/var/lib/docker中,那里存在正在运行和已经exited的容器的信息,我们有时需要remove那些已经不在的容器,可那里只有这些容器的id(好长一串数字和字母),怎么来确定删除的不是正在运行的容器呢,通过下面的命令来定位:

# docker psCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                      NAMES4ee3e662bd12        mymongodb:latest    "mongod"            20 minutes ago      Up 20 minutes       0.0.0.0:32770->27017/tcp   mongo_001

这是只有一个容器在运行,

 #  docker inspect -f   '{{.Id}}' 4ee3e662bd124ee3e662bd122c7fb299ce04e98f0dc30ba03a9c4bc44d4cc54bde81c7d87c4a

运行docker inspect后,出现下面一长串,那就是这个容器的id。在/var/lib/docker目录下删除这个长串以外的就可以了。


Spark Job Server

https://github.com/spark-jobserver/spark-jobserver

从上面的github仓库下载到源码后,推荐在一台可以自由访问因特网的linux(我使用的是REHL)机器上,确保安装SBT(可以参照 Installing sbt manually),之后按照github的readme进行编译。


Swagger

API提供者想用Swagger来表述他的REST API。
宠物店


StrongLoop

创建一个 Node.js 应用程序和 MySQL 服务。

提供了更为强大的nodejs开发框架。一个公司的服务由很多Node.js的程序组成,往往需要对这些nodejs程序进行自动的部署,并能保证动态的扩容缩容,显示这些程序的各种性能参数,StrongLoop可以让集成更快速简单。


Docker Running Error Fix

  1. error: about devicemapper/data no such file:

ERRO[0000] [graphdriver] prior storage driver “devicemapper” failed:
open /var/lib/docker/devicemapper/devicemapper/data: no such file or
directory
FATA[0000] Error starting daemon: error initializing graphdriver: open /var/lib/docker/devicemapper/devicemapper/data: no such file or directory

fix:

Cleaning up Device Mappings after Docker Daemon Death


Nginx with Docker

在调试过程中会产生许多废弃的container,我们需要对其进行清理,可以通过脚本省去一些精力:
直接在命令行上编写脚本并运行:

# for k in $(seq 1 9); do docker rm ngtest0${k}; done

这样会比写一个脚本文件更灵活和快捷。作为一名合格的系统程序员要懂得让自己与系统打交道变得越来越聪明才行。


使用的基本镜像是suse12,基于非x86平台,先在本地机器上编译好nginx的源文件,将编译好后的nginx运行文件COPY到docker container中,注意环境变量的设置,可以先似的docker run bash进入bash环境,查看环境变量的设置情况。
最后发现nginx的container无法运行,而是Exi(0),需要对nginx设置 daemon off,在container中运行的程序要是foreground才行,nginx默认是background。

Dockerfile

FROM qiushan/zsles12:latestMAINTAINER IBMRUN mkdir -p /usr/local/nginxRUN mkdir -p /tmpCOPY  ./nginx/ /usr/local/nginx/COPY ./myconfig.conf /tmp/COPY ./index.html /tmp/WORKDIR /usr/local/nginxENV PATH "/usr/local/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"EXPOSE 8080CMD ["./start.sh"]

start.sh

#!/bin/bashnginx -g 'daemon off;'

在调试过程中出了生成许多废弃的container,还会生成许多none的image,如何做到快速清理呢:

docker rmi $(docker images | grep "^<none>" | awk "{print $3}")

如果确定不需要任何container,可以运行下面的命令来删除清空存在的或已经退出的container:

docker rm `docker ps -a -q `

创建镜像

docker build -t="znginx" .

运行镜像

docker run -d -p 8080:8080 --name znginxtest znginx

访问目的ip的8080端口,会看到如下:

这里写图片描述


Node with Docker

在写Dockerfile时,要注意用ENV来设置node的环境变量,而不要用

RUN export PATH=...

另外,

docker run -it -p port1:port2 --name test testimage bash

是调试创建image的有效方法。


Mongodb Shard Cluster

引入Shard,减少mongodb端的性能瓶颈。
片键的选择是需要注意的。

Hashed keys work well with fields that increase monotonically like
ObjectId values or timestamps

shard集群只有在数据库数据成一定规模时才能发挥作用,而且一般体现在多台物理机组成的集群,而不是一台机器的模拟。


cAdvisor 容器监控

之前用过监控宝,感觉不是很习惯,要注册账户,信息的显示也是通过登录到监控宝网站上查看,由于当时它支持的平台和OS有限,并不易用。
推荐cAdvisor来进行容器docker监控,一是因为它是开源的,不像其他需要到网站注册账户,再一个入门简单。如果考虑多节点,可以看看Kubernetes的heapster。


Mesos 集群资源管理与调度

下图是Mesos的架构图,出自论文 Mesos: A Platform for Fine-Grained Resource Sharing in the Data Center
这里写图片描述

上图展示了Mesos的两级调度机制。Mesos master会根据resource offers机制将slave机器上的资源支配给各个framework的sheduler。
首先slave机器会将自身可用资源(包括CPU、memory)报告给master,这样master就会知道现在cluster中有多少资源可用,之后master会告诉framework可以分配多少资源给它跑任务,framework根据信息决定run两个任务(当然也可以reject,拒接这些资源的邀约),于是向master提出两个任务的申请,master根据每个任务所耗的资源分配到slave上的framework的executor去执行task。

在集群上按照尽量少迁移数据,在数据所存储的节点上进行计算任务的原则进行资源分配和调度,这就需要一个细粒度的调度模型。

以下英文信息引用来自 Return of the Borg: How Twitter Rebuilt Google’s Secret Weapon,建议大家先读读,而不是一上去就去读Mesos的源码或论文。

Hindman says. “So we built a system that would only give an
application access to a certain number of cores, and give others to
another application. And those allocations might change over time.”

Just as Hindman had worked to run many applications on a multi-core processor, they could build a platform that could run many distributed systems across a single server cluster.

这里写图片描述

Google and Twitter treat the data center like one big computer, and eventually, that’s where the world will end up. This is the way computer science always progresses. We start with an interface that’s complicated and we move to one that’s not. It happens on desktops and laptops and servers. And now, it’s happening with data centers too.


Mesos由10000行C++构成,最大可支持50000个节点,通过Zookeeper实现fault tolerance。

Mesos实现的是 efficient fine-grained sharing across diverse cluster computing frameworks.

giving frameworks control over their scheduling 将调度权交给framework自己管理。

resource offers 是Mesos的分布式调度的机制,可以让framework选择所需的资源。

当时Mesos的作者在其上部署了Hadoop、MPI、the Torque batch scheduler、Spark 以及 an elastic Apache web server farm framework。

Mesos的设计哲学是 o define a minimal interface that enables
efficient resource sharing, and otherwise push control to the frameworks.

Mesos采用的资源分配有两个:

  • fair sharing based on max-min fairness;
  • strict priorities

在同一台slave上各个framework的executor,Mesos都做到了资源隔离。考虑到使用系统OS本身的隔离机制,是平台依赖的,Mesos也把resource isolation module做成了pluggable,所涉及的OS容器隔离有Linux Containers,Solaris Projects等。

在Mesos中,任务的调度是在分布式环境中,需要保证高效和健壮。

如果framework在一定时间内没有对mesos给予的资源邀约进行响应,mesos就会收回邀约转向其他的framework。


Summary

以上就是我们对docker所做的工作,出于公司保密原则,很抱歉我不能公开具体聚合成什么,不过大家可以自己设想到docker的应用场景,并自己去实现。

这里写图片描述

19 1
原创粉丝点击