为镜像添加SSH服务
操作Docker容器介绍了一些进入容器的办法,比如attach、exec等命令,但是这些命令都无法解决远程管理容器的问题。因此,当需要远程登录到容器内进行一些操作的时候,就需要SSH的支持了。
如何自行创建一个带有SSH服务的镜像,并详细介绍了两种创建容器的方法:基于docker commit命令创建和基于Dockerfile创建。
基于commit命令创建
Docker提供了docker commit命令,支持用户提交自己对制定容器的修改,并生成新的镜像。
命令格式为docker commit CONTAINER [REPOSITORY[:TAG]]。
这里以ubuntu:14.04镜像添加SSH服务的操作流程为例。
1.准备工作
首先,使用ubuntu:14.04镜像来创建一个容器:
$ docker run -it ubuntu:14.04 /bin/bash
更新apt缓存,并安装openssh-server:
root@fc1936ea8ceb:/# apt-get update; apt-get install openssh-server -y
2.安装和配置SSH服务
选择主流的openssh-server作为服务端:
root@fc1936ea8ceb:/# apt-get install openssh-server –y
如果需要正常启动SSH服务,则目录/var/run/sshd必须存在,手动创建它,并启动SSH服务:
root@fc1936ea8ceb:/# mkdir -p /var/run/sshd
root@fc1936ea8ceb:/# /usr/sbin/sshd -D & [1] 3254
此时查看容器的22端口(SSH服务默认监听的端口),可见此端口已经处于监听状态:
root@fc1936ea8ceb:/# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
修改SSH服务的安全登录配置,取消pam登录限制:
root@fc1936ea8ceb:/# sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
在root用户目录下创建.ssh目录,并复制需要登录的公钥信息(一般为本地主机用户目录下的.ssh/id_rsa.pub文件,可由ssh-keygen-t rsa命令生成)到authorized_keys文件中:
root@fc1936ea8ceb:/# mkdir root/.ssh
root@fc1936ea8ceb:/# vi /root/.ssh/authorized_keys
创建自动启动SSH服务的可执行文件run.sh,并添加可执行权限:
root@fc1936ea8ceb:/# vi /run.sh
root@fc1936ea8ceb:/# chmod +x run.sh
其中,run.sh脚本内容如下:
#!/bin/bash
/usr/sbin/sshd -D
最后,退出容器:
root@fc1936ea8ceb:/# exit
exit
3.保存镜像
将所退出的容器用docker commit命令保存为一个新的sshd:ubuntu镜像:
$ docker commit fc1 sshd:ubuntu
7aef2cd95fd0c712f022bcff6a4ddefccf20fd693da2b24b04ee1cd3ed3eb6fc
使用docker images查看本地生成的新镜像sshd:ubuntu,目前拥有的镜像如下:
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
sshd ubuntu 7aef2cd95fd0 10 seconds ago 255.2 MB
busybox latest e72ac664f4f0 3 weeks ago 2.433 MB
ubuntu latest ba5877dc9bec 3 months ago 192.7 MB
4.使用镜像
启动容器,并添加端口映射10022-->22。其中10022是宿主主机的端口,22是容器的SSH服务监听端口:
$ docker run -p 10022:22 -d sshd:ubuntu /run.sh
3ad7182aa47f9ce670d933f943fdec946ab69742393ab2116bace72db82b4895
启动成功后,可以在宿主主机上看到容器运行的详细信息:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ad7182aa47f sshd:ubuntu "/run.sh" 2 seconds ago Up 2 seconds 0.0.0.0:10022->22/tcp focused_ptolemy
在宿主主机(192.168.1.200)或其他主机上上,可以通过SSH访问10022端口来登录容器:
$ ssh 192.168.1.200 -p 10022
root@3ad7182aa47f:~#
使用Dockerfile创建
使用Dockerfile来创建一个支持SSH服务的镜像。
1.创建工作目录
首先,创建一个sshd_ubuntu工作目录:
$ mkdir sshd_ubuntu
在其中,创建Dockerfile和run.sh文件:
$ cd sshd_ubuntu/
$ touch Dockerfile run.sh
2.编写run.sh脚本和authorized_keys文件
脚本文件run.sh的内容:
#!/bin/bash
/usr/sbin/sshd -D
在宿主主机上生成SSH密钥对,并创建authorized_keys文件:
$ ssh-keygen -t rsa
$ cat ~/.ssh/id_rsa.pub > authorized_keys
3.编写Dockerfile
下面是Dockerfile的内容及各部分的注释,可以对比上一节中利用docker commit命令创建镜像过程,所进行的操作基本一致:
#设置继承镜像
FROM ubuntu:14.04
#提供一些作者的信息
MAINTAINER docker_user (user@docker.com)
#下面开始运行更新命令
RUN apt-get update
#安装ssh服务
RUN apt-get install -y openssh-server
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
#取消pam限制
RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
#复制配置文件到相应位置,并赋予脚本可执行权限
ADD authorized_keys /root/.ssh/authorized_keys
ADD run.sh /run.sh
RUN chmod /run.sh
#开放端口
EXPOSE
#设置自启动命令
CMD ["/run.sh"]
4.创建镜像
在sshd_ubuntu目录下,使用docker build命令来创建镜像。这里需要注意最后还有一个“.”,表示使用当前目录中的Dockerfile:
$ cd sshd_ubuntu
$ docker build -t sshd:Dockerfile .
使用Dockerfile创建自定义镜像,需要注意的是Docker会自动删除中间临时创建的层,还需要注意每一步的操作和编写的Dockerfile中命令的对应关系。
命令执行完毕后,如果见“Successfully built XXX”字样,则说明镜像创建成功。可以看到,以上命令生成的镜像ID是570c26a9de68。
在本地查看sshd:Dockerfile镜像已存在:
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
sshd Dockerfile 570c26a9de68 4 minutes ago 246.5 MB
ubuntu 14.04 ba5877dc9bec 3 months ago 192.7 MB
5.测试镜像,运行容器
使用刚才创建的sshd:Dockerfile镜像来运行一个容器。
直接启动镜像,映射容器的22端口到本地的10122端口:
$ docker run -d -p 10122:22 sshd:Dockerfile
890c04ff8d769b604386ba4475253ae8c21fc92d60083759afa77573bf4e8af1
$ docker ps
在宿主主机新打开一个终端,连接到新建的容器:
$ ssh 192.168.1.200 -p 10122
root@890c04ff8d76:~#
效果与上一小节一致,镜像创建成功。
小结
在Docker社区中,对于是否需要为Docker容器启用SSH服务一直有争论。
反对方的观点是:Docker的理念是一个容器只运行一个服务。因此,如果每个容器都运行一个额外的SSH服务,就违背了这个理念。另外认为根本没有从远程主机进入容器进行维护的必要。
支持方的观点是:在Docker 1.3版本之前,如果要用attach进入容器,经常容易出现卡死的情况。1.3之后,虽然官方推出了docker exec命令,再从宿主主机进入是没有障碍了,但是如果要从其他远程主机进入容器依然没有更好的解决方案。
这两种说法各有道理,其实是在讨论不同的容器场景:即作为应用容器还是作为系统容器。应用容器行为围绕应用生命周期,较为简单,不需要人工的额外干预;而系统容器则需要支持管理员的登录操作,这个时候,对SSH服务的支持就变得十分必要了。
因此,在Docker推出更加高效、安全的方式对系统容器进行远程操作之前,容器的SSH服务还是比较重要的,而且它对资源的需求不高,同时安全性可以保障。
为镜像添加SSH服务的更多相关文章
- 读书笔记---《Docker 技术入门与实践》---为镜像添加SSH服务
之前说到可以通过attach和exec两个命令登陆容器,但是如果遇到需要远程通过ssh登陆容器的场景,就需要手动添加ssh服务. 下面介绍两种方法创建带有ssh服务的镜像,commit命令创建和通过D ...
- Docker实战-为镜像添加SSH服务
1.基于docker commit命令创建 Docker提供了docker commit命令,支持用户提交自己对定制容器的修改,并生成新的镜像. 命令格式为:docker commit CONTAIN ...
- Docker实战(七)之为镜像添加SSH服务
1.基于commit命令创建 Docker提供了docker commit命令,支持用户提交自己对制定容器的修改,并生成新的镜像.命令格式为docker commit CONTAINER [REPOS ...
- 为Docker镜像添加SSH服务
一.基于commit命令创建 1. 首先下载镜像 $ docker run -it ubuntu:16.04 /bin/bash 2. 安装SSH服务 #更新apt缓存 root@5ef1d31632 ...
- docker 为镜像添加ssh服务-docker commit命令创建
环境centos7 一.准备工作 docker pull ubuntu:18.04 docker run -it ubuntu:18.04 bash 二.配置软件源apt-get update,如果系 ...
- Docker-为镜像添加SSH服务
进入容器的办法有很多,包括exec.attach等命令,但是这些命令都无法解决远程管理容器的问题,因此,需要SSH的支持 基于commit命令创建 docker提供了docker commit命令,支 ...
- docker为镜像添加SSH服务
启动并进入容器中 这里用db1容器完成实验. 安装openssh服务和修改sshd配置文件 安装openssh yum install openssh-server openssh-clients - ...
- docker 为镜像添加ssh服务-使用Dockerfile 创建
首先,基于要添加内容的镜像ubuntu:18.04运行一个容器, 在宿主机(下面步骤是在容器中创建的,应该在宿主机创建进行以下步骤) 一.创建一个工作目录 二.创建Dockerfile 和脚本run. ...
- 添加ssh服务构建新镜像-docker commit 方式01
添加ssh服务构建新镜像-docker commit 方式 1:docker commit构建自定义镜像---一般不推荐使用这种方式构建新镜像 1:ubuntu基础镜像下载 ubuntu@ubuntu ...
随机推荐
- node API buffer
https://cnodejs.org/topic/5189ff4f63e9f8a54207f60c 1.拼接字符串时,String比buffer要快,buffer需要toString().当保存非u ...
- [Zend Mail]发送中文名附件出现乱码解决方案
Zend Framework 1.0.* “=?UTF-8?B?”.base64_encode($title).“?=” 发送中文名附件,结果如图: 英文名附件,结果截图: 解决办法就是将中文文件名拼 ...
- CentOS 7 Flannel的安装与配置
1. 安装前的准备 etcd 3.2.9 Docker 17.12.0-ce 三台机器10.100.97.236, 10.100.97.92, 10.100.97.81 etcd不同版本之间的差别还是 ...
- 移动端Retina屏边框线1px 显示为2px或3px问题解决方法
我们在开发移动端web项目时经常遇到设置border:1px,但是显示的边框却为2px或是3px粗细,这是因为设备像素比devicePixelRatio为2或3引起的. 1.何为“设备像素比dev ...
- Linux - 修改文件编码
enca -L zh_CN -x UTF- file
- Unity Shader序列帧动画学习笔记
Unity Shader序列帧动画学习笔记 关于无限播放序列帧动画的一点问题 在学shader的序列帧动画时,书上写了这样一段代码: fixed4 frag(v2f i){ // 获得整数时间 flo ...
- Elasticsearch、Kibana Windows下环境搭建
Elasticsearch 簡介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是 ...
- Android Locale
Locale 是用来适配语言和地区的.在实际使用过程中,如果使用不当还是会出现错误. 首先,需要了解的是,Locale 分两种,一种是语言,一种是地区.语言比如英语,地区比如美国.区别显而易见,说英语 ...
- Mysql分析-profile详解
一.前言当我们要对某一条sql的性能进行分析时,可以使用它. Profiling是从 mysql5.0.3版本以后才开放的.启动profile之后,所有查询包括错误的语句都会记录在内.关闭会话或者se ...
- robot_framework Authorization 解决登录超时问题(token)
写rf的接口时,遇到总是报错提示: 登录超时 解决过程: 1 . 通过对同一个接口进行手机抓包对比,发现该接口请求时,多了Authorization,需要HTTP Basic Authenticati ...