1. Docker 镜像分层设计
docker 镜像有个非常重要的概念:分层。docker 镜像是 “分层存储”的,Dockerfile 中的每一个指令都会生成镜像的一层
。例如所有的自定义镜像都需要执行“FROM centos”,那么这一层只需要第一次下载,后面就都不会下载了。
层,从上到下依次是:
- 应用
- 运行环境
- 操作系统
2. 做一个属于自己公司的镜像
实例1:
基于 centos 官方的镜像做一个新镜像,安装常用的基本功能,如:wget sudo git tree net-tools 。
2.1 创建合理的目录用于存放不同的 Dockerfile
cd /data/dockerfile/
mkdir system runtime app mynginx
前 3 个目录分别对应的内容是操作系统、运行环境、应用软件,第 4 个目录用于存放 dockerfile,本文以创建 Nginx docker 镜像为例,所以起名为 mynginx 。
cd system/
mkdir centos
cd centos/
2.2 编辑 Dockerfile
vim Dockerfile,内容如下:
#Base Image 指定基础镜像
FROM centos
#Maintainer 镜像维护者的信息
MAINTAINER lu [email protected]
#RUN 想让该镜像做什么
#RUN 后面跟的是制作容器镜像时运行的命令
#ADD 后面分别跟两个参数,宿主机文件和镜像中的文件。即从宿主机复制一个文件到景象中。本示例中给出的 “/usr/share/nginx/html/index.html” 是 yum 方式安装 nginx 的 index 默认路径。
#EXPOSE 是容器对外的端口
#CMD 是使用该镜像启动的容器要运行的命令
RUN rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
#基于
RUN yum install -y wget sudo git tree net-tools && yum clean all
注意:
在镜像内安装完软件后务必执行 yum clean all ,可以删除安装软件遗留的无用文件,有效节约空间。
2.3 执行 Dockerfile
docker build -t system/centos:v1 .
注意:
执行 docker build 命令不要忘记最后的点,表示从当前目录读取 Dockerfile 。
制作镜像的过程如下:
[root@k8s-master /data/dockerfile/system/centos]# docker build -t system/centos:v1 .
Sending build context to Docker daemon 2.56kB
Step 1/4 : FROM centos
---> 5182e96772bf
Step 2/4 : MAINTAINER lu [email protected]
---> Using cache
---> 9af4bd99cdc6
Step 3/4 : RUN rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
---> Using cache
---> 91da60642226
Step 4/4 : RUN yum install -y wget sudo git tree net-tools && yum clean all
---> Using cache
---> d5ba564a6b85
Successfully built d5ba564a6b85
Successfully tagged system/centos:v1
实例2:
接下来基于 centos 官网镜像制作镜像 system/centos:v2(也可以基于 system/centos:v1 来制作),在里面安装 ssh 服务(便于使用惯了虚拟机的开发和维护人员使用 ssh 连接容器,不推荐
)。
2.4 编辑 Dockerfile,对比刚才的 Dockerfile,里面多了 SSH 安装的步骤:
cd /data/dockerfile/system/
mkdir centos-ssh
cd centos-ssh
vim Dockerfile,Dockerfile 的配置如下:
#Base Image 指定基础镜像
FROM centos
#Maintainer 镜像维护者的信息
MAINTAINER lu [email protected]
#RUN 想让该镜像做什么
#RUN 后面跟的是制作容器镜像时运行的命令
#ADD 后面分别跟两个参数,宿主机文件和镜像中的文件。即从宿主机复制一个文件到景象中。本示例中给出的 “/usr/share/nginx/html/index.html” 是 yum 方式安装 nginx 的 index 默认路径。
#EXPOSE 是容器对外的端口
#CMD 是使用该镜像启动的容器要运行的命令
RUN rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum install -y wget sudo git tree net-tools openssh-clients openssh-server openssh-devel && yum clean all
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -A -t dsa -f /etc/ssh/ssh_host_dsa_key
#Set root password
RUN echo "root:lusibo@123" | chpasswd
执行 Dockerfile
docker build -t system/centos:v2 .
2.5 接下来验证使用新镜像
验证:使用新镜像启动的 docker 容器是否能按照设想的那样运行和使用。
使用镜像 system/centos:v2 运行一个 docker 容器:
docker run -d --name centos-ssh-demo -p 8022:22 system/centos:v2 /usr/sbin/sshd -D
命令解释:
- --name centos-ssh-demo,启动的容器名称是 centos-ssh-demo;
- -p 8022:22,将启动起来的容器的 22 端口映射给宿主机的 8022 端口;
- /usr/sbin/sshd -D,让sshd服务在后台运行。
运行 docker ps 确认新容器是否创建成功并正常运行:
使用 SSH 的方式连接该容器,在宿主机中操作即可:
ssh -p 8022 [email protected]:8022
连接成功,说明镜像制作成功。
查看容器的进程,可以看到 sshd 服务的进程 ID 是 1 ,如果服务挂了,这个容器也就宕掉了。
问题:
使用容器是为了要运行软件(应用),而不是 SSH。通常来说将软件部署在容器内,该软件运行的进程的 PID 为 1,那么当容器启动或者关闭,这个软件也就启动或关闭了。但是如果 PID 进程 1 被 SSH 占用,或者某些情况下在同一个容器内不得不运行 2 个甚至 2 个以上的软件时,如何去管理这些软件的运行呢?
不可能登陆进每个容器内去操作,不现实。所以这时候我们可以使用 superviser 这个软件来管理容器内的进程。后面的文章再讲。