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 容器技术笔记链接梳理

Docker&Kubernetes ❀ Docker 容器技术笔记链接梳理

Docker部署nginx配置域名

Docker教程系列六:Docker上部署Nginx

docker 安装 nginx 并配置反向代理

dockerfile构建Nginx,Tomcat镜像