Docker 入门私人笔记(七)生产镜像构建实战之构建CentOS+SSH镜像

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 13510182959@126.com

#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 13510182959@126.com
 ---> 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

image.png

查看镜像,已经制作好了
image.png

实例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 13510182959@126.com

#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 .

构建镜像结束,查看镜像
image.png

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 确认新容器是否创建成功并正常运行:
image.png

使用 SSH 的方式连接该容器,在宿主机中操作即可:

ssh -p 8022 root@192.168.100.151:8022

连接成功,说明镜像制作成功。

查看容器的进程,可以看到 sshd 服务的进程 ID 是 1 ,如果服务挂了,这个容器也就宕掉了。
image.png

问题:
使用容器是为了要运行软件(应用),而不是 SSH。通常来说将软件部署在容器内,该软件运行的进程的 PID 为 1,那么当容器启动或者关闭,这个软件也就启动或关闭了。但是如果 PID 进程 1 被 SSH 占用,或者某些情况下在同一个容器内不得不运行 2 个甚至 2 个以上的软件时,如何去管理这些软件的运行呢?
不可能登陆进每个容器内去操作,不现实。所以这时候我们可以使用 superviser 这个软件来管理容器内的进程。后面的文章再讲。

终身学习,向上生长~

7 声望
5 粉丝
0 条评论
推荐阅读
K8S 笔记 - Pod 的 DNS 策略中的“坑”
ClusterFirst: 与配置的集群域后缀不匹配的任何 DNS 查询(例如 "www.kubernetes.io") 都将转发到从节点继承的上游名称服务器。集群管理员可能配置了额外的存根域和上游 DNS 服务器。

逆熵流1阅读 457

使用kubeasz部署高可用kubernetes集群
本实验采用kubeasz作为kubernetes环境部署工具,它是一个基于二进制方式部署和利用ansible-playbook实现自动化来快速部署高可用kubernetes集群的工具,详细介绍请查看kubeasz官方。本实验用到的所有虚拟机默认软...

李朝阳4阅读 773

openSSH升级公钥失效Permission denied (publickey)解决方案
背景centos系统升级openSSH后,服务器上无法再拉取代码,报错如下:原因服务器重新安装SSH后公钥改变,需要重新安装ssh-keygen -t rsa -C "邮箱地址"生成公钥,删除gitlab原有公钥,但是git pull依然报错如下:依...

兰俊秋雨2阅读 1.5k

制作容器镜像的最佳实践
这篇文章主要是我日常工作中的制作镜像的实践, 同时结合我学习到的关于镜像制作的相关文章总结出来的. 包括通用的容器最佳实践, java, nginx, python 容器最佳实践. 最佳实践的目的一方面保证镜像是可复用的, 提...

东风微鸣云原生2阅读 639

K8S 生态周报| containerd 存在 bug 会导致 Pod 被重启,建议升级
这是 2023 年的第一篇『K8S 生态周报』,在上个月的月中之后我因为阳了就停止更新了,一直在修养身体。生病相关的内容我在上一篇文章 张晋涛:我的 2022 总结 | MoeLove有做介绍。愿大家都注意身体,保持健康。

张晋涛1阅读 736

封面图
容器在公有云上的落地姿势
容器(container),并不是一种虚拟化(virtualization)技术,而是一种进程隔离(isolation)技术,从内核空间、资源和安全等方面对进程做隔离。

亚马逊云开发者1阅读 464

封面图
minikube master 节点的 docker 用户的密码什么?
先看下 node 的 ip 地址 {代码...} 但是直接登录 docker node 会失败! {代码...} 查了一下,可以不用账号密码,而是密钥对登录 {代码...} 指定公钥地址,就可以了 {代码...} 参考:How do I ssh into the VM for ...

ponponon阅读 1.4k

终身学习,向上生长~

7 声望
5 粉丝
宣传栏