Docker技术入门与实战笔记(六)

本文详细介绍了Dockerfile的使用,包括基础结构、配置指令和操作指令,如ARG, FROM, RUN, CMD等,并提供了创建镜像的实践案例,如精简镜像、选用合适的基础镜像和使用多步骤创建。" 118395602,10294912,西北工业大学电子信息(专硕)导师信息与考研攻略,"['西北工业大学', '电子信息', '专硕', '考研', '导师']
摘要由CSDN通过智能技术生成

本文是我在学习《Docker技术入门与实战》第3版(杨保华 戴王剑 曹亚仑编著)时所做的笔记,有许多描述不清楚的地方,建议自行购买学习。

使用Dockerfile创建镜像
基本结构

Dockerfile主题内容分为四部分:
1、基础镜像信息;
2、维护者信息;
3、镜像操作指令;
4、容器启动时执行指令。
Dockerfile支持以#开头的注释行。

例如之前构建镜像用的Dockerfile:

# 基础镜像
From ubuntu
#  维护者信息和版本号
LABEL verison="1.1" maintainer="duanhun"
# 镜像操作指令
RUN apt-get update && \
	apt-get install -y git && \
	apt-get install -y nginx && \
	apt-get clean && \
	rm -rf /var/lib/apt/lists/*
# 之前没用到的容器启动时执行指令,也就是说之前安装的nginx就没启动,之前也只是验证了下版本
CMD /usr/sbin/nginx

指令说明
Dockerfile中指令分为配置指令和操作指令。

配置指令
1、ARG
定义创建镜像过程中使用的变量。
格式为ARG [=]
执行docker build时可通过-build-arg[=]来为变量赋值。
Docker内置了一些镜像创建变量,用户可以直接使用而无须声明,包括(不区分大小写)HTTP_PROXY、HTTPS_PROXY、FTP_PROXY、NO_PROXY。

2、FROM
指定所创建镜像的基础镜像。
为了保证镜像精简,尽量选用体积较小的镜像如Alpine或Debian作为基础镜像。

3、LABEL
LABEL 指令可以为生成的镜像添加元数据标签信息。
格式为LABEL <key>=<value> <key>=<value> …

4、EXPOSE
声明镜像内服务监听的端口。
格式为EXPOSE <port> [<port>/<protocol>…]
该指令只是起到声明作用,并不会自动完成端口映射。

5、ENV
指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。
格式与LABEL一样。
指定的环境变量会被命令参数docker run --env <key>=<value> 覆盖。

6、ENTRYPOINT
指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行。
在运行时可以被–entrypoint参数覆盖掉。

7、VOLUME
创建一个数据卷挂载点。

8、USER
指定运行容器时的用户名或UID。

9、WORKDIR
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。

10、ONBUILD
指定当基于所生成镜像创建子镜像时,自动执行的操作指令。

11、STOPSIGNAL
指定所创建镜像启动的容器接收退出的信号值。

12、HEALTHCHECK
配置所启动容器如何进行健康检查。

13、SHELL
指定其他命令所使用shell时的默认shell类型。

操作指令
1、RUN
运行指定命令。
格式为RUN 或RUN [“executable”, “param1”, “param2”]。前者默认将在shell终端中运行;后者则使用exec执行,不会启动shell环境。

2、CMD
指令用来指定启动容器时默认执行的命令。

3、ADD
添加内容到镜像。
格式ADD <src> <dest>
将复制指定的<src>路径下的内容到容器中的<dest>路径下。

4、COPY
复制内容到镜像。
复制本地主机的<src>下内容到镜像中的<dest>。目标路径不存在时会自动创建。
当使用本地目录作为原目录时推荐使用COPY。

创建镜像
docker build命令用于编译Dockerfile文件并生成镜像,子命令-t用来指定生成镜像的名称和版本号,具体信息可参考docker build –help。

选择父镜像
用户可以选择两种镜像作为父镜像,一种是基础镜像,另一种是普通镜像。
基础镜像比较特殊,其Dockerfile中往往不存在FROM指令,或者基于scratch镜像。

使用.dockerignore文件
可以通过.dockerignore文件来让Docker忽略匹配路径或文件,在创建镜像时不将无关数据发送到服务器。
例如:

# .dockerignore文件中可以定义忽略模式
*/temp*
*/*/temp*
tmp?
~*
Dockerfile
!README.md

多步骤创建
对于需要编译的应用来说,通常情况下至少需要准备两个环境的Docker镜像:
1、编译环境镜像;
2、运行环境镜像。
使用多步骤创建,可以在保证最终生成的运行环境镜像保持精简的情况下,使用单一的Dockerfile,降低维护复杂度。

实践经验
1、精简镜像用途;
2、选用合适的基础镜像;
3、提供注释和维护者信息;
4、减少镜像层数:尽量合并RUN、ADD和COPY指令;
5、恰当使用多步骤创建;
6、使用.dockerignore文件;
7、及时删除临时文件和缓存文件;
8、提高生成速度;
9、调整合理的指令顺序;
10、减少外部源的干扰。

操作系统
BusyBox
BusyBox是一个集成了100多个最常用linux命令的精简工具箱,只有不到2MB,被誉为“linux系统的瑞士军刀”。
获取和运行BusyBox:
docker run -it busybox

Alpine
Alpine系统时一个面向安全的轻型Linux发行版,关注安全、性能和资源效能。目前Docker官方推荐使用Alpine作为默认的基础镜像环境。

其他系统自己下载看吧,Debian、Ubuntu、CentOS、Fedora。

为镜像添加SSH服务
基于commit命令创建
Docker提供了docker commit命令,支持用户提交自己对指定容器的修改。
在此采用alpine作为基础镜像来添加SSH服务。
1、准备工作
本地先生成一份ssh-keygen密钥,执行命令,然后一路回车键:

ssh-keygen

在这里插入图片描述
新建一个目录,然后将~/.ssh/id_rsa.pub文件拷贝进取。

mkdir sshd_alpine
cp ~/.ssh/id_rsa.pub sshd_alpine/authorized_keys

下载并启动alpine,执行命令:

docker run -it -v /home/duanhun/projects/docker/sshd_alpine/:/volume alpine

在这里插入图片描述
2、配置软件源
执行命令:

echo "http://mirrors.aliyun.com/alpine/v3.9/main" > /etc/apk/repositories
echo "http://mirrors.aliyun.com/alpine/v3.9/community" >> /etc/apk/repositories
apk update

在这里插入图片描述

3、安装和配置SSH服务
执行命令安装openssh-server:

apk add openssh-server

在这里插入图片描述

生成ssh-keygen密钥,执行命令

ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -t ecdsa -N "" -f /etc/ssh/ssh_host_ecdsa_key
ssh-keygen -t ed25519 -N "" -f /etc/ssh/ssh_host_ed25519_key

在这里插入图片描述
设置允许root用户从ssh登录

echo "PermitRootLogin yes" >> /etc/ssh/sshd_config

把root密码设置成空字符串,不执行的话root无法通过ssh登录

passwd -d root

将/volume下的文件拷贝到/root/.ssh/目录下

mkdir ~/.ssh
cp /volume/authorized_keys ~/.ssh/.

启动SSH服务

/usr/sbin/sshd -D &

在这里插入图片描述
4、验证SSH服务
执行ifconfig查看容器ip地址:
在这里插入图片描述

另外打开一个客户端,执行命令:

ssh -p22 root@172.17.0.2

在这里插入图片描述
5、执行docker commit提交镜像

docker commit 305e5cf32a54 sshd:alpine

在这里插入图片描述

6、测试镜像
停止和删除之前的alpine容器,从新建的镜像重新启动一个容器:

docker run -d -p 10022:22 sshd:alpine /usr/sbin/sshd -D

在这里插入图片描述

继续执行:

ssh -p10022 root@127.0.0.1

在这里插入图片描述
使用Dockerfile创建
也就是把上述命令整理起来再做一些补充即可。
在上边新建的sshd_alpine目录下新建Dockerfile文件,内容如下:

# ssh版本号
ARG sshd_version=7.9_p1-r5
# alpine版本号
ARG alpine_version=3.10.2
# root用户密码
ARG root_passwd=123456
# 基础镜像alpine
FROM alpine:${alpine_version}
# 官网上有这句话:An ARG declared before a FROM is outside of a build stage, so it can’t be used in any instruction after a FROM. To use the default value of an ARG declared before the first FROM use an ARG instruction without a value inside of a build stage:
# google翻译:在FROM之前声明的ARG在构建阶段之外,因此,FROM之后的任何指令都不能使用它。 要使用在第一个FROM之前声明的ARG的默认值,请使用ARG指令,而在构建阶段内部不带值
# 官方说明地址: https://docs.docker.com/engine/reference/builder/
# 这个坑踩了一星期终于踩平了
ARG sshd_version
ARG root_passwd
# 镜像信息
LABEL version=0.1 maintainer=duanhun
# 配置软件源
RUN echo "http://mirrors.aliyun.com/alpine/v3.9/main" > /etc/apk/repositories \
	&& echo "http://mirrors.aliyun.com/alpine/v3.9/community" >> /etc/apk/repositories \
	&& apk update
# 安装和配置ssh服务,并删除缓存
RUN apk add openssh-server=${sshd_version} \
	&& ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key \
	&& ssh-keygen -t ecdsa -N "" -f /etc/ssh/ssh_host_ecdsa_key \
	&& ssh-keygen -t ed25519 -N "" -f /etc/ssh/ssh_host_ed25519_key \
	&& echo "PermitRootLogin yes" >> /etc/ssh/sshd_config \
	&& rm -rf /var/cache/apk/
# root用户处理
RUN echo -e "${root_passwd}\n${root_passwd}" | passwd root 
# COPY命令可自动创建目标目录,ADD不行
COPY authorized_keys /root/.ssh/
# 声明端口号
EXPOSE 22
# 容器启动时启动ssh服务
CMD /usr/sbin/sshd -D

此时ssh_alpine目录下的文件:
在这里插入图片描述
执行命令:

docker build -t sshd:dockerfile .

在这里插入图片描述在这里插入图片描述
继续测试运行:
6、测试镜像
从新建的镜像启动一个容器,不需要指定启动时执行的命令:

docker run -d -p 10022:22 sshd:dockerfile

在这里插入图片描述
继续执行:

ssh -p10022 root@127.0.0.1

在这里插入图片描述
需要清理下之前链接留下的信息才能正常连接。
在容器中执行ps -a,可以看到SSH服务的进程号为1:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值