Docker-容器介绍与配置镜像分层部署nginx优化镜像
Posted 小蒜不次蒜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker-容器介绍与配置镜像分层部署nginx优化镜像相关的知识,希望对你有一定的参考价值。
目录
docker简介
Docker是管理容器的引擎。
Docker为应用打包、部署平台,而非单纯的虚拟化技术
docker和虚拟机的区别:
容器是如何工作的
1.配置docker
1.1搭建docker仓库
准备一台虚拟机server1:
配置软件仓库,从官网下载的仓库!
[root@server1 ~]# cd /etc/yum.repos.d/
[root@server1 yum.repos.d]# vim docker.repo
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck=0
由于下载过程中会出现很多的依赖性,这些依赖性都是从centos源里面找到的,所以这里我们还需搭建一个centos源,这里可以参考阿里云镜像站
[root@server1 yum.repos.d]# vim CentOS-Base.repo
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-7 - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-7 - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-7 - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-7 - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#contrib - packages by Centos Users
[contrib]
name=CentOS-7 - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
本人本地有docker软件目录,所以直接下载!
1.2下载docker-ce
[root@server1 yum.repos.d]# yum repolist
[root@server1 yum.repos.d]# yum install -y docker-ce
开启服务,并开机自启
[root@server1 yum.repos.d]# systemctl enable docker
查看docker 信息:
[root@server1 yum.repos.d]# docker info
使用docker info 出现警告iptables的情况:
解决方式:
[root@server1 sysctl.d]# pwd
/etc/sysctl.d
[root@server1 sysctl.d]# vim docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
[root@server1 sysctl.d]# sysctl --system
[root@server1 sysctl.d]# ip addr
1.3测试
因为本人本地有镜像直接本地拉取,没有的网上拉取!
[root@server1 ~]# docker search yakexi007
[root@server1 ~]# docker load -i mario.tar ##本地加载
[root@server1 ~]# docker pull yakexi007/game2048 ## 要是本地没有,就网上拉取拉取镜像
[root@server1 ~]# docker inmages
做端口映射 第一个80是宿主机的,第二个对应镜像的端口
-d是打入后台,–name 是给镜像取个名字
[root@server1 ~]# docker run -d --name game2048 -p 80:80 yakexi007/game2048
[root@server1 ~]# docker ps ##查询端口连接情况
[root@server1 ~]# docker ps -a ## 查看所有的,包括已经停掉的
[root@server1 ~]# docker history game2048:latest
然后访问docker主机的ip即可:172.25.0.1
接着删除拉取得镜像
[root@server1 ~]# docker rm -f demo
重新拉取镜像mario
做端口映射 第一个80是宿主机的,第二个对应镜像的端口
mario的镜像端口为8080!!!
docker load -i mario.tar
docker run -d --name demo -p 80:8080 mario
访问172.25.0.1:
2.镜像的分层
base镜像提供的是最小的Linux发行版
同一docker主机支持运行多种Linux发行版
采用分层结构的最大好处是:共享资源
拉取一个busybox作为实验环境
[root@server1 ~]# docker pull busybox
[root@server1 ~]# docker run -it --name demo busybox
进入交互式
[root@server1 ~]# docker run -it --name demo busybox
ls
[root@server1 ~]#docker rm demo
-i表示交互式,-t表示打开伪终端
[root@server1 ~]#docker run -it --name demo demo:v1
查看镜像
docker images
运行容器,创建文件!
docker run -it --name demo busybox
-a查看所有进程
docker ps -a
启动已有容器
docker start demo
查看进程
docker ps
进入已存在的demo容器中
docker container attach demo
上传新的镜像,源于demo容器 demo:v1
docker commit demo demo:v1
docker images
我们来对比查看两者层级结构
我们会发现demo:v1是在busybox的基础上又添加了一层!
docker history demo:v1
docker history busybox:latest
删除v1镜像
docker rmi demo:v1
docker images
docker history busybox:latest
重启读取v1中的内容
docker commit demo demo:v1
docker images
注意,已经拉取了busybox再次拉取一定会报错!!如下:
删掉demo后,不影响v1镜像!
docker rm demo
docker ps -a
docker run -it --name demo demo:v1 ## 文件还在!!
对比层级结构查看,我们会发现:手动添加的容器没有解释每一层的作用,game2048里会有解释如下图:
docker history demo:v1
docker history game2048:latest
2.1文件导入镜像
我们若是需要解决这个问题需要用文件的方式导入 镜像!
mkdir docker
cd docker/
vim Dockerfile
cat Dockerfile
FROM busybox
RUN echo westos > testfile
在当前目录文件Dockerfile下创建镜像
docker build -t demo:v2 .
docker images
docker history demo:v2
查看导入的镜像,可以查到镜像内容:
接着我们在文件Dockerfile里面再追加一行输出:
vim Dockerfile
FROM busybox
RUN echo westos > testfile
RUN echo westos > helloworld
docker build -t demo:v3 .
docker history demo:v3
同样可以看到记录追加了一条!
3.Dockerfile详解
3.1. FROM
指定base镜像,如果本地不存在会从远程仓库下载。
3.2. RUN
在容器中运行命令并创建新的镜像层,常用于安装软件包:
3.3. MAINTAINER
设置镜像的作者,比如用户邮箱等。
3.4.COPY
把文件从build context复制到镜像
支持两种形式:COPY src dest 和 COPY [“src”, “dest”]
src必须指定build context中的文件或目录
FROM busybox #镜像来源
RUN echo westos > testfile # RUN后跟shell运行语句
RUN echo westos > helloworld
COPY index.html / #COPY拷贝当前目录的index.html到容器的根目录下
然后在docker目录下
echo westos > index.html
我们可以看到demo:v3里面可以看到index.html文件已经导入!
docker build -t demo:v3 .
docker run -it --name demo demo:v3
ls
3.5.ADD
接下来我们需要在docker目录下放入一个nginx的压缩包:
添加配置文件!
ADD nginx-1.20.1.tar.gz / #ADD 解压tar包到根目录下
docker build -t demo:v4 .
docker history demo:v4
我们需要每次加载docker之后,不希望保留进程!
那么需要加上参数 --rm
docker run -it --rm demo:v4
我们看到nginx已经被解压放入了docker中!
3.6. ENV
设置环境变量,变量可以被后续的指令使用:
ENV HOSTNAME sevrer1
3.7. EXPOSE
如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80
3.8. VOLUME
申明数据卷,通常指定的是应用的数据挂在点:
VOLUME ["/var/www/html"]
添加env expose参数没有效果,后面再演示!
ENV HOSTNAME server1 #ENV 定义变量HOSTNAME为server1
EXPOSE 80 #设定端口为80
VOLUME {"/data"} #挂载目录为/data
docker build -t demo:v5 .
docker run -it --rm demo:v5
我们可以查看data是否挂载成功!
docker inspect demo
我们进入图上显示的路径下:
cd /var/lib/docker/volumes/****
echo westos >> helloworld
echo westos >> helloworld
echo westos >> helloworld
echo westos >> helloworld
重新加载进入docker发现刚才导入的数据全部到docker中了!
docker ps
docker attach ****
ls
cat helloworld
3.9.WORKDIR
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。
3.10.CMD 与 ENTRYPOINT
这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行8覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
文件中添加CMD echo “hello world”
docker build -t demo:v6 .
docker run --rm demo:v6
当文件写为如下就会报错,因为格式不正确
docker build -t demo:v7 .
docker run --rm demo:v7
所以我们删掉镜像v7
修改文件使得可以输出主机名
docker build -t demo:v9 .
docker run --rm demo:v9
若是在运行docker容器的时候,后面加上参数,那么就会覆盖之前的输出:
docker run --rm demo:v9 date
修改文件如下
输出会覆盖
CMD ["world"]
docker1 build -t demo:v9 .
docker run --rm demo:v9
后面添加参数会自动覆盖,如下:
删除掉刚才建立的镜像
删除掉刚才建立的镜像,使用快捷的指令直接删除!
docker rmi `docker images |grep ^demo | awk '{print $3}'`
4.镜像构建- -nginx
导入rhel7镜像,相当于使用rhel7的内核
get rhel7.tar
docker load -i rhel7.tar
docker images
rhel7有140mb大小!
编写Dokcerfile创建镜像,vim Dockerfile
FROM rhel7
COPY dvd.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;"]
通过Dockerfile建立镜像v1,执行命令创建镜像rhel7:v1
docker build it rhel7:v1
docker images rhel7
拉起容器,进程名为demo,查看进程!
docker run -d --name demo rhel7:v1
docker ps
查demo进程/容器信息
docker inspect demo
修改容器docker中nginx的发布页面
echo www.westos.org > index.html
测试访问可访问到nginx主页
curl 172.17.0.2
docker images rhel7
查看到镜像v1的大小346MB很大!!这样是不行的!
我们实际生产中,需要docker容器中的镜像大小越小越好!那么我们需要做优化!
5.镜像优化
选择最精简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络请求
尽量去用构建缓存
使用多阶段构建镜像
优化思路:
v2镜像:减少镜像层数,合并所有RUN指令,清理镜像构建的中间产物包括编译好的安装包和缓存/mnt/nginx-1.20.1 /var/cache/*
我们继续编辑文件Dockerfile,编辑结果如下:
vim Dockerfile
FROM rhel7
EXPOSE 80
COPY dvd.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 pcre-devel zlib-devel make && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.20.1 /var/cache/*
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
创建镜像v2
docker build -t rhel7:v2 .
查看镜像大小
docker images rhel7
发现大小为255MB也没有想象中的那么如意,还需要优化!
我们单阶段镜像最佳优化已经极限了,那么尽量去用构建缓存,使用多阶段构建镜像
两个from!!
vim Dockerfile
FROM rhel7 as build
EXPOSE 80
COPY dvd.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 pcre-devel zlib-devel make && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.20.1 /var/cache/*
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
docker build -t rhel7:v3 .
查看压缩后的镜像v3大小
docker images rhel7
我们运行v3镜像,ldd查看结构!
docker run -it --rm rhel7:v3 bash
ldd
若是还想优化镜像的话:
选择最精简的基础镜像替换原有的rhel7
我们创建一个新的目录new用来存放新的base的文件!
cd /root/docker
mkdir new
cd new
下载到新的base
本地加载base镜像
docker load -i base-debian10.tar
docker images查看大小
仅仅19.2MB,在base上比之前的rhel7大大的优化了!!
编写文件Dockerfile
vim /new/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;"]
docker build -t rhel7:v4 .
docker images rhel7
查看大小只有31.9MB
加载镜像v4
docker run -d --name demo rhel7:v4
docker inspect demo
测试
curl 172.17.0.2即可!
以上是关于Docker-容器介绍与配置镜像分层部署nginx优化镜像的主要内容,如果未能解决你的问题,请参考以下文章
Docker&Kubernetes ❀ Docker 容器技术笔记链接梳理