10.Docker-----安装初步使用镜像Dockerfile常用指令通过Dockerfile文件封装nginx镜像并优化
Posted ♚北秋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10.Docker-----安装初步使用镜像Dockerfile常用指令通过Dockerfile文件封装nginx镜像并优化相关的知识,希望对你有一定的参考价值。
安装、初步使用、镜像、Dockerfile常用指令、通过Dockerfile文件封装nginx镜像并优化
一、简介
- Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
- 一个完整的Docker有以下几个部分组成:
- DockerClient客户端
- Docker Daemon守护进程
- Docker Image镜像
- DockerContainer容器
二、安装
1.安装配置
[root@server1 ~]# vim /etc/yum.repos.d/westos.repo #配置软件仓库
[root@server1 ~]# cat /etc/yum.repos.d/westos.repo #查看配置
[root@server1 ~]# yum repolist #检测仓库
[root@server1 ~]# yum install -y docker-ce #安装docker
[root@server1 ~]# systemctl enable --now docker #开启docker服务,并设置为开机自启
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@server1 ~]# docker info #查看
仓库配有的安装包
安装
桥接
如果docker info 出现如下错误
[root@server1 ~]# sysctl -a | grep bridge-nf-call-iptables #查看是1的话不用修改,也不会出现上述问题
net.bridge.bridge-nf-call-iptables = 0 #修改为1
[root@server1 ~]# vim /etc/sysctl.d/docker.conf
[root@server1 ~]# cat /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
[root@server1 ~]# sysctl --system
[root@server1 ~]# docker info
Registry: https://index.docker.io/v1/
2.导入马里奥游戏
## 下载马里奥游戏
[root@server1 ~]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
lftp 172.25.15.250:/pub/images> get mario.tar
207414272 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 ~]# ls
mario.tar
[root@server1 ~]# docker load -i mario.tar #将游戏导入容器
4aeeaca5ce76: Loading layer 197.2MB/197.2MB
708fd576a927: Loading layer 208.9kB/208.9kB
90222f49bc4c: Loading layer 4.608kB/4.608kB
5f70bf18a086: Loading layer 1.024kB/1.024kB
dbe97b1b7330: Loading layer 1.536kB/1.536kB
44e5704d49fb: Loading layer 9.912MB/9.912MB
Loaded image: mario:latest
[root@server1 ~]# docker run -d --name demo -p 80:8080 mario #运行
5ad30696ec3ce7c9efd33e5964f29333cb4dcd30e99c4d610f8195c2423f394c
浏览器访问172.25.15.1
3.删除
[root@server1 ~]# docker ps -a #查看进程,所有的 (docker ps 正在运行的)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ad30696ec3c mario "python3 -m http.ser…" 6 minutes ago Up 6 minutes 0.0.0.0:80->8080/tcp demo
[root@server1 ~]# docker rm -f demo #删除
demo
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4.导入2048游戏
##下载2048游戏
[root@server1 ~]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
cd ok, cwd=/pub/images
lftp 172.25.15.250:/pub/images> get game2048.tar
57176576 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 ~]# ls
game2048.tar mario.tar
[root@server1 ~]# docker load -i game2048.tar
011b303988d2: Loading layer 5.05MB/5.05MB
36e9226e74f8: Loading layer 51.46MB/51.46MB
192e9fad2abc: Loading layer 3.584kB/3.584kB
6d7504772167: Loading layer 4.608kB/4.608kB
88fca8ae768a: Loading layer 629.8kB/629.8kB
Loaded image: game2048:latest
[root@server1 ~]# docker run -d --name demo -p 80:80 game2048
6fb8beeaea6ae156afba03cca436e4b3dca01d023b7a92bb73979e41abbbc176
[root@server1 ~]#
三、镜像
1.镜像的分层结构
容器层以下所有镜像层都是只读的
docker从上往下依次查找文件
容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
一个镜像最多127层
2.退出方式
- 编辑镜像时
- ctrl+d #退出并删除
- ctrl+qp #直接退出,进程进入后台
3.分层
[root@server1 ~]# cd /var/lib/docker/
[root@server1 docker]# docker pull busybox #
Using default tag: latest
latest: Pulling from library/busybox
Digest: sha256:0f354ec1728d9ff32edcd7d1b8bbdfc798277ad36120dc3dc683be44524c8b60
Status: Image is up to date for busybox:latest
docker.io/library/busybox:latest
[root@server1 docker]# docker run -it --name demo busybox #运行创建一个名字为demo的容器
/ # ls
bin dev etc home proc root sys tmp usr var
/ # touch file1
/ # touch file2
/ # touch file3
/ # touch file4
/ # touch file5
/ # ls
bin etc file2 file4 home root tmp var
dev file1 file3 file5 proc sys usr
/ #
[root@server1 docker]# docker ps #查看正在运行的
[root@server1 docker]# docker ps -a #所有
[root@server1 docker]# docker start demo #启动容器demo
[root@server1 docker]# docker container attach demo #继续编辑镜像
[root@server1 docker]# docker commit demo demo:v1 #创建v1镜像
[root@server1 docker]# docker commit history demo:v1 #查看V1镜像
[root@server1 docker]# docker history busybox:latest
[root@server1 docker]# docker rmi demo:v1 #删除v1镜像
[root@server1 docker]# docker images
有基础的两层,加上编辑的一层,共三层
删除v1
4.镜像的构建
- docker commit 构建新镜像三部曲
- 运行容器
- 修改容器
- 将容器保存为新的镜像
- 缺点:
- 效率低、可重复性弱、容易出错
- 使用者无法对镜像进行审计,存在安全隐患
root@server1 ~]# mkdir docker
[root@server1 ~]# cd docker/
[root@server1 docker]# vim Dockerfile ##镜像的构建
[root@server1 docker]# cat Dockerfile
FROM busybox ##指定base镜像,如果本地不存在会从远程仓库下载
RUN touch file1
RUN mkdir westos
[root@server1 docker]# docker build -t demo:v1 . #创建v1
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
---> 69593048aa3a
Step 2/3 : RUN touch file1
---> Running in 645634f44648
Removing intermediate container 645634f44648
---> eec5bb41f5d2
Step 3/3 : RUN mkdir westos
---> Running in 9714250c45ee
Removing intermediate container 9714250c45ee
---> d3da9446a2c2
Successfully built d3da9446a2c2
Successfully tagged demo:v1
[root@server1 docker]# vim Dockerfile #再次编写好容器的操作
FROM demo:v1 ##指定base镜像,如果本地不存在会从远程仓库下载
RUN touch file2
RUN mkdir redhat
[root@server1 docker]# docker build -t demo:v2 . #创建v2
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
---> 69593048aa3a
Step 2/3 : RUN touch file2
---> Running in 4ab4ecbb36c9
Removing intermediate container 4ab4ecbb36c9
---> a82b29235c1d
Step 3/3 : RUN mkdir redhat
---> Running in 312a217cc548
Removing intermediate container 312a217cc548
---> 57b33e754a66
Successfully built 57b33e754a66
Successfully tagged demo:v2
[root@server1 docker]# docker history demo:v1 #查看容器的层数
[root@server1 docker]# docker history demo:v2
[root@server1 docker]# docker images #查看有几个容器
四、Dockerfile
1.常用指令
用来提交创建镜像
FROM #指定base镜像,如果本地不存在会从远程仓库下载。
MAINTAINER #设置镜像的作者,比如用户邮箱等。
COPY
#把文件从build context复制到镜像
#支持两种形式:COPY src dest 和 COPY ["src", "dest"]
#src必须指定build context中的文件或目录
ADD
#用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:
#ADD html.tar /var/www
#ADD http://ip/html.tar /var/www
ENV
#设置环境变量,变量可以被后续的指令使用:
#ENV HOSTNAME sevrer1.example.com
EXPOSE
#如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80
VOLUME
#申明数据卷,通常指定的是应用的数据挂在点:
VOLUME ["/var/www/html"]
WORKDIR
#为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。
RUN
# 在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install -y vim
CMD 与 ENTRYPOINT
#这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
#docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
#Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
Shell和exec格式的区别
# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT echo "hello, $name"
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面
的exec格式不会:
# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello, $name"]
2.通过Dockerfile文件封装nginx镜像
[root@server1 ~]# cd docker/
## 1.下载nginx安装包
[root@server1 docker]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/docs/lamp/
lftp 172.25.15.250:/pub/docs/lamp> get nginx-1.20.1.tar.gz
1061461 bytes transferred
lftp 172.25.15.250:/pub/docs/lamp> exit
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz
## 2.软件仓库的配置
[root@server1 docker]# cp /etc/yum.repos.d/westos.repo .
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz westos.repo
[root@server1 docker]# cat westos.repo
[wan]
name="wan"
baseurl=http://172.25.15.250/rhel7
gpgcheck=0
[docker]
name=docker
baseurl=ftp://172.25.15.250/pub/docs/docker/docker-ce
gpgcheck=0
## 3.下载rhel7镜像
[root@server1 docker]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
lftp 172.25.15.250:/pub/images> get rhel7.tar
147112448 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz rhel7.tar westos.repo
## 4.导入镜像,封装
[root@server1 docker]# docker load -i rhel7.tar #导入
e1f5733f050b: Loading layer 147.1MB/147.1MB
[root@server1 docker]# vim Dockerfile #编写Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY westos.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
RUN rpmdb --rebuilddb
RUN yum install -y gcc pcre-devel zlib-devel make
WORKDIR /mnt/nginx-1.20.1
RUN ./configure &> /dev/null
RUN make &> /dev/null
RUN make install &> /dev/null
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v1 . #封装容器rhel7:v1
[root@server1 docker]# docker run -d --name rhel7 rhel7:v1 #运行
[root@server1 docker]# docker inspect rhel7 #查看容器信息
[root@server1 docker]# cd /var/lib/docker/volumes /9b855292b296fd0d4fe423342e52dc5ea5d9d190e7ab9cf131ceef7f95637577/_data #进入目录
[root@server1 _data]# ls
[root@server1 _data]# echo www.jwl.org > index.html #编写nginx默认发布文件
[root@server1 _data]# curl 172.17.0.2 #访问查看
www.jwl.org
[root@server1 _data]#
[root@server1 _data]# docker images
我们看到封装好的v1有303MB,对于企业来说过大,因此我们要进行优化。
五、优化容器
1.第一种:简单优化,减少镜像层数
清理镜像构建的中间产物
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
COPY westos.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.1
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel &> /dev/null && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.20.1 && yum remove -y gcc make && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v2 .
[root@server1 docker]# docker run -d --name rhel7.1 rhel7:v2 #换个名称运行
[root@server1 docker]# docker images #查看所有容器
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v2 f3c552fd7ff4 3 minutes ago 233MB #和v1比较少了130MB
rhel7 v1 a8e39b9ae36a 46 minutes ago 303MB #未优化
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB #原始镜像
[root@server1 docker]#
2.第二种:使用多阶段构建镜像
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
COPY westos.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.1
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel &> /dev/null && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.20.1 && yum remove -y gcc make && yum clean all
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v3 .
[root@server1 docker]# docker run -d --name rhel7.2 rhel7:v3
736cd619254c4c157d8402144fff6f15628c56c5b79c571d9b7f321934c77b50
[root@server1 docker]# docker images #V3相比v1和v2更小
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 186d48c6f99a 40 seconds ago 144MB ##使用多阶段构建镜像 缩减到了144M,但还是比nginx官方镜像133M大很多
rhel7 v2 f3c552fd7ff4 8 minutes ago 233MB ##减少镜像层数,清理镜像构建的中间产物
rhel7 v1 a8e39b9ae36a 51 minutes ago 303MB #未优化
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB #原始镜像
3.第三种:更换构建镜像,选择最精简的基础镜像
##1.下载镜像
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz rhel7.tar westos.repo
[root@server1 docker]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
lftp 172.25.15.250:/pub/images> get base-debian10.tar
20818944 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 docker]# ls
base-debian10.tar Dockerfile nginx-1.20.1.tar.gz rhel7.tar westos.repo
[root@server1 docker]# docker load -i base-debian10.tar
de1602ca36c9: Loading layer 3.041MB/3.041MB
1d3b68b6972f: Loading layer 17.77MB/17.77MB
Loaded image: gcr.io/distroless/base-debian10:latest
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 186d48c6f99a 6 minutes ago 144MB
rhel7 v2 f3c552fd7ff4 14 minutes ago 233MB
rhel7 v1 a8e39b9ae36a 57 minutes ago 303MB
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB
gcr.io/distroless/base-debian10 latest d48fcdd54946 51 years ago 19.2MB
## 2.封装
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM nginx:latest as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
RUN mkdir -p /opt/var/cache/nginx && \\
cp -a --parents /usr/lib/nginx /opt && \\
cp -a --parents /usr/share/nginx /opt && \\
cp -a --parents /var/log/nginx /opt && \\
cp -aL --parents /var/run /opt && \\
cp -a --parents /etc/nginx /opt && \\
cp -a --parents /etc/passwd /opt && \\
cp -a --parents /etc/group /opt && \\
cp -a --parents /usr/sbin/nginx /opt && \\
cp -a --parents /usr/sbin/nginx-debug /opt && \\
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \\
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \\
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \\
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \\
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \\
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \\
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \\
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \\
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \\
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian10
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v4 .
[root@server1 docker]# docker run -d --name rhel7.3 rhel7:v4
19cef46b199993e6d1b53da00ad7227170095ef1323e44f5ccb6c16472bceb7e
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v4 dc3e62941331 About a minute ago 31.9MB #更换镜像,选择最精简的基础镜像
rhel7 v3 186d48c6f99a 13 minutes ago 144MB #使用多阶段构建镜像 缩减到了144M,但还是比nginx官方镜像133M大很多
rhel7 v2 f3c552fd7ff4 20 minutes ago 233MB #减少镜像层数,清理镜像构建的中间产物
rhel7 v1 a8e39b9ae36a About an hour ago 303MB #未优化
nginx latest 4cdc5dd7eaad 13 days ago 133MB
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB #原始镜像
gcr.io/distroless/base-debian10 latest d48fcdd54946 51 years ago 19.2MB
[root@server1 docker]#
以上是关于10.Docker-----安装初步使用镜像Dockerfile常用指令通过Dockerfile文件封装nginx镜像并优化的主要内容,如果未能解决你的问题,请参考以下文章
docker----安装初步使用构建镜像Dockerfile编写通过Dockerfile文件封装nginx镜像并优化
Docker教程-10-Docker Compose使用入门