面试官:如何构建Docker镜像?举几个常见的Dockerfile指令?

Docker镜像构建

手动构建h5小游戏镜像

之前都是下载的镜像,那如何自己做个镜像,docker run起来就小游戏那种?

手动构建后就算自动化构建,这些步骤也需要写Dockerfile里的。

##构建思路:先找一个最基础的镜像,然后再其上装应用,装好commit即可
# 1.准备基础镜像
[root@docker01 ~]# docker pull centos:7

# 2.启动容器
[root@docker01 ~]# docker run -it -d centos:7

# 3.进入容器
[root@docker01 ~]# docker exec -it 285b7d1b2ac7 /bin/bash

# 4.更换阿里云源
[root@285b7d1b2ac7 /]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
[root@285b7d1b2ac7 /]# curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo

# 5.安装nginx
[root@285b7d1b2ac7 /]# yum install -y nginx

# 6.拷贝代码
[root@docker01 /code/h5_games]# ll
total 48
drwxr-xr-x 23 root root  4096 Mar  5  2015 ceshi
drwxr-xr-x 42 root root  4096 Mar  5  2015 game
drwxr-xr-x  2 root root  4096 Mar  5  2015 img
-rwxr-xr-x  1 root root 30312 Mar  5  2015 index.html
-rwxr-xr-x  1 root root   578 Mar  5  2015 readme.txt
[root@docker01 /code/h5_games]# tar zcf /root/h5_games.tgz ./*
[root@docker01 /code/h5_games]# cd 
[root@docker01 ~]# docker cp h5_games.tgz 285b7d1b2ac7:/usr/share/nginx/html
Successfully copied 18.8MB to 285b7d1b2ac7:/usr/share/nginx/html

# 7.解压代码
[root@62dde02290a3 /]# cd /usr/share/nginx/html
[root@285b7d1b2ac7 html]# tar xf h5_games.tgz 

# 8.手动将容器构建成镜像:docker commit <要打包的容器ID> <仓库名:标签>  
[root@docker01 ~]# docker commit 285b7d1b2ac7 nginx:c7_v1
sha256:b969c0134e27d76d15836df997fdb33cc9570108dccfdda211af78165eb6fc94

# 9.构建成功,查看镜像
[root@docker01 ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        c7_v1     fd377da627db   8 minutes ago   522MB
...

# 10.用打好的镜像启个容器
[root@docker01 ~]# docker run -it -d -p80:80 nginx:c7_v1 nginx -g "daemon off;" //把nginx启动命令设置成它pid为1的命令
f31bddb49d4c188f3b7c0ed2b8c0f870f49375c2343342dd995b3d97af5fa907

##注:nginx -g "daemon off;"  这句话的意思:把nginx卡在前台启动,-g是启动时给它指定配置(相当于写进nginx.conf)

##### 注意 #####
docker 容器默认会把容器内部第一个进程,也就是 pid=1 的程序作为docker容器是否正在运行的依据,如果docker容器中 pid = 1 的进程挂了,那么docker容器便会直接退出,也就是说Docker容器中必须有一个前台进程,否则认为容器已经挂掉。

在常规的虚机上,nginx默认是以守护进程来运行的(daemon on),在后台默默提供服务,同时部署多个ngxin服务也不会相互干扰。在容器环境,one container == one process,容器要能持续运行,必须有且仅有一个前台进程,所以对nginx进程容器化,需要将nginx转为前台进程(daemon off)# 浏览器访问
http://10.0.0.100/

在这里插入图片描述

docker ps查看刚刚运行的容器

在这里插入图片描述

进入容器查看pid=1的进程,确实为nginx

[root@docker01 ~]# docker exec -it f31bddb49d4c /bin/bash
[root@f31bddb49d4c /]# cd
[root@f31bddb49d4c ~]# ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.0  39308  3932 pts/0    Ss+  19:28   0:00 nginx: master process nginx -g daemon off;
nginx         7  0.0  0.0  39696  2060 pts/0    S+   19:28   0:00 nginx: worker process
nginx         8  0.0  0.0  39696  2060 pts/0    S+   19:28   0:00 nginx: worker process
root         15  0.9  0.0  11828  1888 pts/1    Ss   21:14   0:00 /bin/bash
root         31  0.0  0.0  51732  1716 pts/1    R+   21:14   0:00 ps aux

Dockerfile自动构建镜像

Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。打个比方,镜像相当于你开的中药,dockerfile相当于中药的配方表。

写Dockerfile的思路/步骤如下。说白了,就是把上面那些步骤写到Dockerfile里。

1、手动制作docker镜像,记录历史命令
2、根据历史命令撰写dockenfile文件
3、docker build构建docker镜像
4、测试镜像的功能

dockerfile常用指令

# FROM:指定基础镜像
# RUN:制作镜像过程中在容器内部执行的命令
# CMD:容器启动时执行的基础命令(容器启动后PID为1的进程),可以被docker run命令后面的参数替换
ENTRYPOINT:容器启动时执行的初始命令,不能被替换。如果同时使用CMD和ENTRYPOINT,CMD命令将作为ENTRYPOINT命令的参数
# ADD:把dockerfile当前目录下的文件拷贝到容器中(自动解压tar包)
# COPY:把dockerfile当前目录下的文件拷贝到容器中(不解压tar包)
# EXPOSE:声明镜像暴露的端口

--------------------------------
WORKDIR:指定容器的默认工作目录,非必须
VOLUME:声明下文件映射挂载目录(你可以挂载我这里面哪个目录)
ENV:环境变量(比如ssh的密码,数据库的密码)
LABEL:镜像的属性标签,随便写
MAINTAINER:管理者标识

[root@docker01 ~]# docker inspect nginx:latest 
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },

RUN命令的格式

# RUN命令有以下两种格式:
1、shell格式:
RUN <命令行命令>
2、exec格式:
RUN ["可执行文件","参数1","参数2"]

用dockerfile构建上边的h5小游戏镜像

# 0.准备目录及代码
[root@docker01 ~]# ll
total 18324
-rw-------. 1 root root     1310 Jul 14 17:14 anaconda-ks.cfg
-rw-r--r--  1 root root 18753368 Dec 23 03:17 h5_games.tgz
[root@docker01 ~]# mkdir dockerfile
[root@docker01 ~]# cd dockerfile/
[root@docker01 ~/dockerfile]# mv ../h5_games.tgz .
[root@docker01 ~/dockerfile]# ll
-rw-r--r-- 1 root root 18783621 Feb 28 11:01 h5_games.tgz

# 1.编写Dockerfile
[root@docker01 ~/dockerfile]# vim Dockerfile
FROM centos:7
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo  #//也可用COPY代替
RUN curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
RUN sed -i '/aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo   #//优化,删掉阿里源里没用的。
RUN yum install -y nginx
ADD h5_games.tgz /usr/share/nginx/html
EXPOSE 80  #//可不写。容器内nginx默认是80端口
CMD ["/sbin/nginx","-g","daemon off;"]  #//注意要用双引号

# 2.构建Docker镜像:docker build
[root@docker01 ~/dockerfile]# docker build -t nginx:c7_v2 .
....
-t 指定一个名字
. 指定dockerfile的路径

# 3.查看镜像
[root@docker01 ~/dockerfile]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
nginx        c7_v2     ba6b1d964464   2 minutes ago    503MB
nginx        c7_v1     fd377da627db   37 minutes ago   522MB
...

# 4.运行容器
[root@docker01 ~/dockerfile]# docker run -it -d -p80:80 nginx:c7_v2 
61bf393921a06a527e8ac56e36361275df21cd5b93039ec3a55766c3d4b7dc57
[root@docker01 ~/dockerfile]# docker ps

# 5.浏览器访问,成功

## 如遇报错,比如之前命令用的单引号,nginx起不来,容器退出等,可查看容器日志
docker logs <容器ID>

在这里插入图片描述

镜像瘦身:dockerfile优化

Dockerfile的指令每执行一次都会在docker上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz
RUN tar -xvf redis.tar.gz
以上执行会创建 3层镜像。可简化为以下格式

FROM centos
RUN yum -y install wget && \
wget -O redis.tar.gz "http://download.redis.10/releases/redis-5.0.3,tar.gz" && \
tar -xvf redis.tar.gz
如上,以&&符号连接命令,这样执行后,只会创建1层镜像。

dockerfile优化:减少分层。说白了,构建步骤越少越好。原则如下:

1、尽可能选择体积小linux发行版,比如alpine linux

2、尽可能合并RUN指令,使用 && 和 \ 减少不必要的RUN

3、把变化的内容尽可能放在dockerfile结尾

4、清理无用的文件(比如yum缓存,源码包)

# 优化dockerfile
[root@docker01 ~/dockerfile]# vim Dockerfile
FROM centos:7
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && \
curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo && \
sed -i '/aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo && \
yum install -y nginx && \
yum clean all && \  #//卸磨杀驴
rm -f /etc/yum.repos.d/CentOS-Base.repo && \
rm -f /etc/yum.repos.d/epel.repo
ADD h5_games.tgz /usr/share/nginx/html
#EXPOSE 80
CMD ["/sbin/nginx","-g","daemon off;"]

# 构建镜像
[root@docker01 ~/dockerfile]# docker build -t nginx:c7_v3 .
[root@docker01 ~/dockerfile]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
nginx        c7_v3     b61e011c7a89   2 minutes ago    289MB  #小很多
nginx        c7_v2     ba6b1d964464   22 minutes ago   503MB
nginx        c7_v1     fd377da627db   57 minutes ago   522MB

# 运行容器
[root@docker01 ~/dockerfile]# docker run -it -d -p80:80 nginx:c7_v3
[root@docker01 ~/dockerfile]# docker run -it -d -p81:80 nginx:c7_v3

# 访问10.0.0.100
# 访问10.0.0.100:81

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值