dockerfile基础
一、dockerfile基础
1、官网拉取的镜像
-
docker pull centos:8.4.2105
-
官网拉取的镜像都是最小化的
-
拉取的镜像,有很多的命令不能使用,源也不能使用。所以的话,需要自己构建一下
-
然后基于这个构建的镜像创建容器
-
直接在阿里源上面找到即可
2、构建一个镜像
[root@docker ~]# cat dockerfile
FROM centos:8.4.2105
MAINTAINER qqq
RUN minorver=8.4.2105 \
&& sed -e "s|^mirrorlist=|#mirrorlist=|g" -e "s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.aliyun.com/centos-vault/$minorver|g" -i.bak /etc/yum.repos.d/CentOS-*.repo
RUN yum -y install net-tools vim
CMD ["/bin/bash"]
# 默认是查找当前目录下面文件名为dockerfile的文件
# -t 构建镜像的标签,. 是当前路径
[root@docker ~]# docker build -t centos:v1.0 .
# 查看构建历史
[root@docker ~]# docker history centos:v1.0
IMAGE CREATED CREATED BY SIZE COMMENT
65dac5a93139 5 minutes ago CMD ["/bin/bash"] 0B buildkit.dockerfile.v0
<missing> 5 minutes ago RUN /bin/sh -c yum -y install net-tools vim … 75.7MB buildkit.dockerfile.v0
<missing> 5 minutes ago RUN /bin/sh -c minorver=8.4.2105 && sed -e "… 17.6kB buildkit.dockerfile.v0
<missing> 5 minutes ago MAINTAINER qqq 0B buildkit.dockerfile.v0
<missing> 3 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 years ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 3 years ago /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0… 231MB
二、dockerfile指令
1、RUN指令
-
有shell格式和exec格式
-
RUN shell命令
-
RUN ["可执行文件","参数1","参数2"]
2、build指令
-
docker build -f 文件名(绝对路径名) -t .(dockerfile处于的当前目录)
-
docker build -f /home/user/dockerfiles/myDockerfile -t myimage /home/user/dockerfiles
-
-f指定自定义的文件名,完整的路径,.表示dockerfile文件上一层的目录即可
-
在这个上层目录下寻找dockerfile文件即可
-
不是默认的文件名的话,加上-f参数
-
一些文件都是根据这个上下文去寻找的,就必须放在这个上面中
docker build -f /home/dockerfile -t nginx:v1 /home(dockerfile处于的目录)
3、COPY指令
格式为COPY src dest
-
将本地文件或者目录拷贝到容器里面
-
目标路径,不存在,会自动创建
-
是在上下文路径中寻找的,必须是相对路径
[root@docker ~]# cat d1
FROM centos:8.4.2105
COPY anaconda-ks.cfg /test/
COPY tmp/ /mnt/
CMD ["/bin/bash"]
# 发布一个nginx容器
[root@docker ~]# cat d2
FROM centos:8
RUN yum -y install nginx
COPY index.html /usr/share/nginx/html/
CMD ["nginx","-g","daemon off;"]
-
以/结尾的话就是目录,否则就是文件
-
注意的点
src为目录的话,会将目录下面的内容和子目录拷贝到dest上面去 -
src为文件,并且dest也是文件的话,直接复制过去
4、ADD指令
格式为ADD src dest
-
也是将本地的文件拷贝到容器里面
-
还可以支持解压,将本地的压缩包解压到容器里面
-
上下文路径的
[root@docker ~]# cat d2
FROM centos:8.4.2105
ADD tmp.tar.gz /mnt/
CMD ["/bin/bash"]
4、ENV指令
-
定义环境变量,可以直接使用$进行调用
-
提前定义好变量,适用于要提前传参的场景
ENV rootpasswd=123
5、USER指令
-
格式为
USER TOM -
指定用户登录
[root@docker ~]# cat d3
FROM centos:8
ENV abc=heheh
RUN yum -y install passwd
RUN useradd tom
RUN echo "123" | passwd --stdin tom
USER tom
CMD ["/bin/bash"]
6、VOLUME指令
-
格式为
VOLUME /data -
指定未来容器映射的目录
-
作为一个容器挂载的目录
-
然后就是创建容器的时候-v将本地的目录挂载到容器里面的目录即可
-
需要手动指定
-
不指定的话,会自动创建一个匿名卷挂载到容器的目录上面,而不能是挂载到容器文件,会报错的
VOLUME /data
# 创建容器的时候手动指定一下,即可挂载到容器里面的目录
7、ENTRYPOINT和CMD指令
-
如果2个命令同时使用的话,CMD参数是作为ENTRYPOINT的参数来使用的
-
docker run的时候,没有手动输入命令参数,默认执行CMD参数,如果加了指定参数的话,就会覆盖掉CMD参数
-
CMD和ENTRYPOINT同时使用
[root@docker dd]# cat d1
FROM centos:8
ENTRYPOINT ["echo","hello"]
CMD ["cmd1"]
# 容器运行后,输出的为hello cmd1
[root@docker dd]# docker run -tid --name d1 d1:latest
31343bd836c2a1230786fbbc504f06594d93cb8cf348c870703af96e12fce54e
[root@docker dd]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
31343bd836c2 d1:latest "echo hello cmd1" 8 seconds ago Exited (0) 6 seconds ago d1
[root@docker dd]# docker logs d1
hello cmd1
- 手动指定CMD参数
[root@docker dd]# docker run -tid --name d2 d1 cmd2
eca0255734f40c8fd908a77d5b4a25a2d1d779813547a7af67510392fbc63cd5
[root@docker dd]# docker logs d2
hello cmd2
- 有多个ENTRYPOINT的话需要以最后一个为准
[root@docker dd]# cat d1
FROM centos:8
ENTRYPOINT ["echo","hello"]
ENTRYPOINT ["echo","123"] # 以这个为准
CMD ["cmd1"]
[root@docker dd]# docker run -tid --name d3 d2
f7cc71a250749a817c7856960e8481b7e2238e4c15825257d5088f5e8ccb30a4
[root@docker dd]# docker logs d3
123 cmd1
-
--ENTRYPOINT参数可以覆盖掉原先的ENTRYPOINT参数,使用了这个参数的话,原先的CMD参数被忽略,需要重新传入参数
-
--ENTRYPOINT 后面必须是可执行的命令
-
强行更改容器的命令
[root@docker dd]# docker run -tid --name d5 --entrypoint mkdir d1 /test
83b50c2f2be3a67b001911f9f39910b90bbc48ad7cf18b68272c77eb413bcb6b
[root@docker dd]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83b50c2f2be3 d1 "mkdir /test" 3 seconds ago Exited (0) 1 second ago d5
8、EXPOSE指令
-
EXPOSE 端口号
-
创建容器的时候需要-p指定端口号即可
-
或者使用-P 会随机将宿主机的端口映射到容器里面指定的端口上面
9、WORKDIR指令
-
切换工作目录
-
WORKDIR /app
三、实验
1、配置ssh镜像
1、ssh密码登录
-
密钥文件生成出来
-
ssh服务器启动的是,会用到这些密钥,并于客户端进行加密连接
-
默认一个镜像,里面都没有ssh软件包,所以需要安装,并且配置ssh密钥等等
[root@docker ~]# cat ssh1
FROM centos:8
RUN yum -y install passwd openssh-clients openssh-server net-tools
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
RUN echo "123" | passwd --stdin root
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
- 上面这个是初级版本,然后远程登录一下,会有一些警告
[root@docker ~]# ssh root@172.17.0.2
root@172.17.0.2's password:
"System is booting up. Unprivileged users are not permitted to log in yet. Please come back later. For technical details, see pam_nologin(8)."
[root@b9406140902f ~]#
# 这个是因为pam_nologin模块的原因,会限制登录等等
- 修改后的代码
[root@docker ~]# cat ssh2
FROM centos:8
RUN yum -y install passwd openssh-clients openssh-server net-tools
RUN ssh-keygen -A # 可以生成主机缺少的密钥文件,保证了sshd服务正常启动了,因为容器启动的时候没有密钥文件,sshd服务就不能正常启动了
RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config \
&& echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config \
&& sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config # 禁用pam模块
RUN echo "123" | passwd --stdin root
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"] # sshd进程启动
# 这样就可以使用密码登录了
2、ssh免密登录
- 配置ssh免密登录容器
[root@docker ~]# cat ssh3
FROM centos:8
RUN yum -y install passwd openssh-clients openssh-server net-tools
RUN ssh-keygen -A
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config # 如果添加 usepam模块禁用的话,ssh就不能免密登录了,可能与认证相关的模块需要开启
RUN sed -i 's/^\(account\s\+required\s\+pam_nologin.so\)/# \1/' /etc/pam.d/sshd # 注释这一行就可以了,这个主要是控制用户登录
RUN mkdir -p /root/.ssh
COPY id_rsa.pub /root/.ssh/authorized_keys
RUN chmod 700 /root/.ssh && \
chmod 600 /root/.ssh/authorized_keys && \
chown -R root:root /root/.ssh
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
# 免密登录会出现这个警告
"System is booting up. Unprivileged users are not permitted to log in yet. Please come back later. For technical details, see pam_nologin(8)."
# 解决方式就在上面,修改/etc/pam.d/sshd这个文件或者删除/run/nologin都可以
-
pam_nologin 是检查/etc/nologin或者/run/nologin存在的,如果存在非root用户登录被拒绝显示那个警告
-
不存在的话则放行
-
目的防止普通用户登录系统,避免系统未稳定时产生的异常操作
-
还有一个就是容器中没有完整的init 系统,就会导致pam_nologin误判系统没有启动完成,就不允许登录,但是root用户可以跳过pam_nologin这个规则
2、配置一个基础容器镜像
- 配置源,安装一些基础命令
# 因为原有的基础镜像里面的yum源不能使用,是过期的
[root@docker ~]# cat jichuimage
FROM centos:8.4.2105
RUN minorver=8.5.2111 && sed -e "s|^mirrorlist=|#mirrorlist=|g" \
-e "s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.aliyun.com/centos-vault/$minorver|g" \
-i.bak /etc/yum.repos.d/CentOS-*.repo
RUN yum -y clean all && yum makecache
RUN yum -y install net-tools && yum -y install vim && yum -y install epel-release
CMD ["/bin/bash"]
问题
- dockerfile文件名一定是这个吗
# 不一定是这个名字,可以自定义
# 不是这个名字的时候,需要加上一个 -f 参数
- -f 参数了,不在这个路径下又是怎样构建了
# 写绝对路径即可

浙公网安备 33010602011771号