在docker 1.3版本以前使用attach进入容器会经常出现卡死的情况,之后官方退出了exec命令,从宿主机进入,但是从其他远程主机进入使用ssh服务来维护是用户熟悉的方法。所以这里来创建一个带有ssh服务的镜像。基于docker commit命令和dockerfile创建。

基于commit命令

commit命令格式为docker commit CONTAINER [REPOSITORY[:TAG]],用户提交对容器的修改,并生成新的镜像。

首先使用ubuntu镜像来创建一个容器,尝试使用ssh命令无效。

# docker run -it ubuntu /bin/bash

因为ubuntu官方镜像中没有软件包的缓存文件,使用apt-get update更新即可,也可以修改源来配置。然后安装ssh。

# apt-get update

# apt-get install ssh -y

运行ssh需要目录/var/run/sshd存在,创建启动服务

# mkdir -p /var/run/sshd

# /usr/sbin/sshd -D &

然后可以看到已经运行,netstat命令可能也没有,安装即可apt-get install net-tools

此处还需要修改ssh服务的安全登录配置,取消pam登录限制,如下图注释即可。

然后复制需要登录的公钥信息(这里为本地主机)。使用ssh-keygen可以生成。

复制id_rsa.pub的内容到容器中的/root/.ssh/authorized_keys

创建ssh服务执行文件,然后退出容器

# vim /run.sh

# chmod +x run.sh

使用docker commit保存修改的容器,然后运行

# docker commit CONTAINER ID ssh:ubuntu

# docker run -d -p :22 ssh:ubuntu /run.sh

最后可以在宿主机上通过随机生成的32779端口来访问登录容器了:

使用dockerfile创建镜像

创建一个目录sshd_ubuntu,分别创建文件如下:

authorized_keys文件内容同样的复制

# cat /root/.ssh/id_rsa.pub > authorized_keys

然后编写Dockerfile文件如下,源自行修改即可:

FROM ubuntu:latest

MAINTAINER from whychz@ubuntu.com by boss yan

RUN rm -rf /etc/apt/sources.list

RUN echo 'deb-src http://archive.ubuntu.com/ubuntu xenial main restricted' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted' >> /etc/apt/sources.list

RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted' >> /etc/apt/sources.list

RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial universe' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list

RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list

RUN echo 'deb http://archive.canonical.com/ubuntu xenial partner' >> /etc/apt/sources.list

RUN echo 'deb-src http://archive.canonical.com/ubuntu xenial partner' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted' >> /etc/apt/sources.list

RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe' >> /etc/apt/sources.list

RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse' >> /etc/apt/sources.list

RUN apt-get update

RUN apt-get install -y openssh-server

RUN mkdir -p /var/run/sshd

RUN mkdir -p /root/.ssh

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 755 /run.sh

EXPOSE 22

CMD ["/run.sh"]

然后使用docker build创建镜像。最后的"."(点)表示当前目录中的Dockerfile

# docker build -t ubuntu:sshserver .

执行完成之后docker images查看镜像

最后运行容器,ssh测试是否成功

# docker run -d -p :22 ubuntu/sshserver --name ssh

# ssh 192.168.2.189 -p 32782 可以看到通过ssh已经进来了容器

Dockerfile介绍

Dockerfile是一个文本格式的配置文件,可以使用Dockerfile快速创建自定义的镜像。

基本结构

Dockerfile由一行行命令语句组成,支持#注释。一般分为四个部分:基础镜像,维护者信息,镜像操作指令和容器启动时执行指令。

一开始必须指明所基于的镜像,接下来会说明维护者信息。后面则是镜像的操作,比如RUN指令,每运行一条,镜像会添加新的一层,并提交。最后是CMD指令,来指定运行容器时的操作命令。

指令

FROM

格式为 FROM <image>或 FROM <image>:tag。指明所基于的镜像。

必须为第一条指令,如果在一个Dockerfile文件里创建多个镜像可多次使用,每个镜像一次。

MAINTAINER

格式为 MAINTAINER <name>,指定维护者信息

RUN

运行指定的命令

RUN命令有两种格式

1. RUN <command>

2. RUN ["executable", "param1", "param2"]

第一种后边直接跟shell命令,在linux操作系统上默认 /bin/sh -c。第二种是类似于函数调用。

可将executable理解成为可执行文件,后面就是两个参数。

两种写法比对:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME

RUN ["/bin/bash", "-c", "echo hello"]

注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层。

多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。RUN书写时的换行符是\

CMD

容器启动时要运行的命令

语法有三种格式

1. CMD ["executable","param1","param2"] 使用exec执行,推荐方式

2. CMD ["param1","param2"] 提供给ENTRYPOINT默认参数

3. CMD command param1 param2 在/bin/sh中执行,提供需要交互的应用

举例说明两种写法:

CMD [ "sh", "-c", "echo $HOME"]

CMD [ "echo", "$HOME" ]

这里边包括参数的一定要用双引号,不能是单引号。原因是参数传递后,docker解析的是一个JSON array。

每个dockerfile只能有一条CMD命令。指定了多条就只有最后一条会被执行。如果启动容器时候制定了运行的命令,则也会覆盖掉CMD指定的命令。

EXPOSE

格式为EXPOSE <port>[<port>...]

例如:EXPOSE 22 80 433

告诉docker服务器容器暴露的端口号

ENV

格式为ENV<key><value>

指定环境变量,会被后续的RUN指令使用,并在容器内保持运行

ADD

格式为<src><dest>

将指定的<src>到容器中的<dest>。<src>可以是dockerfile所在目录的一个相对路径,可以是一个url,也可以是一个tar文件(自动解压为目录)

COPY

又是一个复制命令

语法如下:

1. COPY <src>... <dest>

2. COPY ["<src>",... "<dest>"]

与ADD的区别是COPY的<src>只能是本地文件,其他用法一致

ENTRYPOINT

格式为:

1. ENTRYPOINT ["executable", "param1", "param2"]

2. ENTRYPOINT command param1 param2

配置容器启动后执行的命令,不可被docker run覆盖。每个Dockerfile中只能有一个ENTRTPOINT,指定多个时,只有最后一个生效。

VOLUME

格式为:

VOLUME ["/data"]

可实现挂载功能,可以将内地文件夹或者其他容器种得文件夹挂在到这个容器种

["/data"]可以是一个JsonArray ,也可以是多个值。所以如下几种写法都是正确的

VOLUME ["/var/log/"]

VOLUME /var/log

VOLUME /var/log /var/db

一般的使用场景为需要持久化存储数据时

容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失,所以当数据需要持久化时用这个命令。

USER

设置启动容器的用户,可以是用户名或UID,下面的两种写法是正确的:

USER daemo

USER UID

如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行。也可以在之前创建所需要的用户,如:RUN useradd user1,临时获取权限不推荐sudo而使用gosu。

WORKDIR

格式:WORKDIR /path/to/workdir

对后续的RUN,CMD,ENTRYPOINT,COPY,ADD配置工作目录。如果不存在则会创建,也可以设置多次

如:

WORKDIR /a

WORKDIR b

WORKDIR c

RUN pwd

结果是/a/b/c

WORKDIR也可以解析环境变量

如:

ENV DIRPATH /path

WORKDIR $DIRPATH/$DIRNAME

RUN pwd

pwd的执行结果是/path/$DIRNAME

ONBUILD

格式:ONBUILD [INSTRUCTION]

这个命令只对当前镜像的子镜像生效。

比如当前镜像为A,在Dockerfile种添加:

ONBUILD RUN ls -al

这个 ls -al 命令不会在A镜像构建或启动的时候执行,但是如果有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

镜像的创建

docker build [path],命令会读取指定路径下的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此建议一般放置Dockerfile目录为空目录。指定镜像的标签信息使用-t选项。如上面例子的docker build -t ubuntu:sshserver .

最新文章

  1. JS 传播事件、取消事件默认行为、阻止事件传播
  2. HttpClient——Get,Post
  3. linux-13基础命令之-touch,mkdir
  4. 介绍开源的.net通信框架NetworkComms框架 源码分析(十七 ) ConnectionSendClose
  5. [HTML] CSS3 边框
  6. 对TCP说三道四
  7. linux安装ftp服务器
  8. Microsoft Internet Explorer 内存破坏漏洞(CVE-2013-3193)(MS13-059)
  9. 最大似然预计(Maximum likelihood estimation)
  10. windows phone (22) 隐藏元素
  11. 微软 Build 2017 开发者大会:Azure 与 AI 的快速发展
  12. BFC(块级格式上下文)
  13. 第九节、人脸检测之Haar分类器
  14. hihocoder1051 补提交卡(贪心)
  15. Adding ASP.NET MVC5 Identity Authentication to an existing project
  16. 修改app工程名 Android Studio
  17. 动态修改JDBC数据源配置
  18. codeforces 1053D 树形DP
  19. URAL 1040 Airline Company 构造,思路 难度:2
  20. CSS背景横向平铺BUG,解决方法

热门文章

  1. SQL Server中的数据类型
  2. 【作业一】Android开发环境以及开发前的准备
  3. lfs(systemd版本)学习笔记-第3页
  4. SFTP 文件配置
  5. 原生JS强大DOM选择器querySelector与querySelectorAll
  6. Python中的基本数据类型的区别
  7. VUE axios 发送 Form Data 格式数据请求
  8. Android--px(像素)和dp、sp之间的相互转化
  9. android recovery 升级时间与速度研究
  10. Linux进程ID号--Linux进程的管理与调度(三)【转】