文档章节

利用 supervisor 和 icegrid构建可进行远程管理的 ICE 服务框架容器

e
 eyiyluo
发布于 2016/09/12 00:06
字数 5959
阅读 68
收藏 1

#一 目的

构建可以运行 icegrid 的环境,实现既能对容器进行远程管理,又能使用 ice 框架的服务注册以及管理功能。

#二 标准运行容器的镜像

docker就不用介绍了。但有一个地方是需要特别提出来的,就是一个容器在启动的时候只能跑一个命令,而且系统中那些已经做了开机自动启动的服务也不会被拉起来。所以先试着构建一个标准容器,让这个容器在启动的时候能被远程管理,而且还能添加其他服务在开机的时候自动启动。

supervisor 就是一个非常好的服务管理器。那么在构建标准容器的时候要做的就是把 supervisor 和 ssh 装上,配好。

构建标准容器

直接上 Dockerfile。


############################################

# version : basic/ubuntu:14.04

# desc : 当前版本安装的ssh,wget,curl,supervisor

############################################

# 设置继承自灵雀云ubuntu官方镜像

FROM index.alauda.cn/library/ubuntu:latest



# 下面是一些创建者的基本信息

MAINTAINER eyiyluo



###############   Dockerfile变量    ###################



# 设置root口令

ENV ROOT_PWD root



# 注意这里要更改系统的时区设置,因为在 web 应用中经常会用到时区这个系统变量,默认的 ubuntu 会让你的应用程序发生不可思议的效果哦

ENV DEBIAN_FRONTEND noninteractive

########################################################

###############   操作系统级别的设置    ###################

#修改 root 口令

RUN echo "root:"${ROOT_PWD} | chpasswd



# 添加测试用户admin,密码admin,并且将此用户添加到sudoers里

RUN useradd admin && \

    echo "admin:admin" | chpasswd && \

	echo "admin   ALL=(ALL)       ALL" >> /etc/sudoers



# 把admin用户的shell改成bash,否则SSH登录Ubuntu服务器,命令行不显示用户名和目录 

RUN usermod -s /bin/bash admin



# 设置全局别名

RUN echo "# some more ls aliases" >> /etc/profile && \

	echo "alias ll='ls -alF'" >> /etc/profile && \

	echo "alias la='ls -A'" >> /etc/profile && \

	echo "alias l='ls -CF'" >> /etc/profile



# 设置时区

RUN cp /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

########################################################



###############   安装软件包前的准备    ###################



#添加 ICE 相关源并更新

RUN apt-get update



########################################################

###############   安装软件包         ##################

RUN apt-get install -y vim wget curl openssh-server supervisor 

########################################################



###############   软件包配置     ##################

##### 对 ssh 进行相关设置

RUN mkdir -p /var/run/sshd



# 将sshd的UsePAM参数设置为失效

RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config

#################################################



########### 对 supervisor 进行相关设置 ############

# 创建supervisor以及所管理的服务相关目录

RUN mkdir -p /var/log/supervisor \

	&& mkdir -p /var/log/supervisor/sshd \



# 添加 supervisord自身的的配置文件(supervisord.conf文件和Dockerfile文件在同一路径)

COPY supervisord.conf /etc/supervisor/supervisord.conf



# 添加 supervisor 所管理的服务相应的配置文件

COPY sup_sshd.conf /etc/supervisor/conf.d/sup_sshd.conf

#################################################



##################     清理     ################## 

RUN rm -rf /var/lib/apt/lists/*

#################################################



# 容器需要开放的端口

EXPOSE 22

EXPOSE 9001



# 执行supervisord来同时执行多个命令,使用 supervisord 的可执行路径启动服务。

CMD ["/usr/bin/supervisord"]

我觉得写 Dockerfile 和做系统一样也是要有框架的,这个 Dockerfile 就是按照:

“Dockerfile变量设置” -> “容器操作系统级别的设置” -> “安装软件包前的准备” -> “安装软件包” -> “软件包配置” -> “服务管理程序相关设置” -> “其他服务相关设置”->“清理” -> “开放端口” -> “启动命令”

这几个大步骤进行。在标准容器基础上增加其他服务的话只要在相关步骤做相应的增加就可以了

相关配置

容器构建好了,但要能达到开机启动所需服务还少不了对 supervisor 的配置。Dockerfile 中有下面两个地方是将事先写好的配置文件在构建时就 copy 到容器中的。我们将对这2个配置文件中最重要的部分做解释。


# 添加 supervisord自身的的配置文件(supervisord.conf文件和Dockerfile文件在同一路径)

COPY supervisord.conf /etc/supervisor/supervisord.conf



# 添加 supervisor 所管理的服务相应的配置文件

COPY sup_sshd.conf /etc/supervisor/conf.d/sup_sshd.conf

supervisord.conf 配置文件说明

先上配置原文


; supervisor config file

[unix_http_server]

file=/var/run/supervisor.sock   ; (the path to the socket file)

chmod=0700                       ; sockef file mode (default 0700)



[supervisord]

nodaemon=true

logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)

logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)

logfile_backups=10           ; (num of main logfile rotation backups;default 10)

loglevel=debug                ; (log level;default info; others: debug,warn,trace)

pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)

childlogdir=/var/log/supervisor            ; ('AUTO' child log dir, default $TEMP)

supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface



[supervisorctl]

serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket



; The [include] section can just contain the "files" setting.  This

; setting can list multiple files (separated by whitespace or

; newlines).  It can also contain wildcards.  The filenames are

; interpreted as relative to this file.  Included files *cannot*

; include files themselves.





[inet_http_server]         ; inet (TCP) server disabled by default

port=*:9001     		   ; (ip_address:port specifier, *:port for all iface)

username=user              ; (default is no username (open server))

password=123               ; (default is no password (open server))



[include]

files = /etc/supervisor/conf.d/*.conf

运行方式及路径相关


……

[supervisord]

nodaemon=true

logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)

……

  1. 一定要将 nodaemon 的值设置为 true,否则supervisor起不来。

  2. 日志路径是与 Dockerfile 中 “RUN mkdir -p /var/log/supervisor” 的路径一致。

web 管理界面相关


……

[inet_http_server]         ; inet (TCP) server disabled by default

port=*:9001     		   ; (ip_address:port specifier, *:port for all iface)

username=user              ; (default is no username (open server))

password=123               ; (default is no password (open server))

……

  1. “port=*:9001 ” 意味着通过容器的9001端口可以进行webUI访问,这个端口要与 Dockerfile 的“EXPOSE 9001”语句相对应。

  2. 用户名/口令不用说了,就是登录 webUI 时所需的账号和密码了

扩展配置文件相关


……

[include]

files = /etc/supervisor/conf.d/*.conf

……

这句意味着 supervisor 在启动的时候将把“ /etc/supervisor/conf.d/ ” 下,扩展名为 conf 的配置文件一起加载。通常将所需要管理的服务(如 SSH )的启动配置放在这个目录下。

sup_sshd.conf

在上配置原文及注解


[program:sshd]

command=/usr/sbin/sshd -D    ;启动 SSH 服务的命令,-D 是以 daemon 方式运行。不带这个参数也行。但有的服务就一定不能以 daemon 运行,比如 icegridregistry,这个坑后面会讲到。

priority=1    ;这个服务的优先级,数字小的启动晚,停止早。默认是999. 我是把 ssh 的优先级设为1,若有其他的则取默认值。

autostart=true    ;自动启动,也就是 supervisor 启动后就把这个服务拉起来。

autorestart=true    ;自动重启,如果手贱 kill 掉这个服务的进程,supervisor 会自动又把它拉起来。

stdout_logfile=/var/log/supervisor/sshd/stdout.log    ;标准输出日志文件,supervisor 接管这个服务后产生的output日志记录到这里。

stderr_logfile=/var/log/supervisor/sshd/stderr.log    ;错误日志文件,supervisor 接管这个服务后产生的output日志记录到这里。

至此,一个基于 Ubuntu14.04的标准容器就构建并配置完了。它可以实现容器一启动就运行 SSH,允许用 admin 用户远程登录。并为以后增加其他随机启动服务留下足够的空间。

How to run


docker run -p <hostport-1 for ssh>:22 -p <hostport-2 for webUI>:9001 -d <image id>

这已经是最基本的启动命令了,把 Dockerfile 中 expose 的端口映射到 host 的端口即可。至于--name,--hostname,-v 这些参数就根据个人情况而自己加了。

#三 构建包含icegrid相关服务的镜像

构成 icegrid 框架包含的元素有以下关系和约定:

  1. 服务注册器(icegridregistry)--框架的核心节点,可以部署为1主多从或1主0从。它会将域中的从注册服务,节点以及服务管理起来。一个注册器是主还是从由启动时加载的配置文件决定。

  2. 服务运行节点(icegridnode)--服务运行的节点,真正对外提供的服务都在 node 上运行,node 受icegridregistry管理。

  3. 服务(server)--服务,也就是业务逻辑代码或编译后可运行的程序。它一定要存在于 node 中,server 需要在运行前在icegridregistry中注册。

  4. 管理工具(iceadmin)--管理所有节点和实际业务服务的工具,一个是 GUI 的一个是 CLI 的

构建用于注册服务的镜像

一开始我是打算把 master icegridregistry/slave icegridregistry/icegridnode 分别做成单独的镜像的,后来考虑到icegridregistry是主还是从取决于加载什么配置文件,且启动命令都一样,只要改变配置文件的内容就能实现让他是主就是主,让他是从就是从。所以最后决定只做一个icegridregistry的镜像,且容器运行时从同一个配置文件读取配置。只要做两件事情:

  1. 构建镜像的时候copy supervisor 的扩展配置文件(如: sup_icgridregistry.conf)到容器中,该文件把启动命令和 icegridregistry配置文件写死。

  2. docker run 把容器拉起来的时候用 “-v <本地配置文件>:<容器中supervisor 的扩展配置文件(如:sup_icgridregistry.conf)>” 关联起来。

另外,服务管理工具(icegridadmin)也放在icegridregistry中,而且进行注册时有另外的配置。因此有必要用独立的配置目录存放相关配置文件。

Dockerfile 及说明


############################################

# version : basic/ubuntu:14.04

# desc : 当前版本安装的ssh,wget,curl,supervisor

#        ICE GRID 服务运行环境

############################################

# 设置继承自灵雀云ubuntu官方镜像

FROM index.alauda.cn/library/ubuntu:latest



# 下面是一些创建者的基本信息

MAINTAINER eyiyluo



###############   Dockerfile变量    ###################



# 设置root口令

ENV ROOT_PWD root



# 注意这里要更改系统的时区设置,因为在 web 应用中经常会用到时区这个系统变量,默认的 ubuntu 会让你的应用程序发生不可思议的效果哦

ENV DEBIAN_FRONTEND noninteractive

########################################################



###############   操作系统级别的设置    ###################

#修改 root 口令

RUN echo "root:"${ROOT_PWD} | chpasswd



# 添加测试用户admin,密码admin,并且将此用户添加到sudoers里

RUN useradd admin && \

    echo "admin:admin" | chpasswd && \

	echo "admin   ALL=(ALL)       ALL" >> /etc/sudoers



# 把admin用户的shell改成bash,否则SSH登录Ubuntu服务器,命令行不显示用户名和目录 

RUN usermod -s /bin/bash admin



# 设置全局别名

RUN echo "# some more ls aliases" >> /etc/profile && \

	echo "alias ll='ls -alF'" >> /etc/profile && \

	echo "alias la='ls -A'" >> /etc/profile && \

	echo "alias l='ls -CF'" >> /etc/profile



# 设置时区

RUN cp /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

########################################################



###############   安装软件包前的准备    ###################

#添加 ICE 相关源并更新

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv 5E6DA83306132997 \

    && echo "deb http://zeroc.com/download/apt/ubuntu14.04 stable main" >> /etc/apt/sources.list.d/ice.list \

	&& apt-get update



########################################################

###############   安装软件包         ##################



RUN apt-get install -y vim wget curl openssh-server supervisor \

	&& apt-get install --no-install-recommends --no-install-suggests -y zeroc-icegrid



########################################################



###############   软件包配置     ##################



##### 对 ssh 进行相关设置

RUN mkdir -p /var/run/sshd



# 将sshd的UsePAM参数设置为失效

RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config

#################################################



########### 对 supervisor 进行相关设置 ############

# 创建supervisor以及所管理的服务相关目录

RUN mkdir -p /var/log/supervisor \

	&& mkdir -p /var/log/supervisor/sshd \

	&& mkdir -p /var/log/supervisor/icegridregistryd



# 添加 supervisord自身的的配置文件(supervisord.conf文件和Dockerfile文件在同一路径)

COPY supervisord.conf /etc/supervisor/supervisord.conf



# 添加 supervisor 所管理的服务相应的配置文件

COPY sup_sshd.conf /etc/supervisor/conf.d/sup_sshd.conf

COPY sup_icegridregistryd.conf /etc/supervisor/conf.d/sup_icegridregistryd.conf



#################################################



############ 配置 ice 下业务服务相关参数 ############

# 创建存放业务服务配置文件的目录,容器启动时用 -v 将 host 存放这些具体服务配置文件的目录与之绑定

RUN mkdir -p /var/lib/services.conf



# 创建registry和 server 所需要的数据和日志目录,载入 icegrid 管理工具 CLI

COPY icegridadmin /usr/bin/icegridadmin

RUN mkdir -p /var/lib/ice/icegrid \

	&& mkdir -p /var/log/ice/icegrid \

	&& chmod +x /usr/bin/icegridadmin \

	&& mkdir -p /var/log/ice/icegridnode

#################################################



##################     清理     ################## 

RUN rm -rf /var/lib/apt/lists/*

#################################################



# 容器需要开放的端口

EXPOSE 22

EXPOSE 9001

EXPOSE 4061 4062



# 执行supervisord来同时执行多个命令,使用 supervisord 的可执行路径启动服务。

CMD ["/usr/bin/supervisord"]

与标准Dockerfile 差异说明

APT 源


RUN apt-key adv --keyserver keyserver.ubuntu.com --recv 5E6DA83306132997 \

    && echo "deb http://zeroc.com/download/apt/ubuntu14.04 stable main" >> /etc/apt/sources.list.d/ice.list

这里增加了 ICE 源的 APT-KEY,并将源地址写入扩展 source list

ICE 安装


RUN apt-get install -y vim wget curl openssh-server supervisor \

  && apt-get install --no-install-recommends --no-install-suggests -y zeroc-icegrid

用 apt-get 方式安装,在原来的基础上增加安装 zeroc-icegrid。

官方文档用的是


apt-get install --no-install-recommends --no-install-suggests -y zeroc-icegrid=3.6.2

但真机操作上出错,以后再研究了。

supervisor 管理 icegridregistry 时所需的相关目录


RUN mkdir -p /var/log/supervisor \

  && mkdir -p /var/log/supervisor/sshd \

  && mkdir -p /var/log/supervisor/icegridregistryd

很简单,和 sshd 相似的。

**导入supervisor 启动 icegridregistry 的配置文件


COPY sup_icegridregistryd.conf /etc/supervisor/conf.d/sup_icegridregistryd.conf

该文件是事先编辑好的,放在 Dockerfile 同一路径下。构建镜像时从 host copy 到supervisor 可搜索的配置文件目录即可,和 sshd 的启动配置在同一目录。

服务注册管理工具


COPY icegridadmin /usr/bin/icegridadmin

RUN chmod +x /usr/bin/icegridadmin \

  && mkdir -p /var/log/ice/icegridnode

官网 apt 包里并没有包括 cli 集群管理工具,所以我在构建时从 host copy 到镜像里并增加可执行权限。至于新建的目录,你懂的啦,log 嘛。

新增开放的端口


EXPOSE 4061 4062

icegridregistry 各类节点通信的端口,可以在其配置文件里修改。我用的是默认端口。

icegridregistry 相关的配置文件

有2个配置文件是需要特别注意的,一个是 build 的时候就写到镜像中的启动配置,这个是给 supervisor 把 icegridregistry 拉起来用的。另一个是 icegridregistry 启动时加载所用的。

supervisor 管理 icegridregistry 的配置文件

Dockerfile 中有这么一句


COPY sup_icegridregistryd.conf /etc/supervisor/conf.d/sup_icegridregistryd.conf

就是将事先编辑好的sup_icegridregistryd.conf写到镜像中,让 supervisor 知道如何启动 icegridregistry。


[program:icegridregistry]

command=icegridregistry --Ice.Config=/etc/icegridregistry.conf

autostart=true

autorestart=true

stdout_logfile=/var/log/supervisor/icegridregistryd/stdout.log

stderr_logfile=/var/log/supervisor/icegridregistryd/stderr.log

就这几行,其中后4行和 sshd 的配置文件很相似,就不赘述了。第一句是把 icegridregistry 拉起来的命令,这有个坑。一开始我认为应该和 sshd 一样,要以 daemon 方式启动,就用了“ command=icegridregistry --Ice.Config=/etc/icegridregistry.conf --daemon ”这个命令,但在 supervisor 中显示 icegridregistry 是脱管的状态,而 ps -ef | grep ice 却又发现已经有这个进程,且 icegridadmin 管理工具能连上该服务。stderr.log 显示如下错误


root@master-registry:~# cat /var/lib/ice/icegrid/stderr.log 

!! 09/08/16 09:10:25.470 icegridregistry: error: service caught unhandled std::exception:

   FileUtil.cpp:512: IceUtil::FileLockedException:

   could not lock file: `/var/lib/ice/icegrid/__Freeze/lock'

   syscall exception: Resource temporarily unavailable

!! 09/08/16 09:10:27.728 icegridregistry: error: service caught unhandled std::exception:

   FileUtil.cpp:512: IceUtil::FileLockedException:

   could not lock file: `/var/lib/ice/icegrid/__Freeze/lock'

   syscall exception: Resource temporarily unavailable

!! 09/08/16 09:10:30.942 icegridregistry: error: service caught unhandled std::exception:

   FileUtil.cpp:512: IceUtil::FileLockedException:

   could not lock file: `/var/lib/ice/icegrid/__Freeze/lock'

   syscall exception: Resource temporarily unavailable

意思是不能锁住 lock 文件。从现象上可以得出结论:1. 服务已经被拉起来;2. 脱离了 supervisor 的管理。

后来我尝试着直接输入命令的方式启动,并没有任何的错误。打开/var/lib/ice/icegrid/__Freeze/lock 文件看到,里面只记录了一个正整数。目测应该是进程号,通过反复几次操作证实了我的猜测。那么问题来了,为什么用 shell 输命令可以无误的锁这个文件而用 supervisor 拉的时候确锁不住了呢?我猜测是带--daemon 参数时,守护进程要明确的知道需要服务进程的 PID,以便在被 kill 掉以后再次把服务拉起来。如果是在 shell 中启动,就是服务进程被守护进程所看管,因此lock 文件可以被锁。而用 supervisor 拉icegridregistry 服务起来的时候,它也要知道 PID 是什么,icegridregistry的 daemon 也要知道 PID 是什么,大家都要控制 lock 文件。这就造成了竞争,最终结果就是 supervisor 抢不过原生 daemon。当然就失去了对icegridregistry的管理。另外一篇文章佐证了我的猜测(原文见:http://m.blog.chinaunix.net/uid-26000296-id-4759916.html):

输入图片说明

既然这样,把--daemon 去掉就好了,事实果然如此。但为何 sshd 用了-D 参数一样可以被 supervisor 监管呢?我没有深入研究,可能和ssh 的配置文件有关。

icegridregistry 服务自身的配置文件

icegridregistry 启动时根据配置文件来确定自己是 master 身份还是 slave 身份作为注册集群的成员(至于启动后 master 宕机了选谁做下一任 master 就是它自己工作机制的问题了)。配置文件具体的配置解释可以参考这份文档(http://blog.csdn.net/educast/article/details/9414789)。我们分别介绍下 master 配置和 slave 配置。这两个配置文件在 run 容器时临时载入。

icegridregistry-master.conf配置文件说明


# def IceGrid instance name

IceGrid.InstanceName=IceGrid



# listener 

Ice.Default.Locator=IceGrid/Locator:default -p 4061



# IceGrid

IceGrid.Registry.Client.Endpoints=default -t 5000 -p 4061

IceGrid.Registry.Server.Endpoints=default -t 5000

IceGrid.Registry.Internal.Endpoints=default -t 5000



# data path

IceGrid.Registry.Data=/var/lib/ice/icegrid



# cert information

IceGrid.Registry.PermissionsVerifier=IceGrid/NullPermissionsVerifier

IceGrid.Registry.AdminPermissionsVerifier=IceGrid/NullPermissionsVerifier

IceGrid.Registry.SSLPermissionsVerifier=IceGrid/NullSSLPermissionsVerifier

IceGrid.Registry.AdminSSLPermissionsVerifier=IceGrid/NullSSLPermissionsVerifier



# password

IceGridAdmin.Username=admin

IceGridAdmin.Password=admin



#Ice Error and Standard output Set

#

Ice.StdErr=/var/log/ice/icegrid/stderr.log                 

Ice.StdOut=/var/log/ice/icegrid/stdout.log   

这个配置没啥好说的,看属性配置详解就可以了。只是有一点,master 配置中# listener 选项并没有带-h 参数指定监听的 IP 地址。因为容器启动时是通过 DHCP 获取动态 IP 的,不指定的话就可以在所有地址上监听。

icegridregistry-slave.conf配置文件说明


#

# IceGrid slave registry configuration

#



# Instance name

IceGrid.InstanceName=IceGrid



# Master registry connection configuration

Ice.Default.Locator=IceGrid/Locator:default -h 172.16.10.100 -p 24061



# Instance configuration

IceGrid.Registry.ReplicaName=Slave1

IceGrid.Registry.Client.Endpoints=default -t 5000 -p 4061

IceGrid.Registry.Server.Endpoints=default -t 5000 

IceGrid.Registry.Internal.Endpoints=default -t 5000

IceGrid.Registry.Data=/var/lib/ice/icegrid



# Auth configuration

IceGrid.Registry.PermissionsVerifier=IceGrid/NullPermissionsVerifier

IceGrid.Registry.AdminPermissionsVerifier=IceGrid/NullPermissionsVerifier

IceGrid.Registry.AdminSSLPermissionsVerifier=IceGrid/NullSSLPermissionsVerifier



#Ice Error and Standard output Set

#

Ice.StdErr=/var/log/ice/icegrid/stderr.log                 

Ice.StdOut=/var/log/ice/icegrid/stdout.log  

这一段配置“Ice.Default.Locator=IceGrid/Locator:default -h 172.16.10.100 -p 24061”中,必须指定 master 监听的 ip 和端口号。我这里没有跑集群,所以ip 就是 master registry 这个容器所在的 host 的 ip,端口号是该 host 映射后的端口号。具体是什么就得看run master 容器时的启动参数了。

How to run

master 注册器


docker run -p <hostport-1 for ssh>:22 -p <hostport-2 for supervisor webUI>:9001 -p <hostport-3 for icegridregistry listener>:4061 \

-v <master-Icegridregistry configuration file>:/etc/icegridregistry.conf \

--name <your contain name> --hostname <contain hostname> -d <image id>

slave 注册器


docker run -p <hostport-1 for ssh>:22 -p <hostport-2 for supervisor webUI>:9001 -p <hostport-3 for icegridregistry listener>:4061 \

-v <slave-Icegridregistry configuration file>:/etc/icegridregistry.conf \

--name <your contain name> --hostname <contain hostname> -d <image id>

构建用于运行业务的 ICE 节点的镜像

有了前两种镜像的构建经验,icegrid运行节点--icegridnode 的镜像也就没什么难度了。废话少说,直接上 file


############################################

# version : basic/ubuntu:14.04

# desc : 当前版本安装的ssh,wget,curl,supervisor

#        ICE GRID NODE运行环境

############################################

# 设置继承自灵雀云ubuntu官方镜像

FROM index.alauda.cn/library/ubuntu:latest



# 下面是一些创建者的基本信息

MAINTAINER eyiyluo



###############   Dockerfile变量    ###################



# 设置root口令

ENV ROOT_PWD root



# 注意这里要更改系统的时区设置,因为在 web 应用中经常会用到时区这个系统变量,默认的 ubuntu 会让你的应用程序发生不可思议的效果哦

ENV DEBIAN_FRONTEND noninteractive

########################################################



###############   操作系统级别的设置    ###################

#修改 root 口令

RUN echo "root:"${ROOT_PWD} | chpasswd



# 添加测试用户admin,密码admin,并且将此用户添加到sudoers里



RUN useradd admin && \

    echo "admin:admin" | chpasswd && \

	echo "admin   ALL=(ALL)       ALL" >> /etc/sudoers



# 把admin用户的shell改成bash,否则SSH登录Ubuntu服务器,命令行不显示用户名和目录 

RUN usermod -s /bin/bash admin



# 设置全局别名



RUN echo "# some more ls aliases" >> /etc/profile && \

	echo "alias ll='ls -alF'" >> /etc/profile && \

	echo "alias la='ls -A'" >> /etc/profile && \

	echo "alias l='ls -CF'" >> /etc/profile



# 设置时区

RUN cp /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

########################################################



###############   安装软件包前的准备    ###################

#添加 ICE 相关源并更新

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv 5E6DA83306132997 \

    && echo "deb http://zeroc.com/download/apt/ubuntu14.04 stable main" >> /etc/apt/sources.list.d/ice.list \

	&& apt-get update

########################################################



###############   安装软件包         ##################

RUN apt-get install -y vim wget curl openssh-server supervisor \

	&& apt-get install --no-install-recommends --no-install-suggests -y zeroc-icegrid

########################################################



###############   软件包配置         ##################



##### 对 ssh 进行相关设置

RUN mkdir -p /var/run/sshd



# 将sshd的UsePAM参数设置为失效

RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config



##### 对 icegridnode 进行相关设置

# 创建数据和日志目录

RUN mkdir -p /var/lib/ice/icegrid \

	&& mkdir -p /var/log/ice/icegrid



##### 对 supervisor 进行相关设置 ####################

# 创建supervisor以及所管理的服务相关目录

RUN mkdir -p /var/log/supervisor \

	&& mkdir -p /var/log/supervisor/sshd \

	&& mkdir -p /var/log/supervisor/icegridnode



# 添加 supervisord自身的的配置文件(supervisord.conf文件和Dockerfile文件在同一路径)

COPY supervisord.conf /etc/supervisor/supervisord.conf



# 添加 supervisor 所管理的服务相应的配置文件

COPY sup_sshd.conf /etc/supervisor/conf.d/sup_sshd.conf

COPY sup_icegridnoded.conf /etc/supervisor/conf.d/sup_icegridnoded.conf

#################################################





##### ICE 下管理的具体业务服务基础配置 ################

# 安装 JAVA

COPY jdk1.7.0_65 /var/lib/jdk1.7.0_65



# 生成服务程序的存放路径, 该路径在启动容器时与host上存放业务代码的路径进行绑定

# 若有必要,也可在 build 的时候就讲业务服务代码 copy 进来

# 生成节点路径

RUN mkdir -p /var/lib/services \

	&& mkdir -p /var/lib/ice/icegrid/node

#################################################



##################     清理     ################## 

RUN rm -rf /var/lib/apt/lists/*

#################################################



# 容器需要开放的端口

EXPOSE 22

EXPOSE 9001

EXPOSE 4061 4062



# 执行supervisord来同时执行多个命令,使用 supervisord 的可执行路径启动服务。

CMD ["/usr/bin/supervisord"]

###Dockerfile说明

最大的不同就是在构建镜像时直接把 java 1.7 copy 进去了,容器内需要用 java 时指定路径就好。目的就是做一个绿色的 JAVA,省去各种 JAVA_HOME 等环境变量的设置。只要把解压后的 jdk 目录和 Dockerfile 放在同一个目录就可以了。


# 安装 JAVA

COPY jdk1.7.0_65 /var/lib/jdk1.7.0_65

icegridnode 相关配置文件

supervisor 启动 icegridnode 的配置文件


[program:icegridnoded]

command=icegridnode --Ice.Config=/etc/icegridnode.conf

autostart=true

autorestart=true

stdout_logfile=/var/log/supervisor/icegridnode/stdout.log

stderr_logfile=/var/log/supervisor/icegridnode/stderr.log

没啥特别的,就是指定用 icegridnode 命令启动,启动时使用/etc/icegridnode.conf这个配置文件。在后面讲到how to 启动容器时会看到其实是要把事先在 host 上编辑好的配置文件映射到启动容器中。

icegridnode自身启动的配置文件


#

# IceGrid configuration 

#

# Registry connection

Ice.Default.Locator=IceGrid/Locator:default -h 192.168.0.129 -p 24061



# node

IceGrid.Node.Name=node1

IceGrid.Node.Endpoints=default

IceGrid.Node.Data=/var/lib/ice/icegrid/node

IceGrid.Node.Trace.Activator=1



#Ice Error and Standard output Set

Ice.StdErr=/var/log/ice/icegrid/stderr.log                 

Ice.StdOut=/var/log/ice/icegrid/stdout.log

  • 注册服务的连接参数

Ice.Default.Locator=IceGrid/Locator:default -h 192.168.0.129 -p 24061

这是 node 连接注册服务必须用到的配置,本例中用-h 192.168.0.129 -p 24061声明要连接192.168.0.129 的 24061端口用于注册节点。

*其他路径相关配置


IceGrid.Node.Data=/var/lib/ice/icegrid/node

Ice.StdErr=/var/log/ice/icegrid/stderr.log                 

Ice.StdOut=/var/log/ice/icegrid/stdout.log

这3个配置是为了存放节点数据和日志的,在 Dockerfile 中务必确认已经创建了这些目录,否则节点启动失败。

How to run


docker run -p <hostport-1 for ssh>:22 -p <hostport-2 for supervisor webUI>:9001 -p <hostport-3 for icegridnode connection>:4061 \

-v <local Icegridnode config file>:/etc/icegridnode.conf \

--name <your contain name> --hostname <contain hostname> -d <image id>

这就没啥好说的了,docker run 都不清楚的话只有先脑补 docker 基础了。

四 后记

我的最终目的是希望能通过最简单的方式实现 master icegridregistry/salve icegridregistry/icegridnode 这3种类型节点的启动和扩容。docker 1.12出来后自带了 swarm 这个工具并做了简单的研究,设想了2个解决方案:

  1. 1个master icegridregistry集群,里面只包含1个master icegridregistry服务。1个集群用于salve icegridregistry,里面包含多个salve icegridregistry服务,配置中的 master icegridregistry 指向集群地址和端口。1个或多个(根据实际业务需要)icegridnode集群,配置中的 registry 连接分别指向 master icegridregistry和 slave icegridregistry集群地址。测试还没有做,不过我估计应该是可以实现的。只不过如何自动获知 master 和 slave集群对外服务地址是个比较头痛的问题。

  2. 1个master icegridregistry集群,里面根据需要可包含2个以上master icegridregistry服务。无 slave icegridregistry 集群。1个或多个(根据实际业务需要)icegridnode集群,配置中的 registry 连接指向 master icegridregistry集群地址。这个测试也没有做,不知道同一个集群中2个长得一模一样的master icegridregistry服务是不是会引起 icegrid 自己内部的异常。当然,自动获知 master 和 slave集群对外服务地址依然是头痛的问题。

本文所有代码和文件均可在 http://git.oschina.net/eyiyluo_081/std_env 下载

© 著作权归作者所有

e
粉丝 0
博文 1
码字总数 5959
作品 0
南宁
私信 提问
一步一步用jenkins,ansible,supervisor打造一个web构建发布系统

新blog地址:http://hengyunabc.github.io/deploy-system-build-with-jenkins-ansible-supervisor/ 一步一步用jenkins,ansible,supervisor打造一个web构建发布系统。 本来应该还有gitlab这......

横云断岭
2015/03/05
0
0
python web 部署:nginx + gunicorn + supervisor + flask

python web 部署 web开发中,各种语言争奇斗艳,web的部署方面,却没有太多的方式。简单而已,大概都是 nginx 做前端代理,中间 webservice 调用程序脚本。大概方式: nginx 不用多说,一个高...

劲风online
2015/11/06
358
0
ZEROC究竟是何方神圣?

原文出自:http://www.roncoo.com/article/detail/124802 本文整理自《ZeroC Ice权威指南》作者Leader-us针对网友提出的ZeroC 问题的解答。 1、RPC又是炒冷饭?? Leader-us: RPC的确是炒冷...

1362802538
2016/08/11
278
0
Python Web 部署: 使用 flask + gunicorn + supervisor + nginx

flask   python 的服务器框架 gunicorn   webservice,WSGI 的容器 supervisor   进程管理工具 nginx   一个高性能的 web 服务器 创建项目 先为应用创建一个路径 构建 Python 的虚拟环...

SSBun
2017/06/01
0
0
ICE 通信数据包过大问题(c++)

当ICE 之间的通信数据包过大 客户端向服务端发送数据,如果数据包比较小,则正常,如果过大(超过十万字节),则服务端崩溃(未抛出任何异常),该情况只在windows server(windows server2...

guihong
2017/02/09
461
5

没有更多内容

加载失败,请刷新页面

加载更多

springboot 403 问题

添加WebAppConfigurer 配置 @Configuration@EnableAutoConfigurationpublic class WebAppConfigurer extends WebMvcConfigurerAdapter { public WebAppConfigurer() { } ......

布袋和尚_爱吃鱼
30分钟前
4
0
Python自动更换壁纸爬虫与tkinter结合

直接上代码 import ctypesimport timeimport requestsimport osfrom threading import Threadfrom tkinter import Tk, Label, Button,Entry,StringVar,messagebox# '放到AppData\Roami......

物种起源-达尔文
31分钟前
3
0
Postgresql Study 笔记

Postgresql 安装 Windows, MAC Install Postgresql 下载地址: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads Linux Install sudo apt-get update sudo apt-get in......

slagga
33分钟前
4
0
layer.open 打开新页面传参问题

如图所示,点击出售,把A页面的数据传到弹框上面,因为弹框比较复杂,所以使用引入一个新页面。 A.html a.js B.html b.js 1、第一种方案 sellInte: function (){ var obj = document.g...

木九天
35分钟前
4
0
沙龙报名 | 区块链数据服务技术应用实践

京东云是国内首家提供区块链数据在线分析服务产品的公司,也是行业内首家对区块链数据服务进行开源的公司。 本次沙龙是京东云BDS开源后,首次在深圳举办线下沙龙,我们将邀请京东云BDS团队核...

京东云技术新知
36分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部