Chinaunix首页 | 论坛 | 博客
  • 博客访问: 230314
  • 博文数量: 96
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-14 11:43
文章分类

全部博文(96)

文章存档

2016年(41)

2015年(55)

我的朋友

分类: 系统运维

2015-12-02 15:47:34

在刚接触docker的时候,人们经常会说:“我们怎么进入到我的container中去呢?”,其他人会告诉他:“ 在container里面装一个ssh server,这样你就可以连入你的container了。” 但是这是糟糕的尝试,下面我将告诉大家为什么这么做是错误的,并且我们用什么方式来替代它。

在container里安装一个ssh server是非常诱人的,因为这样我们就可以直接连接container并且进入它的内部,我们中的大部分人每天都会用到ssh,我们用公钥私钥来进行登录,或者使用端口映射等其他方式。

所以也不奇怪,人们会建议,在container中创建一个ssh server,但是我们在这么做之前需要考虑以下问题:
1、你需要ssh来干什么?
大部分需求是,你要检查日志,做备份,或者重启进程,调整配置,查看服务器情况,下面将介绍如果不使用ssh来做到以上这些事情。

2、你如何来管理密钥和密码?
大部分的可能是,你将你的密钥和密码一起装进你的image中,或者将他们放在文件卷中,想一想如果你要更新你的密钥或者密码,你应该怎么做呢?
如果你把它们装载进image中,那你每次更新都需要重新创建image,重新发布image,然后重启container。这样做是不是不是很优雅。
一个更好的办法是将这些东西放在一个文件卷标中,它能工作,但是也有显著的缺点,你必须保证你的container没有对这个文件卷标有写的权限,否则可能会污染你的密钥和密码,从而造成你无法登录这个container。而且事情可能因为你为多个container共享这些东西而变的更加难以管理和糟糕。

3、你如何管理你的安全升级
SSH server 是非常安全的,但是一旦你的密钥或密码泄漏,你不得不升级所有使用SSH的container,并且重启他们。这也以为着注入memcache这样的内存缓存服务器的缓存将全部丢失,你不得不重建缓存。

4、你是否需要“加入SSH server”就能工作?
不 是的,你还需要加入进程管理软件,Monit 或 Supervisor等监控软件,让应用开启多个进程运行。换而言之,你把一个简单的container转变为一个复杂的东西了。如果你的应用停止了,你 不得不从你的进程管理软件那里获得信息,因为Docker只能管理单进程。

5、你负责把一个应用转载进一个container,但你也负责访问策略和安全规范?
在一些小的场景中,这没什么问题,但是在大的应用中,你是将应用装载进container的开发人员,可能有另外的人负责对这个应用的访问策略部署。你的公司可能有严格的权限管控,因此公司肯定不希望在container中安装ssh server。

但是不使用ssh,我们改如何做以下事情呢?
1、备份我的数据
你 的数据必须是一个volumn,这样你可以启动另外一个container,并且通过 --volumes-from 来共享你的应用的container的数据,这个新的container会来处理数据备份的事情。额外的好处,如果你项对你的数据文件(比如:日志)进行 压缩长久保存,那完全可以在一个新的container中处理,这样你的应用container就是干净的

2、检查日志
使用文件volumn,和之前一样的方法,重新启动一个日志分析的container,让它来处理日志和检查日志。

3、重启我的应用服务
当你发出” /etc/init.d/foo restart “ 或 ”service foo restart“,它几乎总是导致向进程发送一个特殊的信号,你可以使用如下的命令发送这个信号:”docker kill -s .“
一 些服务他不监听信号,但是接受一个特殊的命令在socket套接字上,如果是tcp server,那就仅仅通过网络链接他,如果他使用unix socket,那就又要用到 volumn了。设置container中的服务,让他控制的sockert在一个特殊的目录中,这个目录就是volumn,然后你可以启动一个新的container,使用这个文件 volumn。

但 是这相当复杂吗?假设你有一个服务叫 foo,创建一个foo.sock 文件在 /var/run/foo.sock,现在需要重启这个服务。我们只需要在启动foo服务时,加上 -v /var/run,(或者加上 VOLUME /var/run),然后当你重启时,执行--volumes-from 参数就可以让新的foo服务启动起来了。
		
# Starting the service
CID=$(docker run -d -v /var/run fooservice)
# Restarting the service with a sidekick container
docker run --volumes-from $CID fooservice fooctl restart

4、修改我的配置文件
如果你正在执行一个持久的配置变更,你最好把他的改变放在image中,如果你又启动一个container,那么服务还是使用的老的配置,你的配置变更将丢失,所以不要使用ssh来访问container。
“但是我需要在应用存活期间,改变我的配置,例如增加一个新的虚拟站点”
这样的话还是需要使用volumn来处理,并且通过服务的api来动态读取配置,这样所有的应用container都可以快速的临时变更配置。

5、调试我的应用
这可能是唯一需要进入container的场景了,这样你就需要 nsenter 软件

介绍 nsenter
nsenter是一个小的工具,用来进入命名空间中,它可以进入命名空间,或者在现有的命名空间中产生一个新的进程,命名空间是什么?他们是container的重要组成部分。
简单点说,通过使用 nsenter 你可以进入一个已经存在的container中,尽管这个container没有安装ssh server或者其他类似软件。
项目地址:
或者简单的来安装:
	

docker run -v /usr/local/bin:/target jpetazzo/nsenter

它将会把nsenter安装到主机的 /usr/bin 中,你就可以方便的使用它了。
使用方法:
1、找出你想要进入的container的pid
	

PID=$(docker inspect --format {{.State.Pid}} )

2、根据pid进入container内部
	

$ sudo nsenter --target $PID --mount --uts --ipc --net --pid

3、如何远程访问
如果你想要远程访问这个container,那么你至少有2种方法
通过SSH链接到你的docker主机,并且使用 nsenter。
通过SSH链接到你的docker主机,通过一个特殊的密钥参数授权esenter命令。

如果你遇到:
	
$ docker run -v /usr/local/bin:/target jpetazzo/nsenter
Installing nsenter to /target
cp: cannot create regular file '/target/nsenter': Permission denied
Installing docker-enter to /target
cp: cannot create regular file '/target/docker-enter': Permission denied
那就需要手动将 container 里的 nsenter 命令拷贝到 /usr/local/bin 目录下了
1、先把jpetazzo/nsenter运行起来:
	

 docker run -d -i -t jpetazzo/nsenter /bin/bash

2、根据docker ps 找到container的id,然后执行cp命令:
	
cp /var/lib/docker/devicemapper/mnt/<containid>/rootfs/nsenter /usr/local/bin/
cp /var/lib/docker/devicemapper/mnt/<containid>/rootfs/docker-enter /usr/local/bin/
注意:devicemapper 是centos的路径名,windows下是aufs

如果遇到在container里无法解析域名,则需要手动增加dns服务器,方法如下:
	
DOCKER_OPTS=" --dns 8.8.8.8"
service docker restart


总结
docker允许你根据自己工作习惯处理,但是请跳出这样的概念:“我的container是一个小的vps”,要知道还有其他的解决方案来处理需要SSH的问题
阅读(2185) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~