熟悉docker 是高级java必备的技术素质。在面试中,经常会有公司问到:你会打dockerfile吗?。面试中很少问及docker的其他知识点,那是因为docker是运维范围内的事。如果你的公司拥有强大的运维平台的话,基本上打dockerfile就不需要你动手,比如:百度、滴滴,他们都有自研的一套部署发布流水线。但实际中并不是所有公司都有这个实力,所以学习docker并会打dockerfile势在必行。
下面记录一下我在学习docker过程中的一些笔记。
1、使用背景简单介绍
docker是基于linux容器技术的,所以官方推荐的是使用cenos7作为docker的操作系统(还因为cenos7本身已经包含了docker)。
我使用的是mac os,其实和cenos7是一样的,直接下载,解压安装。
2、docker的几个基本命令
$ sudo service docker start // 命令行方式启动docker服务
$ docker -v/--version // 查看docker版本/或验证本地是否已安装好docker
$ docker pull 镜像名称 // 拉取镜像(默认是从你的registry mirrors配置的地址中拉取镜像)
$ docker push // 上传镜像
$ docker ps [-a|-all] // 查看docker中[已停止的]/运行中的容器
$ docker images // 查看所有的镜像
$ docker run -it ubuntu /bin/bash // 从镜像启动一个容器,i t分别表示以终端交互式启动容器
$ docker start 容器id // 直接根据容器的id启动容器,结合docker ps -a命令使用
$ docker stop 容器id // 停止一个容器
$ docker rm -f 容器id // 删除一个容器
$ docker container prune // 清理掉所有已停止的容器
$ docker export 容器id > 导出的文件名 // 导出容器
example: $ docker export 123456cx > ubuntu.rar
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$ docker search 镜像名称 // (从registry mirror地址中)搜索镜像
$ docker rmi 镜像名称 // 删除镜像
思考一下:docker如何启动一个web容器后,有无端口号?若有的话是多少?浏览器访问web容器时可以直接使用docker容器的端口吗?docker容器的端口号该如何使用?
思路:docker web容器启动后,外界(操作系统的浏览器)是不能直接访问docker容器的端口的,需要将docker容器端口与本地端口做一个映射,然后才能访问。
3、介绍dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
指令可以是这样的:每一行都是一个指令
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd xiaobuisme
RUN /bin/echo 'xiaobuisme:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
FROM 和 RUN 指令的作用
FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式
shell格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。
4、打dockerfile
创建镜像也就是我们常说的打dockerfile。
有两种方式:
- 从已经创建的容器中更新镜像,并且提交这个镜像
- 使用 Dockerfile 指令来创建一个新的镜像
第一种方式:从已有的容器中更新后提交
$ docker run -t -i ubuntu /bin/bash // 创建一个ubuntu镜像的容器
$ apt-get update ... // 进入容器后,使用apt-get update进行更新
$ exit
$ docker commit -m="提交的message" -a="作者名字" 容器id 镜像新名称 // 提交到仓库(这里我直接提交到本地的私有仓库)
example: $docker commit -m="update" -a="xiaobusime" ed1e33der xiaobuisme/ubuntu:v2
第二种方式:使用dockerfile命令创建一个全新的镜像
在 Dockerfile 文件的存放目录下,执行构建动作。(注意:打dockerfile必须是先创建一个名为Dockerfile的文件,文件中写上相关的指令)
$ vi Dockerfile // 先创建一个dockerfile文件,文件内容如下,copy进去:
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
$ docker build -t xiaobuisme/centos:6.7 . // docker build创建一个叫centos TAG为6.7的文件
参数说明:
-t :指定要创建的目标镜像名
. :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径,就是上下文路径
创建成功,如图所示:
到此为止,dockerfile仅仅是打了一个空壳,那么如何在这个自己打的docker文件中配置需要的环境(例如:redis、nginx)呢?看第5节.
5、dockerfile中配置环境,让它更丰满
需要安装docker compose 组件。(因为我的是mac os版的docker桌面版,所以已经包含了该组件,有需要安装的请参考https://www.runoob.com/docker/docker-compose.html)
思考:如何将多个组件安装在一个dockerfile中?
7、打的dockerfile具体在宿主机的什么位置?什么形式?
通过百度查资料发现,dockerfile在宿主机上并不存在,既然不存在那该如何使用和管理呢?
参考https://www.cnblogs.com/robinunix/p/12795456.html,此处不再赘述。