UnionFS ( 联合文件系统): Union文件系统(UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS.
**bootfs(boot file system)**主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system),在bootfs之上。包含的就是典型Linux系统中的/dev, /proc,/bin, letc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu , Centos等等。
1、初识Dockerfile
Dockerfile就是用来构建docker镜像的构建文件!命令脚本
通过脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层
Docker镜像
Docker镜像的创建方法
基本结构
Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义镜像。
Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。
Docker分为四部分:
DockerFile构建过程
dockerfile是用来构建dokcer镜像的文件!命令参数脚本!
构建步骤︰
1、编写一个dockerfile 文件
2、docker build构建成为一个镜像
3、docker run运行镜像
4、docker push发布镜像(DockerHub、阿里云镜像仓库!)
基础知识:
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交
模板
创建目录,然后
# 第一行必须指定基于的基础镜像
FROM ubuntu
# 维护者信息
LABEL MAINTAINER='seancheng [email protected]'
# 镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# 容器启动时默认要执行的指令
CMD /usr/sbin/nginx
注意:其中,一开始必须指明所基于的镜像名称,接下来一般会说明维护者信息。
后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。
最后是CMD指令来指定运行容器时的操作指令。
指令的一般格式为INSTRUCTION arguments,指令包括:
指令 | 含有 |
---|---|
FROM 镜像 | 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 |
MAINTAINER 名字 | 说明新镜像的维护人信息 |
RUN 命令 | 在所基于的镜像上执行命令 |
CMD [“要执行的命令”,“参数1”,“参数2”] | 指令启动容器时要运行的命令或者脚本,Dockerfile只能由一条CMD命令,如果指定多条则只能最后一条被执行 |
EXPOSE 端口号 | 指定新镜像加载到Docker时要开启端口 |
ENV 环境变量 变量值 | 设置一个环境变量的值,会被后面的RUN使用 |
ADD 源文件/目录 目标文件/目录 | 将源文件复制到目标文件,源文件要与Dockerfile位于相同的目录中,或者是一个URL |
COPY 源文件/目录 目标文件/目录 | 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同目录中 |
VOLUME [“目录”] | 在容器中创建一个挂载点 |
USER 用户名/UID | 指定运行容器时的用户 |
WORKDIR 路径 | 为后续的RUN、CMD、ENTRYPOINT指定工作目录 |
ONBUILD 命令 | 指定生成的镜像作为一个基础镜像时所要运行的命令 |
HEALTHCHECK | HEALTHCHECK |
ENTRYPOINT | 指定这个容器启动的时候要运行的命令,可以追加命令 |
格式为FROM 或FROM :。
第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。
LABEL MAINTAINER
格式为LABEL MAINTAINER ,指定维护者信息
RUN
格式为RUN 或RUN [“executable”,“param1”,“param2”]。
前者将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行。指定使用其他终端可以通过第二种方式实现,例如:
RUN ["/bin/bash","-c","echo hello"]
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行,例如:
RUN echo "hello world\nhello tom" > /tmp/abc && \
cat /tmp/abc
CMD
CMD支持三种格式:
CMD ["executable","param1","param2"]使用exec执行,推荐方式
CMD command param1 param2在/bin/sh中执行,提供给需要交互的应用
CMD ["param1","param2"]提供给ENTRYPOINT的默认参数
CMD用于指定启动容器时默认要执行的命令,每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。
EXPOSE
格式为EXPOSE […]。
例如:
EXPOSE 22 80 8443
EXPOSE用于告诉Docker服务器容器暴露的端口号,供互联系统使用。
在启动容器时通过-P,Docker主机会自动分配一个端口转发到指定的端口;
使用-p则可以具体指定哪个本地端口映射过来。
ENV
格式为ENV 。指定一个环境变量,会被后续RUN指令使用,并在容器运行时保持。例如:
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && ...
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
ADD
格式为ADD 。
该命令将复制指定的到容器中的。其中可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL;还可以是一个tar文件(会自动解压为目录)。
COPY
格式为COPY 。
复制本地主机的(为Dockerfile所在目录的相对路径,文件或目录)为容器中的。目标路径不存在时会自动创建。
当使用本地目录为源目录时,推荐使用COPY。
ENTRYPOINT
ENTRYPOINT有两种格式:
配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖。而且,如果在docker run的后面提供了参数,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。
VOLUME
格式为VOLUME [“/data”]。
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
USER
格式为USER daemon。
指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:
RUN groupadd -r postgres && useradd -r -g postgres postgres
要临时获取管理员权限可以使用gosu,而不推荐sudo。如果不指定,容器默认是root运行。
WORKDIR
格式为WORKDIR /path/to/workdir。
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为/a/b/c。
ONBUILD
格式为ONBUILD [INSTRUCTION]。
配置当所创建的镜像作为其他镜像的基础镜像时,所执行的操作指令。
例如,Dockerfile使用如下的内容创建了镜像image-A
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
此时,如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像时,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令。
FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
使用ONBUILD指令的镜像,推荐在标签中注明,例如ruby:1.9-onbuild。
[root@localhost ~]# mkdir httpd
[root@localhost ~]# cd httpd/
[root@localhost httpd]# touch Dockerfile
[root@localhost httpd]# mkdir files
[root@localhost httpd]# ls
Dockerfile files
[root@localhost httpd]# cd files/
#下载源码包
[root@localhost files]# wget
https://downloads.apache.org/apr/apr-1.7.0.tar.gz
https://downloads.apache.org/httpd/httpd-2.4.54.tar.gz
https://downloads.apache.org/apr/apr-util-1.6.1.tar.gz
[root@localhost files]# tree
.
├── apr-1.7.0.tar.gz
├── apr-util-1.6.1.tar.gz
└── httpd-2.4.54.tar.gz
0 directories, 3 files
[root@localhost files]#
[root@localhost httpd]# vim Dockerfile
[root@localhost httpd]# cat Dockerfile
FROM centos
LABEL MAINTAINER='GIN [email protected]'
ENV apache_version 2.4.54
ENV PATH /usr/local/apache/bin:$PATH
ADD files/apr-1.7.0.tar.gz /usr/src/
ADD files/apr-util-1.6.1.tar.gz /usr/src/
ADD files/httpd-${apache_version}.tar.gz /usr/src/
RUN useradd -r -M -s /sbin/nologin apache && \
cd /etc/yum.repos.d/ && rm -rf * && \
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo && \
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo && \
yum clean all && yum makecache && \
yum -y install gcc gcc-c++ make openssl-devel pcre-devel expat-devel libtool && \
cd /usr/src/apr-1.7.0 && \
sed -i '/$RM "$cfgfile"/d' configure && \
./configure --prefix=/usr/local/apr && \
make && make install && \
cd ../apr-util-1.6.1 && \
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && \
make && make install && \
cd ../httpd-${apache_version} && \
./configure --prefix=/usr/local/apache \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util/ \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=prefork && \
make && make install && \
yum clean all && \
yum -y remove gcc gcc-c++ make && \
rm -rf /tmp/* /usr/src/*
WORKDIR /usr/local/apache
EXPOSE 80
CMD ["-D","FOREGROUND"]
ENTRYPOINT ["/usr/local/apache/bin/httpd"]
[root@localhost httpd]# podman build -t httpd:v1 .
....
Successfully tagged localhost/httpd:v1
26016b81b29be08c8b241a5af86a12368d4d7bf8cb9bfb6de13b8886762f8ea5
[root@localhost httpd]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/httpd v1 26016b81b29b 30 seconds ago 405 MB
[root@localhost httpd]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fdbd24ab9d4a localhost/httpd:v1 -D FOREGROUND 59 seconds ago Up 59 seconds ago 0.0.0.0:42701->80/tcp web
[root@localhost httpd]# podman inspect -l | grep -i 'ipaddr'
"IPAddress": "10.88.0.2",
"IPAddress": "10.88.0.2",
[root@localhost httpd]# curl 10.88.0.2
<html><body><h1>It works!</h1></body></html>
[root@localhost httpd]#
[root@localhost httpd]# podman login docker.io
Username: kuilingwu
Password:
Login Succeeded!
[root@localhost httpd]#
[root@localhost httpd]# podman tag localhost/httpd:v1 docker.io/kuilingwu/httpd:v2022.8.31
[root@localhost httpd]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/httpd v1 26016b81b29b 8 minutes ago 405 MB
docker.io/kuilingwu/httpd v2022.8.31 26016b81b29b 8 minutes ago 405 MB
[root@localhost httpd]# podman push docker.io/kuilingwu/httpd:v2022.8.31
Getting image source signatures
Copying blob 5431d8710a4c done
Copying blob 735aed9d027d done
Copying blob 1bb3db1b8c12 done
Copying blob e9b60e06a7d0 done
Copying blob 2653d992f4ef skipped: already exists
Copying config 26016b81b2 done
Writing manifest to image destination
Storing signatures
[root@localhost httpd]#
[root@localhost httpd]# mkdir scripts
[root@localhost httpd]# ls
Dockerfile files scripts
[root@localhost httpd]# vim scripts/entrypoint.sh
#!/bin/bash
sed -i '/#ServerName/s/#//g' /usr/local/apache/conf/httpd.conf
exec "$@"
[root@localhost httpd]# cd scripts/
[root@localhost scripts]# ls
entrypoint.sh
[root@localhost scripts]# chmod +x entrypoint.sh
[root@localhost scripts]# ls
entrypoint.sh
[root@localhost httpd]# vim Dockerfile
LABEL MAINTAINER='GIN [email protected]'
ENV apache_version 2.4.54
ENV PATH /usr/local/apache/bin:$PATH
ADD files/apr-1.7.0.tar.gz /usr/src/
ADD files/apr-util-1.6.1.tar.gz /usr/src/
ADD files/httpd-${apache_version}.tar.gz /usr/src/
ADD scripts/entrypoint.sh /
#添加执行脚本
RUN useradd -r -M -s /sbin/nologin apache && \
cd /etc/yum.repos.d/ && rm -rf * && \
yum clean all && yum makecache && \
yum -y install gcc gcc-c++ make openssl-devel pcre-devel expat-devel libtool && \
cd /usr/src/apr-1.7.0 && \
sed -i '/$RM "$cfgfile"/d' configure && \
./configure --prefix=/usr/local/apr && \
make && make install && \
cd ../apr-util-1.6.1 && \
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && \
make && make install && \
cd ../httpd-${apache_version} && \
./configure --prefix=/usr/local/apache \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util/ \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=prefork && \
make && make install && \
yum clean all && \
yum -y remove gcc gcc-c++ make && \
rm -rf /tmp/* /usr/src/*
WORKDIR /usr/local/apache
EXPOSE 80
CMD ["/usr/local/apache/bin/httpd","-D","FOREGROUND"]
ENTRYPOINT ["/bin/bash","/entrypoint.sh"]
[root@localhost httpd]# podman build -t httpd:v2 .
.....
Successfully tagged localhost/httpd:v2
75755b5c0cb18b462b26e7aee574a466de89e8e8d2e3bae771cd7be12475a03f
[root@localhost httpd]#
[root@localhost httpd]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/httpd v2 75755b5c0cb1 33 seconds ago 405 MB
[root@localhost httpd]# podman run -d httpd:v2
3d3d603580bc1f911acf5413af5077383d79dd13c145018fd417a6da5150e94c
[root@localhost httpd]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d3d603580bc localhost/httpd:v2 /usr/local/apache... 8 seconds ago Up 8 seconds ago recursing_goldstine
[root@localhost httpd]# podman inspect -l | grep -i 'ipaddr'
"IPAddress": "10.88.0.3",
"IPAddress": "10.88.0.3",
[root@localhost httpd]# curl 10.88.0.3
<html><body><h1>It works!</h1></body></html>
[root@localhost httpd]# podman inspect -l
...#查看执行方式
"Cmd": [
"/usr/local/apache/bin/httpd",
"-D",
"FOREGROUND"
#另一种方法查看脚本是否可以执行
[root@localhost httpd]# podman exec -itl /bin/bash
[root@3d3d603580bc apache]# pwd
/usr/local/apache
[root@3d3d603580bc apache]# cd /
[root@3d3d603580bc /]# ls
bin entrypoint.sh home lib64 media opt root sbin sys usr
dev etc lib lost+found mnt proc run srv tmp var
#这里是会有颜色变化
[root@3d3d603580bc /]# ls --color
bin entrypoint.sh home lib64 media opt root sbin sys usr
dev etc lib lost+found mnt proc run srv tmp var
[root@3d3d603580bc /]#
#或者查看脚本的执行权限
[root@3d3d603580bc /]# ls -l /
total 4
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 340 Aug 30 16:53 dev
-rwxr-xr-x. 1 root root 87 Aug 30 15:46 entrypoint.sh
drwxr-xr-x. 1 root root 236 Aug 30 16:51 etc
[root@localhost httpd]# podman stop recursing_goldstine
recursing_goldstine
[root@localhost httpd]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost httpd]# podman tag localhost/httpd:v2 docker.io/kuilingwu/httpd:v2
[root@localhost httpd]# podman push docker.io/kuilingwu/httpd:v2
Getting image source signatures
Copying blob 23922a5fba9b done
Copying blob 5d02ddf4632c done
Copying blob 2653d992f4ef skipped: already exists
Copying blob 735aed9d027d skipped: already exists
Copying blob 1bb3db1b8c12 skipped: already exists
Copying blob 5431d8710a4c skipped: already exists
Copying config 75755b5c0c done
Writing manifest to image destination
Storing signatures
[root@localhost httpd]#